diff options
author | Pierre Bourdon <delroth@gmail.com> | 2024-05-18 07:26:26 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@lix-systems> | 2024-05-18 07:26:26 +0000 |
commit | d1c8fd3b0981a53f122dc4b9e5cda705de3c1ac2 (patch) | |
tree | 6135f2fd7821e373063481f3f694b73a77a2e858 | |
parent | 7a3745b07607d3fc85fb5a0a08832ab078080884 (diff) | |
parent | 5a1824ebe1fcdeff86b57a13a33d6428e89e4bce (diff) |
Merge "derived-path: refuse built derived path with a non-derivation base" into main
-rw-r--r-- | src/libstore/derived-path.cc | 46 | ||||
-rw-r--r-- | tests/unit/libstore/derived-path.cc | 9 |
2 files changed, 29 insertions, 26 deletions
diff --git a/src/libstore/derived-path.cc b/src/libstore/derived-path.cc index 214caab54..22977c7b1 100644 --- a/src/libstore/derived-path.cc +++ b/src/libstore/derived-path.cc @@ -185,21 +185,32 @@ DerivedPath::Built DerivedPath::Built::parse( }; } -static SingleDerivedPath parseWithSingle( +template <typename DerivedPathT> +static DerivedPathT parseDerivedPath( const Store & store, std::string_view s, std::string_view separator, const ExperimentalFeatureSettings & xpSettings) { size_t n = s.rfind(separator); - return n == s.npos - ? (SingleDerivedPath) SingleDerivedPath::Opaque::parse(store, s) - : (SingleDerivedPath) SingleDerivedPath::Built::parse(store, - make_ref<SingleDerivedPath>(parseWithSingle( + if (n == s.npos) { + return DerivedPathT::Opaque::parse(store, s); + } else { + auto path = DerivedPathT::Built::parse(store, + make_ref<SingleDerivedPath>(parseDerivedPath<SingleDerivedPath>( store, s.substr(0, n), separator, xpSettings)), s.substr(n + 1), xpSettings); + + const auto& basePath = path.getBaseStorePath(); + if (!basePath.isDerivation()) { + throw InvalidPath("cannot use output selection ('%s') on non-derivation store path '%s'", + separator, basePath.to_string()); + } + + return path; + } } SingleDerivedPath SingleDerivedPath::parse( @@ -207,7 +218,7 @@ SingleDerivedPath SingleDerivedPath::parse( std::string_view s, const ExperimentalFeatureSettings & xpSettings) { - return parseWithSingle(store, s, "^", xpSettings); + return parseDerivedPath<SingleDerivedPath>(store, s, "^", xpSettings); } SingleDerivedPath SingleDerivedPath::parseLegacy( @@ -215,24 +226,7 @@ SingleDerivedPath SingleDerivedPath::parseLegacy( std::string_view s, const ExperimentalFeatureSettings & xpSettings) { - return parseWithSingle(store, s, "!", xpSettings); -} - -static DerivedPath parseWith( - const Store & store, std::string_view s, std::string_view separator, - const ExperimentalFeatureSettings & xpSettings) -{ - size_t n = s.rfind(separator); - return n == s.npos - ? (DerivedPath) DerivedPath::Opaque::parse(store, s) - : (DerivedPath) DerivedPath::Built::parse(store, - make_ref<SingleDerivedPath>(parseWithSingle( - store, - s.substr(0, n), - separator, - xpSettings)), - s.substr(n + 1), - xpSettings); + return parseDerivedPath<SingleDerivedPath>(store, s, "!", xpSettings); } DerivedPath DerivedPath::parse( @@ -240,7 +234,7 @@ DerivedPath DerivedPath::parse( std::string_view s, const ExperimentalFeatureSettings & xpSettings) { - return parseWith(store, s, "^", xpSettings); + return parseDerivedPath<DerivedPath>(store, s, "^", xpSettings); } DerivedPath DerivedPath::parseLegacy( @@ -248,7 +242,7 @@ DerivedPath DerivedPath::parseLegacy( std::string_view s, const ExperimentalFeatureSettings & xpSettings) { - return parseWith(store, s, "!", xpSettings); + return parseDerivedPath<DerivedPath>(store, s, "!", xpSettings); } DerivedPath DerivedPath::fromSingle(const SingleDerivedPath & req) diff --git a/tests/unit/libstore/derived-path.cc b/tests/unit/libstore/derived-path.cc index c62d79a78..ffa541e9f 100644 --- a/tests/unit/libstore/derived-path.cc +++ b/tests/unit/libstore/derived-path.cc @@ -77,6 +77,15 @@ TEST_F(DerivedPathTest, built_built_xp) { MissingExperimentalFeature); } +/** + * Built paths with a non-derivation base should fail parsing. + */ +TEST_F(DerivedPathTest, non_derivation_base) { + ASSERT_THROW( + DerivedPath::parse(*store, "/nix/store/g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-x^foo"), + InvalidPath); +} + #ifndef COVERAGE RC_GTEST_FIXTURE_PROP( |