mirror of
https://github.com/NixOS/nix.git
synced 2025-11-08 19:46:02 +01:00
Merge pull request #14438 from NixOS/backport-14434-to-2.32-maintenance
[Backport 2.32-maintenance] libstore: Improve store-reference back-compat with IPv6 ZoneId literals
This commit is contained in:
commit
e1ff27324b
8 changed files with 92 additions and 2 deletions
|
|
@ -0,0 +1 @@
|
||||||
|
ssh://userinfo@[fea5:23e1:3916:fc24:cb52:2837:2ecb:ea8e%eth0]?a=b&c=d
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
ssh://userinfo@[fea5:23e1:3916:fc24:cb52:2837:2ecb:ea8e%25eth0]?a=b&c=d
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
ssh://userinfo@fea5:23e1:3916:fc24:cb52:2837:2ecb:ea8e%25?a=b&c=d
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
ssh://userinfo@fea5:23e1:3916:fc24:cb52:2837:2ecb:ea8e%eth0?a=b&c=d
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
ssh://fea5:23e1:3916:fc24:cb52:2837:2ecb:ea8e%eth0?a=b&c=d
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
ssh://fea5:23e1:3916:fc24:cb52:2837:2ecb:ea8e%eth0
|
||||||
|
|
@ -183,4 +183,64 @@ static StoreReference sshIPv6AuthorityWithUserinfoAndParams{
|
||||||
|
|
||||||
URI_TEST_READ(ssh_unbracketed_ipv6_3, sshIPv6AuthorityWithUserinfoAndParams)
|
URI_TEST_READ(ssh_unbracketed_ipv6_3, sshIPv6AuthorityWithUserinfoAndParams)
|
||||||
|
|
||||||
|
static const StoreReference sshIPv6AuthorityWithUserinfoAndParamsAndZoneId{
|
||||||
|
.variant =
|
||||||
|
StoreReference::Specified{
|
||||||
|
.scheme = "ssh",
|
||||||
|
.authority = "userinfo@[fea5:23e1:3916:fc24:cb52:2837:2ecb:ea8e%25eth0]",
|
||||||
|
},
|
||||||
|
.params =
|
||||||
|
{
|
||||||
|
{"a", "b"},
|
||||||
|
{"c", "d"},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
URI_TEST_READ(ssh_unbracketed_ipv6_4, sshIPv6AuthorityWithUserinfoAndParamsAndZoneId)
|
||||||
|
URI_TEST_READ(ssh_unbracketed_ipv6_5, sshIPv6AuthorityWithUserinfoAndParamsAndZoneId)
|
||||||
|
|
||||||
|
static const StoreReference sshIPv6AuthorityWithUserinfoAndParamsAndZoneIdTricky{
|
||||||
|
.variant =
|
||||||
|
StoreReference::Specified{
|
||||||
|
.scheme = "ssh",
|
||||||
|
.authority = "userinfo@[fea5:23e1:3916:fc24:cb52:2837:2ecb:ea8e%2525]",
|
||||||
|
},
|
||||||
|
.params =
|
||||||
|
{
|
||||||
|
{"a", "b"},
|
||||||
|
{"c", "d"},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Non-standard syntax where the IPv6 literal appears without brackets. In
|
||||||
|
// this case don't considering %25 to be a pct-encoded % and just take it as a
|
||||||
|
// literal value. 25 is a perfectly legal ZoneId value in theory.
|
||||||
|
URI_TEST_READ(ssh_unbracketed_ipv6_6, sshIPv6AuthorityWithUserinfoAndParamsAndZoneIdTricky)
|
||||||
|
URI_TEST_READ(ssh_unbracketed_ipv6_7, sshIPv6AuthorityWithUserinfoAndParamsAndZoneId)
|
||||||
|
|
||||||
|
static const StoreReference sshIPv6AuthorityWithParamsAndZoneId{
|
||||||
|
.variant =
|
||||||
|
StoreReference::Specified{
|
||||||
|
.scheme = "ssh",
|
||||||
|
.authority = "[fea5:23e1:3916:fc24:cb52:2837:2ecb:ea8e%25eth0]",
|
||||||
|
},
|
||||||
|
.params =
|
||||||
|
{
|
||||||
|
{"a", "b"},
|
||||||
|
{"c", "d"},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
URI_TEST_READ(ssh_unbracketed_ipv6_8, sshIPv6AuthorityWithParamsAndZoneId)
|
||||||
|
|
||||||
|
static const StoreReference sshIPv6AuthorityWithZoneId{
|
||||||
|
.variant =
|
||||||
|
StoreReference::Specified{
|
||||||
|
.scheme = "ssh",
|
||||||
|
.authority = "[fea5:23e1:3916:fc24:cb52:2837:2ecb:ea8e%25eth0]",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
URI_TEST_READ(ssh_unbracketed_ipv6_9, sshIPv6AuthorityWithZoneId)
|
||||||
|
|
||||||
} // namespace nix
|
} // namespace nix
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,27 @@ StoreReference StoreReference::parse(const std::string & uri, const StoreReferen
|
||||||
* greedily assumed to be the part of the host address. */
|
* greedily assumed to be the part of the host address. */
|
||||||
auto authorityString = schemeAndAuthority->authority;
|
auto authorityString = schemeAndAuthority->authority;
|
||||||
auto userinfo = splitPrefixTo(authorityString, '@');
|
auto userinfo = splitPrefixTo(authorityString, '@');
|
||||||
auto maybeIpv6 = boost::urls::parse_ipv6_address(authorityString);
|
/* Back-compat shim for ZoneId specifiers. Technically this isn't
|
||||||
|
* standard, but the expectation is this works with the old syntax
|
||||||
|
* for ZoneID specifiers. For the full story behind the fiasco that
|
||||||
|
* is ZoneID in URLs look at [^].
|
||||||
|
* [^]: https://datatracker.ietf.org/doc/html/draft-schinazi-httpbis-link-local-uri-bcp-03
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Fish out the internals from inside square brackets. It might be that the pct-sign is unencoded and that's
|
||||||
|
* why we failed to parse it previously. */
|
||||||
|
if (authorityString.starts_with('[') && authorityString.ends_with(']')) {
|
||||||
|
authorityString.remove_prefix(1);
|
||||||
|
authorityString.remove_suffix(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto maybeBeforePct = splitPrefixTo(authorityString, '%');
|
||||||
|
bool hasZoneId = maybeBeforePct.has_value();
|
||||||
|
auto maybeZoneId = hasZoneId ? std::optional{authorityString} : std::nullopt;
|
||||||
|
|
||||||
|
std::string_view maybeIpv6S = maybeBeforePct.value_or(authorityString);
|
||||||
|
auto maybeIpv6 = boost::urls::parse_ipv6_address(maybeIpv6S);
|
||||||
|
|
||||||
if (maybeIpv6) {
|
if (maybeIpv6) {
|
||||||
std::string fixedAuthority;
|
std::string fixedAuthority;
|
||||||
if (userinfo) {
|
if (userinfo) {
|
||||||
|
|
@ -129,7 +149,11 @@ StoreReference StoreReference::parse(const std::string & uri, const StoreReferen
|
||||||
fixedAuthority += '@';
|
fixedAuthority += '@';
|
||||||
}
|
}
|
||||||
fixedAuthority += '[';
|
fixedAuthority += '[';
|
||||||
fixedAuthority += authorityString;
|
fixedAuthority += maybeIpv6S;
|
||||||
|
if (maybeZoneId) {
|
||||||
|
fixedAuthority += "%25"; // pct-encoded percent character
|
||||||
|
fixedAuthority += *maybeZoneId;
|
||||||
|
}
|
||||||
fixedAuthority += ']';
|
fixedAuthority += ']';
|
||||||
return {
|
return {
|
||||||
.variant =
|
.variant =
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue