Skip to content

Commit

Permalink
fix extracting files with tricky pathnames containing . and .. (fix #712
Browse files Browse the repository at this point in the history
)
  • Loading branch information
elfmz committed Jun 21, 2020
1 parent 88e6a11 commit 243730c
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 7 deletions.
7 changes: 3 additions & 4 deletions multiarc/src/formats/libarch/libarch_cmd_read.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,9 @@ static bool LIBARCH_CommandReadWanteds(const char *cmd, LibArchOpenRead &arc, co
}

const char *pathname = archive_entry_pathname(entry);

src_path = pathname ? pathname : "";
parts.clear();
StrExplode(parts, src_path, "/\\");
LibArch_ParsePathToParts(parts, src_path);

if (parts.empty()) {
fprintf(stderr, "Empty path: '%s'\n", pathname);
Expand Down Expand Up @@ -108,10 +107,10 @@ bool LIBARCH_CommandRead(const char *cmd, const char *arc_path, const char *arc_
for (int i = 0; i < files_cnt; ++i) {
wanteds.emplace_back();
if (arc_root_path && *arc_root_path) {
StrExplode(wanteds.back(), std::string(arc_root_path), "/\\");
LibArch_ParsePathToParts(wanteds.back(), std::string(arc_root_path));
}
if (files[i] && *files[i]) {
StrExplode(wanteds.back(), std::string(files[i]), "/\\");
LibArch_ParsePathToParts(wanteds.back(), std::string(files[i]));
}
if (wanteds.back().empty()) {
fprintf(stderr, "Skipping empty path: '%s'\n", files[i]);
Expand Down
6 changes: 3 additions & 3 deletions multiarc/src/formats/libarch/libarch_cmd_write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,10 +213,10 @@ static bool LIBARCH_CommandRemoveOrReplace(const char *cmd, const char *arc_path
files_parts.emplace_back();
if (arc_root_path && *arc_root_path) {
str = arc_root_path;
StrExplode(files_parts.back(), str, "/\\");
LibArch_ParsePathToParts(files_parts.back(), str);
}
str = files[i];
StrExplode(files_parts.back(), str, "/\\");
LibArch_ParsePathToParts(files_parts.back(), str);
}

std::vector<std::string> parts;
Expand All @@ -233,7 +233,7 @@ static bool LIBARCH_CommandRemoveOrReplace(const char *cmd, const char *arc_path
if (pathname) {
parts.clear();
str = pathname;
StrExplode(parts, str, "/\\");
LibArch_ParsePathToParts(parts, str);
bool matches = false;
for (const auto &fp : files_parts) {
size_t i = 0;
Expand Down
21 changes: 21 additions & 0 deletions multiarc/src/formats/libarch/libarch_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,27 @@ bool LibArch_DetectedFormatHasCompression(struct archive *a)
}


void LibArch_ParsePathToParts(std::vector<std::string> &parts, const std::string &path)
{
size_t i = parts.size();
StrExplode(parts, path, "/");
while (i < parts.size()) {
if (parts[i] == ".") {
parts.erase(parts.begin() + i);
} else if (parts[i] == "..") {
parts.erase(parts.begin() + i);
if (i != 0) {
parts.erase(parts.begin() + i - 1);
--i;
} else {
fprintf(stderr, "LibArch_ParsePathToParts: impossible <..> in '%s'\n", path.c_str());
}
} else {
++i;
}
}
}

LibArchOpenRead::LibArchOpenRead(const char *name, const char *cmd)
{
Open(name);
Expand Down
2 changes: 2 additions & 0 deletions multiarc/src/formats/libarch/libarch_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ template <typename ... ARGS>
};

bool LibArch_DetectedFormatHasCompression(struct archive *a);
void LibArch_ParsePathToParts(std::vector<std::string> &parts, const std::string &path);

struct LibArchOpenRead
{
Expand Down Expand Up @@ -67,3 +68,4 @@ struct LibArchOpenWrite
private:
LibArchOpenWrite(const LibArchOpenWrite&) = delete;
};

0 comments on commit 243730c

Please sign in to comment.