From 44e86304b611a955f4e934fc160f3f4a0a2b1c92 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 26 Sep 2018 12:03:58 +0200 Subject: [PATCH] Make NAR header check more robust Changes std::bad_alloc into bad archive: input doesn't look like a Nix archive --- src/libutil/archive.cc | 2 +- src/libutil/serialise.cc | 5 +++-- src/libutil/serialise.hh | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/libutil/archive.cc b/src/libutil/archive.cc index 1be8934a2..bb68e8288 100644 --- a/src/libutil/archive.cc +++ b/src/libutil/archive.cc @@ -283,7 +283,7 @@ void parseDump(ParseSink & sink, Source & source) { string version; try { - version = readString(source); + version = readString(source, narVersionMagic1.size()); } catch (SerialisationError & e) { /* This generally means the integer at the start couldn't be decoded. Ignore and throw the exception below. */ diff --git a/src/libutil/serialise.cc b/src/libutil/serialise.cc index 17448f70e..31df6fdfd 100644 --- a/src/libutil/serialise.cc +++ b/src/libutil/serialise.cc @@ -268,16 +268,17 @@ void readPadding(size_t len, Source & source) size_t readString(unsigned char * buf, size_t max, Source & source) { auto len = readNum(source); - if (len > max) throw Error("string is too long"); + if (len > max) throw SerialisationError("string is too long"); source(buf, len); readPadding(len, source); return len; } -string readString(Source & source) +string readString(Source & source, size_t max) { auto len = readNum(source); + if (len > max) throw SerialisationError("string is too long"); std::string res(len, 0); source((unsigned char*) res.data(), len); readPadding(len, source); diff --git a/src/libutil/serialise.hh b/src/libutil/serialise.hh index 4b6ad5da5..969e4dff3 100644 --- a/src/libutil/serialise.hh +++ b/src/libutil/serialise.hh @@ -284,7 +284,7 @@ inline uint64_t readLongLong(Source & source) void readPadding(size_t len, Source & source); size_t readString(unsigned char * buf, size_t max, Source & source); -string readString(Source & source); +string readString(Source & source, size_t max = std::numeric_limits::max()); template T readStrings(Source & source); Source & operator >> (Source & in, string & s);