Signed-off-by: Qiumiao Zhang <zhangqiumiao1@huawei.com> (cherry picked from commit dd302052047a8a8a61b163eb57a12055ed6697bf)
91 lines
2.9 KiB
Diff
91 lines
2.9 KiB
Diff
From e814d33900992e034a8c3ddec2c65463c5206090 Mon Sep 17 00:00:00 2001
|
|
From: Michael Brown <mcb30@ipxe.org>
|
|
Date: Thu, 13 Jan 2022 14:53:36 +0000
|
|
Subject: [PATCH] [uri] Allow for relative URIs that include colons within the
|
|
path
|
|
|
|
RFC3986 allows for colons to appear within the path component of a
|
|
relative URI, but iPXE will currently parse such URIs incorrectly by
|
|
interpreting the text before the colon as the URI scheme.
|
|
|
|
Fix by checking for valid characters when identifying the URI scheme.
|
|
Deliberately deviate from the RFC3986 definition of valid characters
|
|
by accepting "_" (which was incorrectly used in the iPXE-specific
|
|
"ib_srp" URI scheme and so must be accepted for compatibility with
|
|
existing deployments), and by omitting the code to check for
|
|
characters that are not used in any URI scheme supported by iPXE.
|
|
|
|
Reported-by: Ignat Korchagin <ignat@cloudflare.com>
|
|
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
Conflict:NA
|
|
Reference:https://github.com/ipxe/ipxe/commit/e814d33900992e034a8c3ddec2c65463c5206090
|
|
---
|
|
src/core/uri.c | 15 ++++++++++-----
|
|
src/tests/uri_test.c | 10 ++++++++++
|
|
2 files changed, 20 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/src/core/uri.c b/src/core/uri.c
|
|
index a0f79e9ec1..b82472ef03 100644
|
|
--- a/src/core/uri.c
|
|
+++ b/src/core/uri.c
|
|
@@ -334,8 +334,15 @@ struct uri * parse_uri ( const char *uri_string ) {
|
|
uri->efragment = tmp;
|
|
}
|
|
|
|
- /* Identify absolute/relative URI */
|
|
- if ( ( tmp = strchr ( raw, ':' ) ) ) {
|
|
+ /* Identify absolute URIs */
|
|
+ epath = raw;
|
|
+ for ( tmp = raw ; ; tmp++ ) {
|
|
+ /* Possible scheme character (for our URI schemes) */
|
|
+ if ( isalpha ( *tmp ) || ( *tmp == '-' ) || ( *tmp == '_' ) )
|
|
+ continue;
|
|
+ /* Invalid scheme character or NUL: is a relative URI */
|
|
+ if ( *tmp != ':' )
|
|
+ break;
|
|
/* Absolute URI: identify hierarchical/opaque */
|
|
uri->scheme = raw;
|
|
*(tmp++) = '\0';
|
|
@@ -347,9 +354,7 @@ struct uri * parse_uri ( const char *uri_string ) {
|
|
uri->opaque = tmp;
|
|
epath = NULL;
|
|
}
|
|
- } else {
|
|
- /* Relative URI */
|
|
- epath = raw;
|
|
+ break;
|
|
}
|
|
|
|
/* If we don't have a path (i.e. we have an absolute URI with
|
|
diff --git a/src/tests/uri_test.c b/src/tests/uri_test.c
|
|
index 929ab36325..338f479cd3 100644
|
|
--- a/src/tests/uri_test.c
|
|
+++ b/src/tests/uri_test.c
|
|
@@ -657,6 +657,15 @@ static struct uri_test uri_file_volume = {
|
|
},
|
|
};
|
|
|
|
+/** Relative URI with colons in path */
|
|
+static struct uri_test uri_colons = {
|
|
+ "/boot/52:54:00:12:34:56/boot.ipxe",
|
|
+ {
|
|
+ .path = "/boot/52:54:00:12:34:56/boot.ipxe",
|
|
+ .epath = "/boot/52:54:00:12:34:56/boot.ipxe",
|
|
+ },
|
|
+};
|
|
+
|
|
/** URI with port number */
|
|
static struct uri_port_test uri_explicit_port = {
|
|
"http://192.168.0.1:8080/boot.php",
|
|
@@ -957,6 +966,7 @@ static void uri_test_exec ( void ) {
|
|
uri_parse_format_dup_ok ( &uri_file_relative );
|
|
uri_parse_format_dup_ok ( &uri_file_absolute );
|
|
uri_parse_format_dup_ok ( &uri_file_volume );
|
|
+ uri_parse_format_dup_ok ( &uri_colons );
|
|
|
|
/** URI port number tests */
|
|
uri_port_ok ( &uri_explicit_port );
|
|
|
|
|