aboutsummaryrefslogtreecommitdiff
path: root/tests/unit/libstore
diff options
context:
space:
mode:
authorRobert Hensing <robert@roberthensing.nl>2024-01-30 18:37:23 +0100
committereldritch horrors <pennae@lix.systems>2024-05-02 19:34:38 +0200
commitb7ce11c97dfd0e73ddefbd15ef2cb59fee7d23f2 (patch)
treec661941f805e1ab011f584d5c02f45743e66bcad /tests/unit/libstore
parent4b3dc66386e164936227ebfbb97ce92b41512ba0 (diff)
Disallow store path names that are . or .. (plus opt. -)
As discussed in the maintainer meeting on 2024-01-29. Mainly this is to avoid a situation where the name is parsed and treated as a file name, mostly to protect users. .-* and ..-* are also considered invalid because they might strip on that separator to remove versions. Doesn't really work, but that's what we decided, and I won't argue with it, because .-* probably doesn't seem to have a real world application anyway. We do still permit a 1-character name that's just "-", which still poses a similar risk in such a situation. We can't start disallowing trailing -, because a non-zero number of users will need it and we've seen how annoying and painful such a change is. What matters most is preventing a situation where . or .. can be injected, and to just get this done. (cherry picked from commit f1b4663805a9dbcb1ace64ec110092d17c9155e0) Change-Id: I900a8509933cee662f888c3c76fa8986b0058839
Diffstat (limited to 'tests/unit/libstore')
-rw-r--r--tests/unit/libstore/path.cc68
1 files changed, 68 insertions, 0 deletions
diff --git a/tests/unit/libstore/path.cc b/tests/unit/libstore/path.cc
index f7b69d5f9..213b6e95f 100644
--- a/tests/unit/libstore/path.cc
+++ b/tests/unit/libstore/path.cc
@@ -39,6 +39,12 @@ TEST_DONT_PARSE(double_star, "**")
TEST_DONT_PARSE(star_first, "*,foo")
TEST_DONT_PARSE(star_second, "foo,*")
TEST_DONT_PARSE(bang, "foo!o")
+TEST_DONT_PARSE(dot, ".")
+TEST_DONT_PARSE(dot_dot, "..")
+TEST_DONT_PARSE(dot_dot_dash, "..-1")
+TEST_DONT_PARSE(dot_dash, ".-1")
+TEST_DONT_PARSE(dot_dot_dash_a, "..-a")
+TEST_DONT_PARSE(dot_dash_a, ".-a")
#undef TEST_DONT_PARSE
@@ -63,6 +69,10 @@ TEST_DO_PARSE(period, "foo.txt")
TEST_DO_PARSE(question_mark, "foo?why")
TEST_DO_PARSE(equals_sign, "foo=foo")
TEST_DO_PARSE(dotfile, ".gitignore")
+TEST_DO_PARSE(triple_dot_a, "...a")
+TEST_DO_PARSE(triple_dot_1, "...1")
+TEST_DO_PARSE(triple_dot_dash, "...-")
+TEST_DO_PARSE(triple_dot, "...")
#undef TEST_DO_PARSE
@@ -84,6 +94,64 @@ RC_GTEST_FIXTURE_PROP(
RC_ASSERT(p == store->parseStorePath(store->printStorePath(p)));
}
+
+RC_GTEST_FIXTURE_PROP(
+ StorePathTest,
+ prop_check_regex_eq_parse,
+ ())
+{
+ static auto nameFuzzer =
+ rc::gen::container<std::string>(
+ rc::gen::oneOf(
+ // alphanum, repeated to weigh heavier
+ rc::gen::oneOf(
+ rc::gen::inRange('0', '9'),
+ rc::gen::inRange('a', 'z'),
+ rc::gen::inRange('A', 'Z')
+ ),
+ // valid symbols
+ rc::gen::oneOf(
+ rc::gen::just('+'),
+ rc::gen::just('-'),
+ rc::gen::just('.'),
+ rc::gen::just('_'),
+ rc::gen::just('?'),
+ rc::gen::just('=')
+ ),
+ // symbols for scary .- and ..- cases, repeated for weight
+ rc::gen::just('.'), rc::gen::just('.'),
+ rc::gen::just('.'), rc::gen::just('.'),
+ rc::gen::just('-'), rc::gen::just('-'),
+ // ascii symbol ranges
+ rc::gen::oneOf(
+ rc::gen::inRange(' ', '/'),
+ rc::gen::inRange(':', '@'),
+ rc::gen::inRange('[', '`'),
+ rc::gen::inRange('{', '~')
+ ),
+ // typical whitespace
+ rc::gen::oneOf(
+ rc::gen::just(' '),
+ rc::gen::just('\t'),
+ rc::gen::just('\n'),
+ rc::gen::just('\r')
+ ),
+ // some chance of control codes, non-ascii or other garbage we missed
+ rc::gen::inRange('\0', '\xff')
+ ));
+
+ auto name = *nameFuzzer;
+
+ std::string path = store->storeDir + "/575s52sh487i0ylmbs9pvi606ljdszr0-" + name;
+ bool parsed = false;
+ try {
+ store->parseStorePath(path);
+ parsed = true;
+ } catch (const BadStorePath &) {
+ }
+ RC_ASSERT(parsed == std::regex_match(std::string { name }, nameRegex));
+}
+
#endif
}