Skip to content

Commit

Permalink
ensure_filepath() not creating dirs when it should
Browse files Browse the repository at this point in the history
  • Loading branch information
kyz committed Feb 19, 2023
1 parent 526df93 commit cc09dd3
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 3 deletions.
8 changes: 8 additions & 0 deletions cabextract/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
2023-02-19 Stuart Caie <kyzer@cabextract.org.uk>

* ensure_filepath(): had wrong logic, for the archive-controlled
part of a pathname, it was using the result of lstat() whether
it succeeded or not, and thus not creating directories when it
ought to. Fixed and added a testcase for cabextract's --directory
option. Thanks to iq2luc for raising the issue and offering a fix.

2023-02-04 Stuart Caie <kyzer@cabextract.org.uk>

* src/cabextract.c: By default, cabextract will now overwrite
Expand Down
2 changes: 1 addition & 1 deletion cabextract/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ bundled_mspack = mspack/mspack.h \
mspack/macros.h mspack/readbits.h mspack/readhuff.h

TESTS = test/bugs.test test/case-ascii.test test/case-utf8.test \
test/dirwalk-vulns.test test/encoding.test \
test/dir.test test/dirwalk-vulns.test test/encoding.test \
test/mixed.test test/search.test test/simple.test \
test/split.test test/utf8-stresstest.test \
test/symlinks.test
Expand Down
6 changes: 4 additions & 2 deletions cabextract/src/cabextract.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 = '/';
Expand Down
59 changes: 59 additions & 0 deletions cabextract/test/dir.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/bin/sh
# test that cabextract creates directories as expected
. test/testcase

# extract to user-chosen absolute path
"$cabextract" -d $tmpdir/test cabs/dir.cab >$actual
compare_with <<EOF
Extracting cabinet: cabs/dir.cab
extracting $tmpdir/test/plain.c
extracting $tmpdir/test/1/2/3/4.c
All done, no errors.
EOF

# cd to $tmpdir
basedir=`pwd`
cd $tmpdir || exit 1

# extract to current path
"$cabextract" "$basedir/cabs/dir.cab" >$actual
compare_with <<EOF
Extracting cabinet: $basedir/cabs/dir.cab
extracting plain.c
extracting 1/2/3/4.c
All done, no errors.
EOF

# extract to user-chosen relative directory
"$cabextract" -d tdir "$basedir/cabs/dir.cab" >$actual
compare_with <<EOF
Extracting cabinet: $basedir/cabs/dir.cab
extracting tdir/plain.c
extracting tdir/1/2/3/4.c
All done, no errors.
EOF

# extract to user-chosen relative directory with two elements
"$cabextract" -d a/b "$basedir/cabs/dir.cab" >$actual
compare_with <<EOF
Extracting cabinet: $basedir/cabs/dir.cab
extracting a/b/plain.c
extracting a/b/1/2/3/4.c
All done, no errors.
EOF

# extract to user-chosen relative directory with two elements, one of which already exists
"$cabextract" -d tdir/a "$basedir/cabs/dir.cab" >$actual
compare_with <<EOF
Extracting cabinet: $basedir/cabs/dir.cab
extracting tdir/a/plain.c
extracting tdir/a/1/2/3/4.c
All done, no errors.
EOF

read status < $status && test "x$status" = xsuccess

0 comments on commit cc09dd3

Please sign in to comment.