mirror of
https://github.com/NixOS/nix.git
synced 2025-12-07 17:41:00 +01:00
Merge pull request #13943 from NixOS/mergify/bp/2.31-maintenance/pr-13940
libstore: Reallow unbracketed IPv6 addresses in store references (backport #13940)
This commit is contained in:
commit
1676a04197
6 changed files with 91 additions and 2 deletions
|
|
@ -0,0 +1 @@
|
|||
ssh://::1
|
||||
|
|
@ -0,0 +1 @@
|
|||
ssh://userinfo@fea5:23e1:3916:fc24:cb52:2837:2ecb:ea8e
|
||||
|
|
@ -0,0 +1 @@
|
|||
ssh://userinfo@fea5:23e1:3916:fc24:cb52:2837:2ecb:ea8e?a=b&c=d
|
||||
|
|
@ -148,4 +148,39 @@ URI_TEST(
|
|||
.params = {},
|
||||
}))
|
||||
|
||||
static StoreReference sshLoopbackIPv6{
|
||||
.variant =
|
||||
StoreReference::Specified{
|
||||
.scheme = "ssh",
|
||||
.authority = "[::1]",
|
||||
},
|
||||
};
|
||||
|
||||
URI_TEST_READ(ssh_unbracketed_ipv6_1, sshLoopbackIPv6)
|
||||
|
||||
static StoreReference sshIPv6AuthorityWithUserinfo{
|
||||
.variant =
|
||||
StoreReference::Specified{
|
||||
.scheme = "ssh",
|
||||
.authority = "userinfo@[fea5:23e1:3916:fc24:cb52:2837:2ecb:ea8e]",
|
||||
},
|
||||
};
|
||||
|
||||
URI_TEST_READ(ssh_unbracketed_ipv6_2, sshIPv6AuthorityWithUserinfo)
|
||||
|
||||
static StoreReference sshIPv6AuthorityWithUserinfoAndParams{
|
||||
.variant =
|
||||
StoreReference::Specified{
|
||||
.scheme = "ssh",
|
||||
.authority = "userinfo@[fea5:23e1:3916:fc24:cb52:2837:2ecb:ea8e]",
|
||||
},
|
||||
.params =
|
||||
{
|
||||
{"a", "b"},
|
||||
{"c", "d"},
|
||||
},
|
||||
};
|
||||
|
||||
URI_TEST_READ(ssh_unbracketed_ipv6_3, sshIPv6AuthorityWithUserinfoAndParams)
|
||||
|
||||
} // namespace nix
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ boost = dependency(
|
|||
'container',
|
||||
# Shouldn't list, because can header-only, and Meson currently looks for libs
|
||||
#'regex',
|
||||
'url',
|
||||
],
|
||||
include_type : 'system',
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
#include <regex>
|
||||
|
||||
#include "nix/util/error.hh"
|
||||
#include "nix/util/split.hh"
|
||||
#include "nix/util/url.hh"
|
||||
#include "nix/store/store-reference.hh"
|
||||
#include "nix/util/file-system.hh"
|
||||
#include "nix/util/util.hh"
|
||||
|
||||
#include <boost/url/ipv6_address.hpp>
|
||||
|
||||
namespace nix {
|
||||
|
||||
static bool isNonUriPath(const std::string & spec)
|
||||
|
|
@ -43,6 +44,29 @@ std::string StoreReference::render(bool withParams) const
|
|||
return res;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
struct SchemeAndAuthorityWithPath
|
||||
{
|
||||
std::string_view scheme;
|
||||
std::string_view authority;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
/**
|
||||
* Return the 'scheme' and remove the '://' or ':' separator.
|
||||
*/
|
||||
static std::optional<SchemeAndAuthorityWithPath> splitSchemePrefixTo(std::string_view string)
|
||||
{
|
||||
auto scheme = splitPrefixTo(string, ':');
|
||||
if (!scheme)
|
||||
return std::nullopt;
|
||||
|
||||
splitPrefix(string, "//");
|
||||
return SchemeAndAuthorityWithPath{.scheme = *scheme, .authority = string};
|
||||
}
|
||||
|
||||
StoreReference StoreReference::parse(const std::string & uri, const StoreReference::Params & extraParams)
|
||||
{
|
||||
auto params = extraParams;
|
||||
|
|
@ -92,6 +116,32 @@ StoreReference StoreReference::parse(const std::string & uri, const StoreReferen
|
|||
},
|
||||
.params = std::move(params),
|
||||
};
|
||||
} else if (auto schemeAndAuthority = splitSchemePrefixTo(baseURI)) {
|
||||
/* Back-compatibility shim to accept unbracketed IPv6 addresses after the scheme.
|
||||
* Old versions of nix allowed that. Note that this is ambiguous and does not allow
|
||||
* specifying the port number. For that the address must be bracketed, otherwise it's
|
||||
* greedily assumed to be the part of the host address. */
|
||||
auto authorityString = schemeAndAuthority->authority;
|
||||
auto userinfo = splitPrefixTo(authorityString, '@');
|
||||
auto maybeIpv6 = boost::urls::parse_ipv6_address(authorityString);
|
||||
if (maybeIpv6) {
|
||||
std::string fixedAuthority;
|
||||
if (userinfo) {
|
||||
fixedAuthority += *userinfo;
|
||||
fixedAuthority += '@';
|
||||
}
|
||||
fixedAuthority += '[';
|
||||
fixedAuthority += authorityString;
|
||||
fixedAuthority += ']';
|
||||
return {
|
||||
.variant =
|
||||
Specified{
|
||||
.scheme = std::string(schemeAndAuthority->scheme),
|
||||
.authority = fixedAuthority,
|
||||
},
|
||||
.params = std::move(params),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue