From 61db590ad857ef145de45fbfdd5513eb45077b37 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Fri, 26 Feb 2021 12:29:42 -0500 Subject: [PATCH 1/2] Detect `..` in Paths Correctly This commit addresses #2509. --- programs/util.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/programs/util.c b/programs/util.c index 7208d66d..3fd4cd17 100644 --- a/programs/util.c +++ b/programs/util.c @@ -679,7 +679,27 @@ const char* UTIL_getFileExtension(const char* infilename) static int pathnameHas2Dots(const char *pathname) { - return NULL != strstr(pathname, ".."); + /* We need to figure out whether any ".." present in the path is a whole + * path token, which is the case if it is bordered on both sides by either + * the beginning/end of the path or by a directory separator. + */ + const char *needle = pathname; + while (1) { + needle = strstr(needle, ".."); + + if (needle == NULL) { + return 0; + } + + if ((needle == pathname || needle[-1] == PATH_SEP) + && (needle[2] == '\0' || needle[2] == PATH_SEP)) { + return 1; + } + + /* increment so we search for the next match */ + needle++; + }; + return 0; } static int isFileNameValidForMirroredOutput(const char *filename) From 9b7f9d26d5cefe2f9208950e15866b69525e9e46 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Fri, 26 Feb 2021 13:01:20 -0500 Subject: [PATCH 2/2] Cover These Edge Cases in Tests --- tests/playTests.sh | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/tests/playTests.sh b/tests/playTests.sh index ec1692c2..8550bade 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -486,23 +486,29 @@ rm -rf tmp* if [ "$isWindows" = false ] ; then println "\n===> compress multiple files into an output directory and mirror input folder, --output-dir-mirror" println "test --output-dir-mirror" > tmp1 - mkdir -p tmpInputTestDir/we/must/go/deeper - println cool > tmpInputTestDir/we/must/go/deeper/tmp2 + mkdir -p tmpInputTestDir/we/.../..must/go/deeper.. + println cool > tmpInputTestDir/we/.../..must/go/deeper../tmp2 zstd tmp1 -r tmpInputTestDir --output-dir-mirror tmpOutDir test -f tmpOutDir/tmp1.zst - test -f tmpOutDir/tmpInputTestDir/we/must/go/deeper/tmp2.zst + test -f tmpOutDir/tmpInputTestDir/we/.../..must/go/deeper../tmp2.zst println "test: compress input dir will be ignored if it has '..'" - zstd -r tmpInputTestDir/we/must/../must --output-dir-mirror non-exist && die "input cannot contain '..'" + zstd -r tmpInputTestDir/we/.../..must/../..mustgo/deeper.. --output-dir-mirror non-exist && die "input cannot contain '..'" + zstd -r tmpInputTestDir/we/.../..must/deeper../.. --output-dir-mirror non-exist && die "input cannot contain '..'" + zstd -r ../tests/tmpInputTestDir/we/.../..must/deeper.. --output-dir-mirror non-exist && die "input cannot contain '..'" test ! -d non-exist + println "test: compress input dir should succeed with benign uses of '..'" + zstd -r tmpInputTestDir/we/.../..must/go/deeper.. --output-dir-mirror tmpout + test -d tmpout + println "test : decompress multiple files into an output directory, --output-dir-mirror" zstd tmpOutDir -r -d --output-dir-mirror tmpOutDirDecomp test -f tmpOutDirDecomp/tmpOutDir/tmp1 - test -f tmpOutDirDecomp/tmpOutDir/tmpInputTestDir/we/must/go/deeper/tmp2 + test -f tmpOutDirDecomp/tmpOutDir/tmpInputTestDir/we/.../..must/go/deeper../tmp2 println "test: decompress input dir will be ignored if it has '..'" - zstd -r tmpOutDir/tmpInputTestDir/we/must/../must --output-dir-mirror non-exist && die "input cannot contain '..'" + zstd -r tmpOutDir/tmpInputTestDir/we/.../..must/../..must --output-dir-mirror non-exist && die "input cannot contain '..'" test ! -d non-exist rm -rf tmp*