mirror of
https://github.com/NixOS/nix.git
synced 2025-11-15 15:02:42 +01:00
fix(nix-prefetch-url): correctly extract filename from URLs with query parameters
Previously, `prefetchFile()` used `baseNameOf()` directly on the URL string to extract the filename. This caused issues with URLs containing query parameters that include slashes, such as S3 URLs with custom endpoints: ``` s3://bucket/file.txt?endpoint=http://server:9000 ``` The `baseNameOf()` function naively searches for the rightmost `/` in the entire string, which would find the `/` in `http://server:9000` and extract `server:9000®ion=...` as the filename. This resulted in invalid store path names containing illegal characters like `:`. This commit fixes the issue by: 1. Adding a `VerbatimURL::lastPathSegment()` method that extracts the last non-empty path segment from a URL, using `pathSegments(true)` to filter empty segments 2. Changing `prefetchFile()` to accept `const VerbatimURL &` and use the new `lastPathSegment()` method instead of manual path parsing 3. Adding early validation with `checkName()` to fail quickly on invalid filenames 4. Maintains backward compatibility by falling back to `baseNameOf()` for unparsable `VerbatimURL`s
This commit is contained in:
parent
ddf7de0a76
commit
e3b3f05e5d
3 changed files with 44 additions and 7 deletions
|
|
@ -4,6 +4,7 @@
|
|||
#include "nix/util/split.hh"
|
||||
#include "nix/util/canon-path.hh"
|
||||
#include "nix/util/strings-inline.hh"
|
||||
#include "nix/util/file-system.hh"
|
||||
|
||||
#include <boost/url.hpp>
|
||||
|
||||
|
|
@ -440,4 +441,21 @@ std::ostream & operator<<(std::ostream & os, const VerbatimURL & url)
|
|||
return os;
|
||||
}
|
||||
|
||||
std::optional<std::string> VerbatimURL::lastPathSegment() const
|
||||
{
|
||||
try {
|
||||
auto parsedUrl = parsed();
|
||||
auto segments = parsedUrl.pathSegments(/*skipEmpty=*/true);
|
||||
if (std::ranges::empty(segments))
|
||||
return std::nullopt;
|
||||
return segments.back();
|
||||
} catch (BadURL &) {
|
||||
// Fall back to baseNameOf for unparsable URLs
|
||||
auto name = baseNameOf(to_string());
|
||||
if (name.empty())
|
||||
return std::nullopt;
|
||||
return std::string{name};
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace nix
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue