Branch: r14.0.x

03af0c40 2016-09-02 21:51:07 Alexander Golubev
Ark: [rar module] fix suppport for buggy rar versions

Rar versions from 5.0 till 5.3, not including the last one were added extra
spaces to short directory/file names. This behaviour resulted in
appearing of additional entries for directories and may be some other
issues.

Also slightly rework internal rar version parsing/storing and fix some
comments.

(cherry picked from commit e5a3116cffdf87b13912803006311262219aeb7b)
M ark/filelistview.cpp
M ark/rar.cpp
M ark/rar.h
diff --git a/ark/filelistview.cpp b/ark/filelistview.cpp
index f1c941f..c1e6f3f 100644
--- a/ark/filelistview.cpp
+++ b/ark/filelistview.cpp
@@ -394,7 +394,7 @@
 	// Iterate over the current tree level siblings
 	while (flvi)
 	{
-		if (flvi->fileName() == *pathIt || flvi->fileName() == (*pathIt).stripWhiteSpace()) {
+		if (flvi->fileName() == *pathIt) {
 			++pathIt;
 			if (pathIt != pathEnd) {
 				flvi = (FileLVI*) flvi->firstChild();
diff --git a/ark/rar.cpp b/ark/rar.cpp
index 02600d5..6799b64 100644
--- a/ark/rar.cpp
+++ b/ark/rar.cpp
@@ -55,7 +55,11 @@
 #include "arkutils.h"
 #include "filelistview.h"
 
-#define VERSION_5  5
+//                   MMmmppbb ; M-major, m-minor, p-patch b-(100-beta)
+#define VERSION_MAJOR 1000000
+#define VERSION_MINOR   10000
+#define VERSION_PATCH     100
+#define VERSION_5 (5*VERSION_MAJOR - VERSION_PATCH + 1 ) // consider betas
 
 RarArch::RarArch( ArkWidget *_gui, const TQString & _fileName )
   : Arch( _gui, _fileName ), m_isFirstLine(false), m_version(0)
@@ -95,11 +99,19 @@
   // Look for rar/unrar version first
   if (!m_version)
   {
-    TQRegExp versionRegExp (TQString::fromLatin1 ("RAR\\s(\\d+)\\.(\\S+)\\s.*"));
+    TQRegExp versionRegExp (TQString::fromLatin1 ("RAR\\s(\\d+)\\.(\\d+)\\s(beta (\\d+))?\\s+Copyright.*"));
 
     if (versionRegExp.exactMatch (uline))
     {
-      m_version = versionRegExp.capturedTexts()[1].toShort ();
+      // Rar displays verion in form of "M.mp (beta b)?"
+      m_version  = versionRegExp.cap(1).toShort() * VERSION_MAJOR;
+      m_version += versionRegExp.cap(2).toShort()/10 * VERSION_MINOR;
+      m_version += versionRegExp.cap(2).toShort()%10 * VERSION_PATCH;
+
+      if (!versionRegExp.cap(4).isEmpty()) { // beta versions should go befor release ones
+        m_version -= VERSION_PATCH;
+        m_version += versionRegExp.cap(4).toShort();
+      }
 
       if (m_version < VERSION_5) {
           m_headerString = "-------------------------------------------------------------------------------";
@@ -150,6 +162,10 @@
     if (parsedData.size() >= 8 && nameRegExp.exactMatch (uline)) {
       m_entryFilename = nameRegExp.capturedTexts()[2];
 
+      if(m_version < 5*VERSION_MAJOR+3*VERSION_MINOR) { // workaround bug with extra spaces in rar<5.3.0
+        m_entryFilename = m_entryFilename.stripWhiteSpace();
+      }
+
       entry << m_entryFilename; // filename
       entry << parsedData[ 1 ]; // size
       entry << parsedData[ 2 ]; // packed
@@ -163,13 +179,13 @@
       return false;
     }
   }
-  
+
   // send to GUI
   // Use addOrUpdateItem() rather than addItem() due to recent RAR version
   // place directories in archive after their content.
   FileLVI *item = m_gui->fileList()->addOrUpdateItem( entry );
-  
-  // But archives packaged with older versions of ark may have directories 
+
+  // But archives packaged with older versions of rar may have directories
   // entries first, so make sure they will get an appropriate icon
   if (item && entry[5].find('d', 0, false) != -1) {
     // check attr's for d (case insensitive to handle windows archives)
diff --git a/ark/rar.h b/ark/rar.h
index fadb3e9..1476214 100644
--- a/ark/rar.h
+++ b/ark/rar.h
@@ -24,6 +24,8 @@
 #ifndef RAR_H
 #define RAR_H 
 
+#include <stdint.h>
+
 #include "arch.h"
 
 class TQString;
@@ -65,7 +67,7 @@
      * Therefore, the variables below are needed.
      */
     bool m_isFirstLine;
-    short m_version;
+    uint32_t m_version;
     TQString m_entryFilename;
 };