aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2018-05-21 17:25:00 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2018-05-21 18:30:18 +0300
commite3c8b1c5273e20a6c20b5ba923cdcea919340950 (patch)
treeb1ac64796daed928aba3eca6e65165960a1e940b
parent716a34125008cb5ad16b32b0032822b7e27d0225 (diff)
Add validate_package_name() function, validate manifest package names
-rw-r--r--libbpkg/manifest.cxx86
-rw-r--r--libbpkg/manifest.hxx7
-rw-r--r--tests/manifest/testscript79
3 files changed, 161 insertions, 11 deletions
diff --git a/libbpkg/manifest.cxx b/libbpkg/manifest.cxx
index a7d8b95..3e9a4fa 100644
--- a/libbpkg/manifest.cxx
+++ b/libbpkg/manifest.cxx
@@ -17,7 +17,7 @@
#include <libbutl/path.mxx>
#include <libbutl/base64.mxx>
#include <libbutl/utility.mxx> // casecmp(), lcase(), alpha(),
- // digit(), xdigit()
+ // alnum(), digit(), xdigit()
#include <libbutl/manifest-parser.mxx>
#include <libbutl/manifest-serializer.mxx>
#include <libbutl/standard-version.mxx>
@@ -870,6 +870,44 @@ namespace bpkg
return o;
}
+ // Package name.
+ //
+ static const strings illegal_pkg_names ({
+ "build",
+ "con", "prn", "aux", "nul",
+ "com1", "com2", "com3", "com4", "com5", "com6", "com7", "com8", "com9",
+ "lpt1", "lpt2", "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9"});
+
+ static const string legal_pkg_chars ("_+-.");
+
+ void
+ validate_package_name (const string& name)
+ {
+ if (name.size () < 2)
+ throw invalid_argument ("length is less than two characters");
+
+ if (find (illegal_pkg_names.begin (), illegal_pkg_names.end (), name) !=
+ illegal_pkg_names.end ())
+ throw invalid_argument ("illegal name");
+
+ if (!alpha (name.front ()))
+ throw invalid_argument ("illegal first character (must be alphabetic)");
+
+ // Here we rely on the fact that the name length >= 2.
+ //
+ for (auto i (name.cbegin () + 1), e (name.cend () - 1); i != e; ++i)
+ {
+ char c (*i);
+
+ if (!(alnum(c) || legal_pkg_chars.find (c) != string::npos))
+ throw invalid_argument ("illegal character");
+ }
+
+ if (!alnum (name.back ()))
+ throw invalid_argument (
+ "illegal last character (must be alphabetic or digit)");
+ }
+
// pkg_package_manifest
//
static void
@@ -946,8 +984,14 @@ namespace bpkg
if (!m.name.empty ())
bad_name ("package name redefinition");
- if (v.empty ())
- bad_value ("empty package name");
+ try
+ {
+ validate_package_name (v);
+ }
+ catch (const invalid_argument& e)
+ {
+ bad_value (string ("invalid package name: ") + e.what ());
+ }
m.name = move (v);
}
@@ -1222,15 +1266,22 @@ namespace bpkg
ne = i + 1;
}
+ string nm (i == e ? move (lv) : string (b, ne));
+
+ try
+ {
+ validate_package_name (nm);
+ }
+ catch (const invalid_argument& e)
+ {
+ bad_value (
+ string ("invalid prerequisite package name: ") + e.what ());
+ }
+
if (i == e)
- da.push_back (dependency {lv, nullopt});
+ da.push_back (dependency {move (nm), nullopt});
else
{
- string nm (b, ne);
-
- if (nm.empty ())
- bad_value ("prerequisite package name not specified");
-
try
{
da.push_back (
@@ -1356,14 +1407,27 @@ namespace bpkg
serialize (serializer& s) const
{
// @@ Should we check that all non-optional values are specified ?
- // @@ Should we check that values are valid: name is not empty, version
- // release is not empty, sha256sum is a proper string, ...?
+ // @@ Should we check that values are valid: version release is not empty,
+ // sha256sum is a proper string, ...?
// @@ Currently we don't know if we are serializing the individual package
// manifest or the package list manifest, so can't ensure all values
// allowed in the current context (*-file values).
//
s.next ("", "1"); // Start of manifest.
+
+ auto bad_value ([&s](const string& d) {
+ throw serialization (s.name (), d);});
+
+ try
+ {
+ validate_package_name (name);
+ }
+ catch (const invalid_argument& e)
+ {
+ bad_value (string ("invalid package name: ") + e.what ());
+ }
+
s.next ("name", name);
s.next ("version", version.string ());
diff --git a/libbpkg/manifest.hxx b/libbpkg/manifest.hxx
index f1e031e..97239db 100644
--- a/libbpkg/manifest.hxx
+++ b/libbpkg/manifest.hxx
@@ -376,6 +376,13 @@ namespace bpkg
comment (std::move (c)) {}
};
+ // Check if the package name complies with the specification (see the bpkg
+ // manual for details) and throw std::invalid_argument if that's not the
+ // case.
+ //
+ LIBBPKG_EXPORT void
+ validate_package_name (const std::string&);
+
class LIBBPKG_EXPORT package_manifest
{
public:
diff --git a/tests/manifest/testscript b/tests/manifest/testscript
index 15a20ab..c8fdfaa 100644
--- a/tests/manifest/testscript
+++ b/tests/manifest/testscript
@@ -5,6 +5,85 @@
: packages
:
{
+ : name
+ :
+ {
+ : valid
+ :
+ $* -pp <<EOF >>EOF
+ : 1
+ sha256sum: a2b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+ :
+ name: libfoo.c++-2
+ version: 2.0.0
+ summary: Modern C++ parser
+ license: LGPLv2
+ url: http://www.example.org/projects/libfoo/
+ email: libfoo-users@example.org
+ location: libfoo.c++-2-2.0.0.tar.bz2
+ sha256sum: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+ EOF
+
+ : invalid
+ :
+ {
+ : short
+ :
+ $* -pp <<EOI 2>'stdin:4:7: error: invalid package name: length is less than two characters' != 0
+ : 1
+ sha256sum: a2b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+ :
+ name: b
+ EOI
+
+ : illegal
+ :
+ $* -pp <<EOI 2>'stdin:4:7: error: invalid package name: illegal name' != 0
+ : 1
+ sha256sum: a2b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+ :
+ name: com3
+ EOI
+
+ : first-char
+ :
+ $* -pp <<EOI 2>'stdin:4:7: error: invalid package name: illegal first character (must be alphabetic)' != 0
+ : 1
+ sha256sum: a2b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+ :
+ name: 2b
+ EOI
+
+ : last-char
+ :
+ $* -pp <<EOI 2>'stdin:4:7: error: invalid package name: illegal last character (must be alphabetic or digit)' != 0
+ : 1
+ sha256sum: a2b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+ :
+ name: foo_
+ EOI
+
+ : char
+ :
+ $* -pp <<EOI 2>'stdin:4:7: error: invalid package name: illegal character' != 0
+ : 1
+ sha256sum: a2b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+ :
+ name: foo'bar
+ EOI
+
+ : dependency
+ :
+ $* -pp <<EOI 2>'stdin:5:10: error: invalid prerequisite package name: length is less than two characters' != 0
+ : 1
+ sha256sum: a2b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+ :
+ name: foo
+ depends: b
+ EOI
+ }
+ }
+
: pkg
:
{