kyz/libmspack

Fail to properly create path components coming from the archive

iq2luc opened this issue · 3 comments

iq2luc commented

Problem description

Path components coming from the archive are not properly created.

Cause

In function ensure_filepath() from cabextract.c line 1229, lstat() is used to get information about that particular file system entry and then, at line 1231, even if the lstat() call failed (for example the entry does not exist at all in the file system), the st_buf is still used for determining if the path is a directory or not.

Examples

Fail - cabextract does not create the path component coming from the archive

[~]> ls *
dest:

src:
W2KSP4_EN.EXE

[~]> cabextract -d dest -F i386/mspatcha.dl_ src/W2KSP4_EN.EXE
Extracting cabinet: src/W2KSP4_EN.EXE
  extracting dest/i386/mspatcha.dl_
dest/i386/mspatcha.dl_: No such file or directory

All done, errors in processing 1 file(s)

Pass - manually create the path component before calling cabextract

[~]> mkdir dest/i386

[~]> cabextract -d dest -F i386/mspatcha.dl_ src/W2KSP4_EN.EXE
Extracting cabinet: src/W2KSP4_EN.EXE
  extracting dest/i386/mspatcha.dl_

All done, no errors.

Info - program version

[~]> cabextract -v
cabextract version 1.10

Proposed solution

The proposed patch fixes the issue and the archive directory components are properly created.

diff --git a/cabextract/src/cabextract.c b/cabextract/src/cabextract.c
index 0a19a9b..a58b0bd 100644
--- a/cabextract/src/cabextract.c
+++ b/cabextract/src/cabextract.c
@@ -1227,8 +1227,10 @@ static int ensure_filepath(char *path, int n) {
       /* in the archive-determined part of the path and not keeping symlinks:
        * use lstat() and delete symlinks if found */
       ok = (lstat(path, &st_buf) == 0);
-      if (ok && (st_buf.st_mode & S_IFMT) == S_IFLNK) unlink(path);
-      ok = S_ISDIR(st_buf.st_mode);
+      if (ok) {
+         if ((st_buf.st_mode & S_IFMT) == S_IFLNK) unlink(path);
+         ok = S_ISDIR(st_buf.st_mode);
+      }
     }
     if (!ok) ok = (mkdir(path, 0777 & ~user_umask) == 0);
     *p = '/';
kyz commented

Thanks for spotting this, I believe it's fixed in cc09dd3. Please let me know and I'll release a new version of cabextract.

iq2luc commented

I confirm cc09dd3 fixes the issue and the program is working OK.
Thank you for the quick resolution and for the program itself.

kyz commented

This issue has now been fixed in the cabextract 1.11 release