From 6018f3c1eadd5c60902aa5cf4f926ff17cbaf8ab Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Thu, 8 Mar 2018 15:24:30 +0300 Subject: Check parsed package manifests for duplicates --- libbpkg/manifest.cxx | 65 +++++++++++++++++++++++++++++++---------------- tests/manifest/driver.cxx | 42 ++++++++++++++++++------------ tests/manifest/testscript | 23 ++++++++++++----- 3 files changed, 86 insertions(+), 44 deletions(-) diff --git a/libbpkg/manifest.cxx b/libbpkg/manifest.cxx index d6a7a14..89374ff 100644 --- a/libbpkg/manifest.cxx +++ b/libbpkg/manifest.cxx @@ -1515,7 +1515,7 @@ namespace bpkg // Parse package manifests. // for (nv = p.next (); !nv.empty (); nv = p.next ()) - push_back (pkg_package_manifest (p, nv, iu)); + push_back (pkg_package_manifest (p, move (nv), iu)); } void pkg_package_manifests:: @@ -1558,26 +1558,55 @@ namespace bpkg s.next ("", ""); // End of stream. } + // Parse package directory manifests. + // + static void + parse_directory_manifests (parser& p, bool iu, vector& ms) + { + // Normally, such manifests are created manually, so let's check for + // duplicates. + // + for (name_value nv (p.next ()); !nv.empty (); ) + { + package_manifest pm (dir_package_manifest (p, move (nv), iu)); + nv = p.next (); + + for (const auto& m: ms) + { + if (m.location == pm.location) + throw parsing (p.name (), + nv.name_line, nv.name_column, + "duplicate package manifest"); + } + + ms.push_back (move (pm)); + } + } + + // Serialize package directory manifests. + // + static void + serialize_directory_manifests (serializer& s, + const vector& ms) + { + for (const package_manifest& m: ms) + serialize_directory_manifest (s, m); + + s.next ("", ""); // End of stream. + } + // dir_package_manifests // dir_package_manifests:: dir_package_manifests (parser& p, bool iu) { - // Parse package manifests. - // - for (name_value nv (p.next ()); !nv.empty (); nv = p.next ()) - push_back (dir_package_manifest (p, nv, iu)); + parse_directory_manifests (p, iu, *this); } void dir_package_manifests:: serialize (serializer& s) const { - // Serialize package manifests. - // - for (const package_manifest& p: *this) - dir_package_manifest (s, p); - - s.next ("", ""); // End of stream. + serialize_directory_manifests (s, *this); } // git_package_manifests @@ -1585,21 +1614,13 @@ namespace bpkg git_package_manifests:: git_package_manifests (parser& p, bool iu) { - // Parse package manifests. - // - for (name_value nv (p.next ()); !nv.empty (); nv = p.next ()) - push_back (git_package_manifest (p, nv, iu)); + parse_directory_manifests (p, iu, *this); } void git_package_manifests:: serialize (serializer& s) const { - // Serialize package manifests. - // - for (const package_manifest& p: *this) - git_package_manifest (s, p); - - s.next ("", ""); // End of stream. + serialize_directory_manifests (s, *this); } // repository_url_traits @@ -2705,7 +2726,7 @@ namespace bpkg name_value nv (p.next ()); while (!nv.empty ()) { - ms.push_back (parse_repository_manifest (p, nv, base_type, iu)); + ms.push_back (parse_repository_manifest (p, move (nv), base_type, iu)); nv = p.next (); // Make sure there is location in all except the last entry. diff --git a/tests/manifest/driver.cxx b/tests/manifest/driver.cxx index 5e028bf..62f9d8f 100644 --- a/tests/manifest/driver.cxx +++ b/tests/manifest/driver.cxx @@ -41,20 +41,30 @@ main (int argc, char* argv[]) manifest_parser p (cin, "stdin"); manifest_serializer s (cout, "stdout"); - if (opt == "-pp") - pkg_package_manifests (p).serialize (s); - else if (opt == "-dp") - dir_package_manifests (p).serialize (s); - else if (opt == "-gp") - git_package_manifests (p).serialize (s); - else if (opt == "-pr") - pkg_repository_manifests (p).serialize (s); - else if (opt == "-dr") - dir_repository_manifests (p).serialize (s); - else if (opt == "-gr") - git_repository_manifests (p).serialize (s); - else if (opt == "-s") - signature_manifest (p).serialize (s); - else - assert (false); + try + { + if (opt == "-pp") + pkg_package_manifests (p).serialize (s); + else if (opt == "-dp") + dir_package_manifests (p).serialize (s); + else if (opt == "-gp") + git_package_manifests (p).serialize (s); + else if (opt == "-pr") + pkg_repository_manifests (p).serialize (s); + else if (opt == "-dr") + dir_repository_manifests (p).serialize (s); + else if (opt == "-gr") + git_repository_manifests (p).serialize (s); + else if (opt == "-s") + signature_manifest (p).serialize (s); + else + assert (false); + } + catch (const manifest_parsing& e) + { + cerr << e << endl; + return 1; + } + + return 0; } diff --git a/tests/manifest/testscript b/tests/manifest/testscript index b72f492..59f4db0 100644 --- a/tests/manifest/testscript +++ b/tests/manifest/testscript @@ -76,12 +76,18 @@ EOF } - : git + : dir : { - : manifest + : empty + : + : Roundtrip an empty dir package manifest list. + : + $* -gp <"" >:"" + + : non-empty : - : Roundtrip the git package manifest list. + : Roundtrip the dir package manifest list. : $* -gp <>EOF : 1 @@ -90,11 +96,16 @@ location: mhello/ EOF - : empty + : duplicate : - : Roundtrip an empty git package manifest list. + $* -gp <'stdin:5:1: error: duplicate package manifest' != 0 + : 1 + location: hello/ : - $* -gp <"" >:"" + location: hello/ + : + location: mhello/ + EOI } } -- cgit v1.1