diff --git a/src/libutil-tests/archive.cc b/src/libutil-tests/archive.cc new file mode 100644 index 000000000..386f7b857 --- /dev/null +++ b/src/libutil-tests/archive.cc @@ -0,0 +1,47 @@ +#include "nix/util/archive.hh" +#include "nix/util/tests/characterization.hh" +#include "nix/util/tests/gmock-matchers.hh" + +#include + +namespace nix { + +namespace { + +class NarTest : public CharacterizationTest +{ + std::filesystem::path unitTestData = getUnitTestData() / "nars"; + +public: + std::filesystem::path goldenMaster(std::string_view testStem) const override + { + return unitTestData / (std::string(testStem) + ".nar"); + } +}; + +class InvalidNarTest : public NarTest, public ::testing::WithParamInterface> +{}; + +} // namespace + +TEST_P(InvalidNarTest, throwsErrorMessage) +{ + const auto & [name, message] = GetParam(); + readTest(name, [&](const std::string & narContents) { + ASSERT_THAT( + [&]() { + StringSource source{narContents}; + NullFileSystemObjectSink sink; + parseDump(sink, source); + }, + ::testing::ThrowsMessage(testing::HasSubstrIgnoreANSIMatcher(message))); + }); +} + +INSTANTIATE_TEST_SUITE_P( + NarTest, + InvalidNarTest, + ::testing::Values( + std::pair{"invalid-tag-instead-of-contents", "bad archive: expected tag 'contents', got 'AAAAAAAA'"})); + +} // namespace nix diff --git a/src/libutil-tests/data/nars/invalid-tag-instead-of-contents.nar b/src/libutil-tests/data/nars/invalid-tag-instead-of-contents.nar new file mode 100644 index 000000000..80dbf5a12 Binary files /dev/null and b/src/libutil-tests/data/nars/invalid-tag-instead-of-contents.nar differ diff --git a/src/libutil-tests/meson.build b/src/libutil-tests/meson.build index 0e2a2e468..ec235ae98 100644 --- a/src/libutil-tests/meson.build +++ b/src/libutil-tests/meson.build @@ -44,6 +44,7 @@ config_priv_h = configure_file( subdir('nix-meson-build-support/common') sources = files( + 'archive.cc', 'args.cc', 'base-n.cc', 'canon-path.cc', diff --git a/src/libutil/archive.cc b/src/libutil/archive.cc index b978ac4db..3d96df75e 100644 --- a/src/libutil/archive.cc +++ b/src/libutil/archive.cc @@ -187,8 +187,10 @@ static void parse(FileSystemObjectSink & sink, Source & source, const CanonPath tag = getString(); } - if (tag == "contents") - parseContents(crf, source); + if (tag != "contents") + throw badArchive("expected tag 'contents', got '%s'", tag); + + parseContents(crf, source); expectTag(")"); });