Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
FileSystem: only load zip symlink from the same pak
  • Loading branch information
illwieckz committed Mar 10, 2019
1 parent 88a8c41 commit 1206aad
Showing 1 changed file with 94 additions and 51 deletions.
145 changes: 94 additions & 51 deletions src/common/FileSystem.cpp
Expand Up @@ -1354,7 +1354,91 @@ std::string ExpandSymlink(Str::StringRef path, Str::StringRef content)
return mergestart;
}

std::string ReadFile(Str::StringRef path, int symlinkLevels, std::error_code& err)
std::string ReadZipFile(LoadedPakInfo pak, ZipArchive *zipFile, Str::StringRef originalPath, Str::StringRef path, int symlinkLevels, std::error_code& err)
{
auto it = fileMap.find(path);
if (it == fileMap.end()) {
SetErrorCodeFilesystem(err, filesystem_error::no_such_file);
return "";
}

const LoadedPakInfo& p = loadedPaks[it->second.first];

// Open file
if (p.type == pakType_t::PAK_DIR) {
Log::Warn("symlink %s tried to escape the pak", path);
return "";
}

if (p.fd != pak.fd) {
Log::Warn("symlink %s tried to escape the pak", path);
return "";
}

// Read file contents
zipFile->OpenFile(it->second.second, err);

if (err) {
return "";
}

// Open file in zip
offset_t length = zipFile->FileLength(err);

if (err) {
return "";
}

// Read file
std::string out;
out.resize(length);
zipFile->ReadFile(&out[0], length, err);

if (err) {
return "";
}

bool isSymlink = zipFile->IsSymlink(err);
if (err) {
return "";
}

if (isSymlink) {
if (UsePakSymlink()) {
if (symlinkLevels <= 0) {
Log::Debug("symlink %s: too many levels of symbolic links", originalPath);
return "";
}

out = ExpandSymlink(path, out);

if (out[0] == '\0') {
return "";
}

auto it = fileMap.find(path);

if (it == fileMap.end()) {
SetErrorCodeFilesystem(err, filesystem_error::no_such_file);
return "";
}

out = ReadZipFile(pak, zipFile, originalPath, out, symlinkLevels -1, err);

if (err) {
return "";
}
}
else {
Log::Warn("symlink found in archive but fs_pakSymlink is disabled: %s", originalPath);
return "";
}
}

return out;
}

std::string ReadFile(Str::StringRef path, std::error_code& err)
{
auto it = fileMap.find(path);
if (it == fileMap.end()) {
Expand All @@ -1372,13 +1456,15 @@ std::string ReadFile(Str::StringRef path, int symlinkLevels, std::error_code& er
#else
File file = RawPath::OpenRead(Path::Build(pak.path, path), err);
#endif
if (err)
if (err) {
return "";
}

// Get file length
offset_t length = file.Length(err);
if (err)
if (err) {
return "";
}

// Read file contents
std::string out;
Expand All @@ -1388,72 +1474,29 @@ std::string ReadFile(Str::StringRef path, int symlinkLevels, std::error_code& er
} else if (pak.type == pakType_t::PAK_ZIP) {
// Open zip
ZipArchive zipFile = ZipArchive::Open(pak.fd, err);
if (err)
return "";

// Open file in zip
zipFile.OpenFile(it->second.second, err);
if (err)
return "";

// Get file length
offset_t length = zipFile.FileLength(err);
if (err)
if (err) {
return "";
}

// Read file
std::string out;
out.resize(length);
zipFile.ReadFile(&out[0], length, err);
if (err)
return "";
std::string out = ReadZipFile(pak, &zipFile, path, path, MAX_SYMLINK_LEVELS, err);

bool isSymlink = zipFile.IsSymlink(err);
if (err) {
return "";
}

// Close file and check for CRC errors
zipFile.CloseFile(err);
if (err)
if (err) {
return "";

if (isSymlink) {
if (UsePakSymlink()) {
if (symlinkLevels <= 0) {
Log::Debug("symlink: %s: too many levels of symbolic links", path);
return "";
}
out = ExpandSymlink(path, out);
if (out[0] == '\0') {
return "";
}
out = ReadFile(out, symlinkLevels -1, err);
if (err) {
return "";
}
}
else {
Log::Warn("symlink found in archive but fs_pakSymlink is disabled: %s", path);
return "";
}
}

return out;
return out;
}

ASSERT_UNREACHABLE();
}

std::string ReadFile(Str::StringRef path, std::error_code& err)
{
std::string out = ReadFile(path, MAX_SYMLINK_LEVELS, err);
if (err) {
return "";
}
return out;
}

void CopyFile(Str::StringRef path, const File& dest, std::error_code& err)
{
auto it = fileMap.find(path);
Expand Down

0 comments on commit 1206aad

Please sign in to comment.