libutil: reject malformed nars harder with better errors
fixes #993 Change-Id: I56aff32498ecd32e65f1576661d5a15808a4439f
This commit is contained in:
+19
-14
@@ -367,14 +367,20 @@ struct Parser
|
||||
buffer.clear(); \
|
||||
u; \
|
||||
})
|
||||
#define READ_STRING_LIMITED(limit) \
|
||||
({ \
|
||||
size_t len = FETCH_INT(size_t); \
|
||||
co_yield WantBytes{len + (8 - len % 8) % 8}; \
|
||||
StringSource src(std::string_view(buffer.data(), buffer.size())); \
|
||||
auto str = readString(src, (limit)); \
|
||||
buffer.clear(); \
|
||||
std::move(str); \
|
||||
#define READ_STRING_LIMITED(limit) \
|
||||
({ \
|
||||
size_t len = FETCH_INT(size_t); \
|
||||
if (len > (limit)) { \
|
||||
throw SerialisationError( \
|
||||
"found malformed string tag. input may be a compressed NAR, which cannot be read " \
|
||||
"directly" \
|
||||
); \
|
||||
} \
|
||||
co_yield WantBytes{len + (8 - len % 8) % 8}; \
|
||||
StringSource src(std::string_view(buffer.data(), buffer.size())); \
|
||||
auto str = readString(src, (limit)); \
|
||||
buffer.clear(); \
|
||||
std::move(str); \
|
||||
})
|
||||
#define READ_STRING() READ_STRING_LIMITED(std::numeric_limits<size_t>::max())
|
||||
#define READ_PADDING(size) \
|
||||
@@ -487,14 +493,13 @@ struct Parser
|
||||
std::string version;
|
||||
try {
|
||||
version = READ_STRING_LIMITED(narVersionMagic1.size());
|
||||
if (version != narVersionMagic1) {
|
||||
throw SerialisationError("bad NAR version tag");
|
||||
}
|
||||
co_yield parse();
|
||||
} catch (SerialisationError & e) {
|
||||
/* This generally means the integer at the start couldn't be
|
||||
decoded. Ignore and throw the exception below. */
|
||||
throw badArchive(fmt("input doesn't look like a Nix archive (%s)", e.info().msg.str()));
|
||||
}
|
||||
if (version != narVersionMagic1) {
|
||||
throw badArchive("input doesn't look like a Nix archive");
|
||||
}
|
||||
co_yield parse();
|
||||
}
|
||||
|
||||
#undef FETCH_INT
|
||||
|
||||
@@ -62,6 +62,12 @@ if nix-store --dump $storePath >/dev/full ; then
|
||||
exit -1
|
||||
fi
|
||||
|
||||
# compressed nars should cause a useful error message. we use ascii
|
||||
# text input because the salient point is the initial length field.
|
||||
echo 'not a real nar' > bad.nar
|
||||
expect 1 nix nar ls bad.nar / 2>&1 | fgrep "doesn't look like a Nix archive (found malformed string tag"
|
||||
|
||||
|
||||
# Test reading from remote nar listings if available
|
||||
nix copy --to "file://$cacheDir?write-nar-listing=true" $storePath
|
||||
|
||||
|
||||
Reference in New Issue
Block a user