ZipInputAccessor: Fix symlink handling

This commit is contained in:
Eelco Dolstra 2022-05-12 12:06:50 +02:00
parent 65c957f0c1
commit b6cf6e5553
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE

View file

@ -58,10 +58,8 @@ struct ZipInputAccessor : InputAccessor
if (zipFile) zip_close(zipFile); if (zipFile) zip_close(zipFile);
} }
std::string readFile(PathView _path) override std::string _readFile(PathView path)
{ {
auto path = canonPath(_path);
auto i = members.find(((std::string) path).c_str()); auto i = members.find(((std::string) path).c_str());
if (i == members.end()) if (i == members.end())
throw Error("file '%s' does not exist", path); throw Error("file '%s' does not exist", path);
@ -78,6 +76,16 @@ struct ZipInputAccessor : InputAccessor
return buf; return buf;
} }
std::string readFile(PathView _path) override
{
auto path = canonPath(_path);
if (lstat(path).type != tRegular)
throw Error("file '%s' is not a regular file");
return _readFile(path);
}
bool pathExists(PathView _path) override bool pathExists(PathView _path) override
{ {
auto path = canonPath(_path); auto path = canonPath(_path);
@ -104,6 +112,7 @@ struct ZipInputAccessor : InputAccessor
if (i == members.end()) if (i == members.end())
throw Error("file '%s' does not exist", path); throw Error("file '%s' does not exist", path);
// FIXME: cache this
zip_uint8_t opsys; zip_uint8_t opsys;
zip_uint32_t attributes; zip_uint32_t attributes;
if (zip_file_get_external_attributes(zipFile, i->second.index, ZIP_FL_UNCHANGED, &opsys, &attributes) == -1) if (zip_file_get_external_attributes(zipFile, i->second.index, ZIP_FL_UNCHANGED, &opsys, &attributes) == -1)
@ -112,8 +121,8 @@ struct ZipInputAccessor : InputAccessor
switch (opsys) { switch (opsys) {
case ZIP_OPSYS_UNIX: case ZIP_OPSYS_UNIX:
auto type = (attributes >> 16) & 0770000; auto t = (attributes >> 16) & 0770000;
switch (type) { switch (t) {
case 0040000: type = tDirectory; break; case 0040000: type = tDirectory; break;
case 0100000: case 0100000:
type = tRegular; type = tRegular;
@ -121,7 +130,7 @@ struct ZipInputAccessor : InputAccessor
break; break;
case 0120000: type = tSymlink; break; case 0120000: type = tSymlink; break;
default: default:
throw Error("file '%s' in '%s' has unsupported type %o", path, zipPath, type); throw Error("file '%s' in '%s' has unsupported type %o", path, zipPath, t);
} }
break; break;
} }
@ -153,9 +162,14 @@ struct ZipInputAccessor : InputAccessor
return entries; return entries;
} }
std::string readLink(PathView path) override std::string readLink(PathView _path) override
{ {
throw UnimplementedError("ZipInputAccessor::readLink"); auto path = canonPath(_path);
if (lstat(path).type != tSymlink)
throw Error("file '%s' is not a symlink");
return _readFile(canonPath(_path));
} }
}; };