backport some upstream patches
Signed-off-by: Qiumiao Zhang <zhangqiumiao1@huawei.com> (cherry picked from commit dd302052047a8a8a61b163eb57a12055ed6697bf)
This commit is contained in:
parent
3007afe5b1
commit
511d83683d
@ -0,0 +1,90 @@
|
|||||||
|
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 );
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
From 5d22307c4161dde453d50e8dc7bef8b3a2f6c9b3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael Brown <mcb30@ipxe.org>
|
||||||
|
Date: Tue, 15 Feb 2022 14:28:01 +0000
|
||||||
|
Subject: [PATCH] [image] Do not clear current working URI when executing
|
||||||
|
embedded image
|
||||||
|
|
||||||
|
Embedded images do not have an associated URI. This currently causes
|
||||||
|
the current working URI (cwuri) to be cleared when starting an
|
||||||
|
embedded image.
|
||||||
|
|
||||||
|
If the current working URI has been set via a ${next-server} setting
|
||||||
|
from a cached DHCP packet then this will result in unexpected
|
||||||
|
behaviour. An attempt by the embedded script to use a relative URI to
|
||||||
|
download files from the TFTP server will fail with the error:
|
||||||
|
|
||||||
|
Could not start download: Operation not supported (ipxe.org/3c092083)
|
||||||
|
|
||||||
|
Rerunning the "dhcp" command will not fix this error, since the TFTP
|
||||||
|
settings applicator will not see any change to the ${next-server}
|
||||||
|
setting and so will not reset the current working URI.
|
||||||
|
|
||||||
|
Fix by setting the current working URI to the image's URI only if the
|
||||||
|
image actually has an associated URI.
|
||||||
|
|
||||||
|
Debugged-by: Ignat Korchagin <ignat@cloudflare.com>
|
||||||
|
Originally-fixed-by: Ignat Korchagin <ignat@cloudflare.com>
|
||||||
|
Tested-by: Ignat Korchagin <ignat@cloudflare.com>
|
||||||
|
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
||||||
|
|
||||||
|
Conflict:NA
|
||||||
|
Reference:https://github.com/ipxe/ipxe/commit/5d22307c4161dde453d50e8dc7bef8b3a2f6c9b3
|
||||||
|
---
|
||||||
|
src/core/image.c | 7 +++++--
|
||||||
|
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/core/image.c b/src/core/image.c
|
||||||
|
index ce8cf868b0..3e236ca603 100644
|
||||||
|
--- a/src/core/image.c
|
||||||
|
+++ b/src/core/image.c
|
||||||
|
@@ -338,9 +338,12 @@ int image_exec ( struct image *image ) {
|
||||||
|
/* Sanity check */
|
||||||
|
assert ( image->flags & IMAGE_REGISTERED );
|
||||||
|
|
||||||
|
- /* Switch current working directory to be that of the image itself */
|
||||||
|
+ /* Switch current working directory to be that of the image
|
||||||
|
+ * itself, if applicable
|
||||||
|
+ */
|
||||||
|
old_cwuri = uri_get ( cwuri );
|
||||||
|
- churi ( image->uri );
|
||||||
|
+ if ( image->uri )
|
||||||
|
+ churi ( image->uri );
|
||||||
|
|
||||||
|
/* Preserve record of any currently-running image */
|
||||||
|
saved_current_image = current_image;
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
From 04288974f6d81019314cbf9cbd72ab1fae95496f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael Brown <mcb30@ipxe.org>
|
||||||
|
Date: Wed, 16 Feb 2022 12:30:02 +0000
|
||||||
|
Subject: [PATCH] [pci] Ensure that pci_read_config() initialises all fields
|
||||||
|
|
||||||
|
As per the general pattern for initialisation functions in iPXE,
|
||||||
|
pci_init() saves code size by assuming that the caller has already
|
||||||
|
zeroed the underlying storage (e.g. as part of zeroing a larger
|
||||||
|
containing structure). There are several places within the code where
|
||||||
|
pci_init() is deliberately used to initialise a transient struct
|
||||||
|
pci_device without zeroing the entire structure, because the calling
|
||||||
|
code knows that only the PCI bus:dev.fn address is required to be
|
||||||
|
initialised (e.g. when reading from PCI configuration space).
|
||||||
|
|
||||||
|
Ensure that using pci_init() followed by pci_read_config() will fully
|
||||||
|
initialise the struct pci_device even if the caller did not previously
|
||||||
|
zero the underlying storage, since Coverity reports that there are
|
||||||
|
several places in the code that rely upon this.
|
||||||
|
|
||||||
|
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
||||||
|
|
||||||
|
Conflict:NA
|
||||||
|
Reference:https://github.com/ipxe/ipxe/commit/04288974f6d81019314cbf9cbd72ab1fae95496f
|
||||||
|
---
|
||||||
|
src/drivers/bus/pci.c | 5 +++++
|
||||||
|
1 file changed, 5 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/drivers/bus/pci.c b/src/drivers/bus/pci.c
|
||||||
|
index 1b7350c8b8..5891e42ff4 100644
|
||||||
|
--- a/src/drivers/bus/pci.c
|
||||||
|
+++ b/src/drivers/bus/pci.c
|
||||||
|
@@ -121,6 +121,11 @@ static void pci_read_bases ( struct pci_device *pci ) {
|
||||||
|
unsigned long bar;
|
||||||
|
int reg;
|
||||||
|
|
||||||
|
+ /* Clear any existing base addresses */
|
||||||
|
+ pci->ioaddr = 0;
|
||||||
|
+ pci->membase = 0;
|
||||||
|
+
|
||||||
|
+ /* Get first memory and I/O BAR addresses */
|
||||||
|
for ( reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4 ) {
|
||||||
|
bar = pci_bar ( pci, reg );
|
||||||
|
if ( bar & PCI_BASE_ADDRESS_SPACE_IO ) {
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,629 @@
|
|||||||
|
From 1844aacc837bf81cb1959fa65f2e52dcc70a0cae Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael Brown <mcb30@ipxe.org>
|
||||||
|
Date: Thu, 11 Nov 2021 23:31:23 +0000
|
||||||
|
Subject: [PATCH] [uri] Retain original encodings for path, query, and fragment
|
||||||
|
fields
|
||||||
|
|
||||||
|
iPXE decodes any percent-encoded characters during the URI parsing
|
||||||
|
stage, thereby allowing protocol implementations to consume the raw
|
||||||
|
field values directly without further decoding.
|
||||||
|
|
||||||
|
When reconstructing a URI string for use in an HTTP request line, the
|
||||||
|
percent-encoding is currently reapplied in a reversible way: we
|
||||||
|
guarantee that our reconstructed URI string could be decoded to give
|
||||||
|
the same raw field values.
|
||||||
|
|
||||||
|
This technically violates RFC3986, which states that "URIs that differ
|
||||||
|
in the replacement of a reserved character with its corresponding
|
||||||
|
percent-encoded octet are not equivalent". Experiments show that
|
||||||
|
several HTTP server applications will attach meaning to the choice of
|
||||||
|
whether or not a particular character was percent-encoded, even when
|
||||||
|
the percent-encoding is unnecessary from the perspective of parsing
|
||||||
|
the URI into its component fields.
|
||||||
|
|
||||||
|
Fix by storing the originally encoded substrings for the path, query,
|
||||||
|
and fragment fields and using these original encoded versions when
|
||||||
|
reconstructing a URI string. The path field is also stored as a
|
||||||
|
decoded string, for use by protocols such as TFTP that communicate
|
||||||
|
using raw strings rather than URI-encoded strings. All other fields
|
||||||
|
(such as the username and password) continue to be stored only in
|
||||||
|
their decoded versions since nothing ever needs to know the originally
|
||||||
|
encoded versions of these fields.
|
||||||
|
|
||||||
|
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
||||||
|
|
||||||
|
Conflict:NA
|
||||||
|
Reference:https://github.com/ipxe/ipxe/commit/1844aacc837bf81cb1959fa65f2e52dcc70a0cae
|
||||||
|
---
|
||||||
|
src/core/uri.c | 131 +++++++++++++++++++++++++----------------
|
||||||
|
src/include/ipxe/uri.h | 31 +++++++---
|
||||||
|
src/net/tcp/httpcore.c | 4 +-
|
||||||
|
src/tests/uri_test.c | 53 +++++++++++++----
|
||||||
|
src/usr/imgmgmt.c | 4 +-
|
||||||
|
5 files changed, 148 insertions(+), 75 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/core/uri.c b/src/core/uri.c
|
||||||
|
index e9e512ab4a..a0f79e9ec1 100644
|
||||||
|
--- a/src/core/uri.c
|
||||||
|
+++ b/src/core/uri.c
|
||||||
|
@@ -79,12 +79,10 @@ size_t uri_decode ( const char *encoded, void *buf, size_t len ) {
|
||||||
|
/**
|
||||||
|
* Decode URI field in-place
|
||||||
|
*
|
||||||
|
- * @v uri URI
|
||||||
|
- * @v field URI field index
|
||||||
|
+ * @v encoded Encoded field, or NULL
|
||||||
|
*/
|
||||||
|
-static void uri_decode_inplace ( struct uri *uri, unsigned int field ) {
|
||||||
|
- const char *encoded = uri_field ( uri, field );
|
||||||
|
- char *decoded = ( ( char * ) encoded );
|
||||||
|
+static void uri_decode_inplace ( char *encoded ) {
|
||||||
|
+ char *decoded = encoded;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
/* Do nothing if field is not present */
|
||||||
|
@@ -150,7 +148,7 @@ static int uri_character_escaped ( char c, unsigned int field ) {
|
||||||
|
* parser but for any other URI parsers (e.g. HTTP query
|
||||||
|
* string parsers, which care about '=' and '&').
|
||||||
|
*/
|
||||||
|
- static const char *escaped[URI_FIELDS] = {
|
||||||
|
+ static const char *escaped[URI_EPATH] = {
|
||||||
|
/* Scheme or default: escape everything */
|
||||||
|
[URI_SCHEME] = "/#:@?=&",
|
||||||
|
/* Opaque part: escape characters which would affect
|
||||||
|
@@ -172,20 +170,21 @@ static int uri_character_escaped ( char c, unsigned int field ) {
|
||||||
|
* appears within paths.
|
||||||
|
*/
|
||||||
|
[URI_PATH] = "#:@?",
|
||||||
|
- /* Query: escape everything except '/', which
|
||||||
|
- * sometimes appears within queries.
|
||||||
|
- */
|
||||||
|
- [URI_QUERY] = "#:@?",
|
||||||
|
- /* Fragment: escape everything */
|
||||||
|
- [URI_FRAGMENT] = "/#:@?",
|
||||||
|
};
|
||||||
|
|
||||||
|
- return ( /* Always escape non-printing characters and whitespace */
|
||||||
|
- ( ! isprint ( c ) ) || ( c == ' ' ) ||
|
||||||
|
- /* Always escape '%' */
|
||||||
|
- ( c == '%' ) ||
|
||||||
|
- /* Escape field-specific characters */
|
||||||
|
- strchr ( escaped[field], c ) );
|
||||||
|
+ /* Always escape non-printing characters and whitespace */
|
||||||
|
+ if ( ( ! isprint ( c ) ) || ( c == ' ' ) )
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ /* Escape nothing else in already-escaped fields */
|
||||||
|
+ if ( field >= URI_EPATH )
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ /* Escape '%' and any field-specific characters */
|
||||||
|
+ if ( ( c == '%' ) || strchr ( escaped[field], c ) )
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -262,10 +261,12 @@ static void uri_dump ( const struct uri *uri ) {
|
||||||
|
DBGC ( uri, " port \"%s\"", uri->port );
|
||||||
|
if ( uri->path )
|
||||||
|
DBGC ( uri, " path \"%s\"", uri->path );
|
||||||
|
- if ( uri->query )
|
||||||
|
- DBGC ( uri, " query \"%s\"", uri->query );
|
||||||
|
- if ( uri->fragment )
|
||||||
|
- DBGC ( uri, " fragment \"%s\"", uri->fragment );
|
||||||
|
+ if ( uri->epath )
|
||||||
|
+ DBGC ( uri, " epath \"%s\"", uri->epath );
|
||||||
|
+ if ( uri->equery )
|
||||||
|
+ DBGC ( uri, " equery \"%s\"", uri->equery );
|
||||||
|
+ if ( uri->efragment )
|
||||||
|
+ DBGC ( uri, " efragment \"%s\"", uri->efragment );
|
||||||
|
if ( uri->params )
|
||||||
|
DBGC ( uri, " params \"%s\"", uri->params->name );
|
||||||
|
}
|
||||||
|
@@ -298,17 +299,19 @@ struct uri * parse_uri ( const char *uri_string ) {
|
||||||
|
char *raw;
|
||||||
|
char *tmp;
|
||||||
|
char *path;
|
||||||
|
+ char *epath;
|
||||||
|
char *authority;
|
||||||
|
size_t raw_len;
|
||||||
|
unsigned int field;
|
||||||
|
|
||||||
|
- /* Allocate space for URI struct and a copy of the string */
|
||||||
|
+ /* Allocate space for URI struct and two copies of the string */
|
||||||
|
raw_len = ( strlen ( uri_string ) + 1 /* NUL */ );
|
||||||
|
- uri = zalloc ( sizeof ( *uri ) + raw_len );
|
||||||
|
+ uri = zalloc ( sizeof ( *uri ) + ( 2 * raw_len ) );
|
||||||
|
if ( ! uri )
|
||||||
|
return NULL;
|
||||||
|
ref_init ( &uri->refcnt, uri_free );
|
||||||
|
raw = ( ( ( void * ) uri ) + sizeof ( *uri ) );
|
||||||
|
+ path = ( raw + raw_len );
|
||||||
|
|
||||||
|
/* Copy in the raw string */
|
||||||
|
memcpy ( raw, uri_string, raw_len );
|
||||||
|
@@ -328,7 +331,7 @@ struct uri * parse_uri ( const char *uri_string ) {
|
||||||
|
/* Chop off the fragment, if it exists */
|
||||||
|
if ( ( tmp = strchr ( raw, '#' ) ) ) {
|
||||||
|
*(tmp++) = '\0';
|
||||||
|
- uri->fragment = tmp;
|
||||||
|
+ uri->efragment = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Identify absolute/relative URI */
|
||||||
|
@@ -338,47 +341,47 @@ struct uri * parse_uri ( const char *uri_string ) {
|
||||||
|
*(tmp++) = '\0';
|
||||||
|
if ( *tmp == '/' ) {
|
||||||
|
/* Absolute URI with hierarchical part */
|
||||||
|
- path = tmp;
|
||||||
|
+ epath = tmp;
|
||||||
|
} else {
|
||||||
|
/* Absolute URI with opaque part */
|
||||||
|
uri->opaque = tmp;
|
||||||
|
- path = NULL;
|
||||||
|
+ epath = NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Relative URI */
|
||||||
|
- path = raw;
|
||||||
|
+ epath = raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we don't have a path (i.e. we have an absolute URI with
|
||||||
|
* an opaque portion, we're already finished processing
|
||||||
|
*/
|
||||||
|
- if ( ! path )
|
||||||
|
+ if ( ! epath )
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
/* Chop off the query, if it exists */
|
||||||
|
- if ( ( tmp = strchr ( path, '?' ) ) ) {
|
||||||
|
+ if ( ( tmp = strchr ( epath, '?' ) ) ) {
|
||||||
|
*(tmp++) = '\0';
|
||||||
|
- uri->query = tmp;
|
||||||
|
+ uri->equery = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we have no path remaining, then we're already finished
|
||||||
|
* processing.
|
||||||
|
*/
|
||||||
|
- if ( ! path[0] )
|
||||||
|
+ if ( ! epath[0] )
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
/* Identify net/absolute/relative path */
|
||||||
|
- if ( uri->scheme && ( strncmp ( path, "//", 2 ) == 0 ) ) {
|
||||||
|
+ if ( uri->scheme && ( strncmp ( epath, "//", 2 ) == 0 ) ) {
|
||||||
|
/* Net path. If this is terminated by the first '/'
|
||||||
|
* of an absolute path, then we have no space for a
|
||||||
|
* terminator after the authority field, so shuffle
|
||||||
|
* the authority down by one byte, overwriting one of
|
||||||
|
* the two slashes.
|
||||||
|
*/
|
||||||
|
- authority = ( path + 2 );
|
||||||
|
+ authority = ( epath + 2 );
|
||||||
|
if ( ( tmp = strchr ( authority, '/' ) ) ) {
|
||||||
|
/* Shuffle down */
|
||||||
|
- uri->path = tmp;
|
||||||
|
+ uri->epath = tmp;
|
||||||
|
memmove ( ( authority - 1 ), authority,
|
||||||
|
( tmp - authority ) );
|
||||||
|
authority--;
|
||||||
|
@@ -386,10 +389,16 @@ struct uri * parse_uri ( const char *uri_string ) {
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Absolute/relative path */
|
||||||
|
- uri->path = path;
|
||||||
|
+ uri->epath = epath;
|
||||||
|
authority = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /* Create copy of path for decoding */
|
||||||
|
+ if ( uri->epath ) {
|
||||||
|
+ strcpy ( path, uri->epath );
|
||||||
|
+ uri->path = path;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* If we don't have an authority (i.e. we have a non-net
|
||||||
|
* path), we're already finished processing
|
||||||
|
*/
|
||||||
|
@@ -421,8 +430,8 @@ struct uri * parse_uri ( const char *uri_string ) {
|
||||||
|
|
||||||
|
done:
|
||||||
|
/* Decode fields in-place */
|
||||||
|
- for ( field = 0 ; field < URI_FIELDS ; field++ )
|
||||||
|
- uri_decode_inplace ( uri, field );
|
||||||
|
+ for ( field = 0 ; field < URI_EPATH ; field++ )
|
||||||
|
+ uri_decode_inplace ( ( char * ) uri_field ( uri, field ) );
|
||||||
|
|
||||||
|
DBGC ( uri, "URI parsed \"%s\" to", uri_string );
|
||||||
|
uri_dump ( uri );
|
||||||
|
@@ -458,8 +467,8 @@ size_t format_uri ( const struct uri *uri, char *buf, size_t len ) {
|
||||||
|
static const char prefixes[URI_FIELDS] = {
|
||||||
|
[URI_PASSWORD] = ':',
|
||||||
|
[URI_PORT] = ':',
|
||||||
|
- [URI_QUERY] = '?',
|
||||||
|
- [URI_FRAGMENT] = '#',
|
||||||
|
+ [URI_EQUERY] = '?',
|
||||||
|
+ [URI_EFRAGMENT] = '#',
|
||||||
|
};
|
||||||
|
char prefix;
|
||||||
|
size_t used = 0;
|
||||||
|
@@ -480,6 +489,10 @@ size_t format_uri ( const struct uri *uri, char *buf, size_t len ) {
|
||||||
|
if ( ! uri_field ( uri, field ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
+ /* Skip path field if encoded path is present */
|
||||||
|
+ if ( ( field == URI_PATH ) && uri->epath )
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
/* Prefix this field, if applicable */
|
||||||
|
prefix = prefixes[field];
|
||||||
|
if ( ( field == URI_HOST ) && ( uri->user != NULL ) )
|
||||||
|
@@ -676,6 +689,7 @@ char * resolve_path ( const char *base_path,
|
||||||
|
struct uri * resolve_uri ( const struct uri *base_uri,
|
||||||
|
struct uri *relative_uri ) {
|
||||||
|
struct uri tmp_uri;
|
||||||
|
+ char *tmp_epath = NULL;
|
||||||
|
char *tmp_path = NULL;
|
||||||
|
struct uri *new_uri;
|
||||||
|
|
||||||
|
@@ -685,20 +699,27 @@ struct uri * resolve_uri ( const struct uri *base_uri,
|
||||||
|
|
||||||
|
/* Mangle URI */
|
||||||
|
memcpy ( &tmp_uri, base_uri, sizeof ( tmp_uri ) );
|
||||||
|
- if ( relative_uri->path ) {
|
||||||
|
- tmp_path = resolve_path ( ( base_uri->path ?
|
||||||
|
- base_uri->path : "/" ),
|
||||||
|
- relative_uri->path );
|
||||||
|
+ if ( relative_uri->epath ) {
|
||||||
|
+ tmp_epath = resolve_path ( ( base_uri->epath ?
|
||||||
|
+ base_uri->epath : "/" ),
|
||||||
|
+ relative_uri->epath );
|
||||||
|
+ if ( ! tmp_epath )
|
||||||
|
+ goto err_epath;
|
||||||
|
+ tmp_path = strdup ( tmp_epath );
|
||||||
|
+ if ( ! tmp_path )
|
||||||
|
+ goto err_path;
|
||||||
|
+ uri_decode_inplace ( tmp_path );
|
||||||
|
+ tmp_uri.epath = tmp_epath;
|
||||||
|
tmp_uri.path = tmp_path;
|
||||||
|
- tmp_uri.query = relative_uri->query;
|
||||||
|
- tmp_uri.fragment = relative_uri->fragment;
|
||||||
|
+ tmp_uri.equery = relative_uri->equery;
|
||||||
|
+ tmp_uri.efragment = relative_uri->efragment;
|
||||||
|
tmp_uri.params = relative_uri->params;
|
||||||
|
- } else if ( relative_uri->query ) {
|
||||||
|
- tmp_uri.query = relative_uri->query;
|
||||||
|
- tmp_uri.fragment = relative_uri->fragment;
|
||||||
|
+ } else if ( relative_uri->equery ) {
|
||||||
|
+ tmp_uri.equery = relative_uri->equery;
|
||||||
|
+ tmp_uri.efragment = relative_uri->efragment;
|
||||||
|
tmp_uri.params = relative_uri->params;
|
||||||
|
- } else if ( relative_uri->fragment ) {
|
||||||
|
- tmp_uri.fragment = relative_uri->fragment;
|
||||||
|
+ } else if ( relative_uri->efragment ) {
|
||||||
|
+ tmp_uri.efragment = relative_uri->efragment;
|
||||||
|
tmp_uri.params = relative_uri->params;
|
||||||
|
} else if ( relative_uri->params ) {
|
||||||
|
tmp_uri.params = relative_uri->params;
|
||||||
|
@@ -707,7 +728,14 @@ struct uri * resolve_uri ( const struct uri *base_uri,
|
||||||
|
/* Create demangled URI */
|
||||||
|
new_uri = uri_dup ( &tmp_uri );
|
||||||
|
free ( tmp_path );
|
||||||
|
+ free ( tmp_epath );
|
||||||
|
return new_uri;
|
||||||
|
+
|
||||||
|
+ free ( tmp_path );
|
||||||
|
+ err_path:
|
||||||
|
+ free ( tmp_epath );
|
||||||
|
+ err_epath:
|
||||||
|
+ return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -746,6 +774,7 @@ static struct uri * tftp_uri ( struct sockaddr *sa_server,
|
||||||
|
if ( asprintf ( &path, "/%s", filename ) < 0 )
|
||||||
|
goto err_path;
|
||||||
|
tmp.path = path;
|
||||||
|
+ tmp.epath = path;
|
||||||
|
|
||||||
|
/* Demangle URI */
|
||||||
|
uri = uri_dup ( &tmp );
|
||||||
|
diff --git a/src/include/ipxe/uri.h b/src/include/ipxe/uri.h
|
||||||
|
index 3879a0e730..e5b7c8616b 100644
|
||||||
|
--- a/src/include/ipxe/uri.h
|
||||||
|
+++ b/src/include/ipxe/uri.h
|
||||||
|
@@ -46,6 +46,20 @@ struct parameters;
|
||||||
|
* scheme = "ftp", user = "joe", password = "secret",
|
||||||
|
* host = "insecure.org", port = "8081", path = "/hidden/path/to",
|
||||||
|
* query = "what=is", fragment = "this"
|
||||||
|
+ *
|
||||||
|
+ * The URI syntax includes a percent-encoding mechanism that can be
|
||||||
|
+ * used to represent characters that would otherwise not be possible,
|
||||||
|
+ * such as a '/' character within the password field. These encodings
|
||||||
|
+ * are decoded during the URI parsing stage, thereby allowing protocol
|
||||||
|
+ * implementations to consume the raw field values directly without
|
||||||
|
+ * further decoding.
|
||||||
|
+ *
|
||||||
|
+ * Some protocols (such as HTTP) communicate using URI-encoded values.
|
||||||
|
+ * For these protocols, the original encoded substring must be
|
||||||
|
+ * retained verbatim since the choice of whether or not to encode a
|
||||||
|
+ * particular character may have significance to the receiving
|
||||||
|
+ * application. We therefore retain the originally-encoded substrings
|
||||||
|
+ * for the path, query, and fragment fields.
|
||||||
|
*/
|
||||||
|
struct uri {
|
||||||
|
/** Reference count */
|
||||||
|
@@ -62,12 +76,14 @@ struct uri {
|
||||||
|
const char *host;
|
||||||
|
/** Port number */
|
||||||
|
const char *port;
|
||||||
|
- /** Path */
|
||||||
|
+ /** Path (after URI decoding) */
|
||||||
|
const char *path;
|
||||||
|
- /** Query */
|
||||||
|
- const char *query;
|
||||||
|
- /** Fragment */
|
||||||
|
- const char *fragment;
|
||||||
|
+ /** Path (with original URI encoding) */
|
||||||
|
+ const char *epath;
|
||||||
|
+ /** Query (with original URI encoding) */
|
||||||
|
+ const char *equery;
|
||||||
|
+ /** Fragment (with original URI encoding) */
|
||||||
|
+ const char *efragment;
|
||||||
|
/** Form parameters */
|
||||||
|
struct parameters *params;
|
||||||
|
} __attribute__ (( packed ));
|
||||||
|
@@ -100,8 +116,9 @@ enum uri_fields {
|
||||||
|
URI_HOST = URI_FIELD ( host ),
|
||||||
|
URI_PORT = URI_FIELD ( port ),
|
||||||
|
URI_PATH = URI_FIELD ( path ),
|
||||||
|
- URI_QUERY = URI_FIELD ( query ),
|
||||||
|
- URI_FRAGMENT = URI_FIELD ( fragment ),
|
||||||
|
+ URI_EPATH = URI_FIELD ( epath ),
|
||||||
|
+ URI_EQUERY = URI_FIELD ( equery ),
|
||||||
|
+ URI_EFRAGMENT = URI_FIELD ( efragment ),
|
||||||
|
URI_FIELDS
|
||||||
|
};
|
||||||
|
|
||||||
|
diff --git a/src/net/tcp/httpcore.c b/src/net/tcp/httpcore.c
|
||||||
|
index 01bb496b21..fd94b5f083 100644
|
||||||
|
--- a/src/net/tcp/httpcore.c
|
||||||
|
+++ b/src/net/tcp/httpcore.c
|
||||||
|
@@ -614,8 +614,8 @@ int http_open ( struct interface *xfer, struct http_method *method,
|
||||||
|
|
||||||
|
/* Calculate request URI length */
|
||||||
|
memset ( &request_uri, 0, sizeof ( request_uri ) );
|
||||||
|
- request_uri.path = ( uri->path ? uri->path : "/" );
|
||||||
|
- request_uri.query = uri->query;
|
||||||
|
+ request_uri.epath = ( uri->epath ? uri->epath : "/" );
|
||||||
|
+ request_uri.equery = uri->equery;
|
||||||
|
request_uri_len =
|
||||||
|
( format_uri ( &request_uri, NULL, 0 ) + 1 /* NUL */);
|
||||||
|
|
||||||
|
diff --git a/src/tests/uri_test.c b/src/tests/uri_test.c
|
||||||
|
index 92c2f90371..929ab36325 100644
|
||||||
|
--- a/src/tests/uri_test.c
|
||||||
|
+++ b/src/tests/uri_test.c
|
||||||
|
@@ -149,8 +149,10 @@ static void uri_okx ( struct uri *uri, struct uri *expected, const char *file,
|
||||||
|
okx ( uristrcmp ( uri->host, expected->host ) == 0, file, line );
|
||||||
|
okx ( uristrcmp ( uri->port, expected->port ) == 0, file, line );
|
||||||
|
okx ( uristrcmp ( uri->path, expected->path ) == 0, file, line );
|
||||||
|
- okx ( uristrcmp ( uri->query, expected->query ) == 0, file, line );
|
||||||
|
- okx ( uristrcmp ( uri->fragment, expected->fragment ) == 0, file, line);
|
||||||
|
+ okx ( uristrcmp ( uri->epath, expected->epath ) == 0, file, line );
|
||||||
|
+ okx ( uristrcmp ( uri->equery, expected->equery ) == 0, file, line );
|
||||||
|
+ okx ( uristrcmp ( uri->efragment, expected->efragment ) == 0,
|
||||||
|
+ file, line);
|
||||||
|
okx ( uri->params == expected->params, file, line );
|
||||||
|
}
|
||||||
|
#define uri_ok( uri, expected ) uri_okx ( uri, expected, __FILE__, __LINE__ )
|
||||||
|
@@ -490,25 +492,33 @@ static struct uri_test uri_empty = {
|
||||||
|
/** Basic HTTP URI */
|
||||||
|
static struct uri_test uri_boot_ipxe_org = {
|
||||||
|
"http://boot.ipxe.org/demo/boot.php",
|
||||||
|
- { .scheme = "http", .host = "boot.ipxe.org", .path = "/demo/boot.php" }
|
||||||
|
+ { .scheme = "http", .host = "boot.ipxe.org",
|
||||||
|
+ .path = "/demo/boot.php", .epath = "/demo/boot.php" },
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Basic opaque URI */
|
||||||
|
static struct uri_test uri_mailto = {
|
||||||
|
"mailto:ipxe-devel@lists.ipxe.org",
|
||||||
|
- { .scheme = "mailto", .opaque = "ipxe-devel@lists.ipxe.org" }
|
||||||
|
+ { .scheme = "mailto", .opaque = "ipxe-devel@lists.ipxe.org" },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/** Basic host-only URI */
|
||||||
|
+static struct uri_test uri_host = {
|
||||||
|
+ "http://boot.ipxe.org",
|
||||||
|
+ { .scheme = "http", .host = "boot.ipxe.org" },
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Basic path-only URI */
|
||||||
|
static struct uri_test uri_path = {
|
||||||
|
"/var/lib/tftpboot/pxelinux.0",
|
||||||
|
- { .path = "/var/lib/tftpboot/pxelinux.0" },
|
||||||
|
+ { .path = "/var/lib/tftpboot/pxelinux.0",
|
||||||
|
+ .epath ="/var/lib/tftpboot/pxelinux.0" },
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Path-only URI with escaped characters */
|
||||||
|
static struct uri_test uri_path_escaped = {
|
||||||
|
"/hello%20world%3F",
|
||||||
|
- { .path = "/hello world?" },
|
||||||
|
+ { .path = "/hello world?", .epath = "/hello%20world%3F" },
|
||||||
|
};
|
||||||
|
|
||||||
|
/** HTTP URI with all the trimmings */
|
||||||
|
@@ -521,8 +531,9 @@ static struct uri_test uri_http_all = {
|
||||||
|
.host = "example.com",
|
||||||
|
.port = "3001",
|
||||||
|
.path = "/~foo/cgi-bin/foo.pl",
|
||||||
|
- .query = "a=b&c=d",
|
||||||
|
- .fragment = "bit",
|
||||||
|
+ .epath = "/~foo/cgi-bin/foo.pl",
|
||||||
|
+ .equery = "a=b&c=d",
|
||||||
|
+ .efragment = "bit",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -533,8 +544,9 @@ static struct uri_test uri_http_escaped = {
|
||||||
|
.scheme = "https",
|
||||||
|
.host = "test.ipxe.org",
|
||||||
|
.path = "/wtf?\n",
|
||||||
|
- .query = "kind#of/uri is",
|
||||||
|
- .fragment = "this?",
|
||||||
|
+ .epath = "/wtf%3F%0A",
|
||||||
|
+ .equery = "kind%23of/uri%20is",
|
||||||
|
+ .efragment = "this%3F",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -550,8 +562,9 @@ static struct uri_test uri_http_escaped_improper = {
|
||||||
|
.scheme = "https",
|
||||||
|
.host = "test.ipxe.org",
|
||||||
|
.path = "/wtf?\n",
|
||||||
|
- .query = "kind#of/uri is",
|
||||||
|
- .fragment = "this?",
|
||||||
|
+ .epath = "/wt%66%3f\n",
|
||||||
|
+ .equery = "kind%23of/uri is",
|
||||||
|
+ .efragment = "this?",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -562,6 +575,7 @@ static struct uri_test uri_ipv6 = {
|
||||||
|
.scheme = "http",
|
||||||
|
.host = "[2001:ba8:0:1d4::6950:5845]",
|
||||||
|
.path = "/",
|
||||||
|
+ .epath = "/",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -573,6 +587,7 @@ static struct uri_test uri_ipv6_port = {
|
||||||
|
.host = "[2001:ba8:0:1d4::6950:5845]",
|
||||||
|
.port = "8001",
|
||||||
|
.path = "/boot",
|
||||||
|
+ .epath = "/boot",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -583,6 +598,7 @@ static struct uri_test uri_ipv6_local = {
|
||||||
|
.scheme = "http",
|
||||||
|
.host = "[fe80::69ff:fe50:5845%net0]",
|
||||||
|
.path = "/ipxe",
|
||||||
|
+ .epath = "/ipxe",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -598,6 +614,7 @@ static struct uri_test uri_ipv6_local_non_conforming = {
|
||||||
|
.scheme = "http",
|
||||||
|
.host = "[fe80::69ff:fe50:5845%net0]",
|
||||||
|
.path = "/ipxe",
|
||||||
|
+ .epath = "/ipxe",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -625,6 +642,7 @@ static struct uri_test uri_file_absolute = {
|
||||||
|
{
|
||||||
|
.scheme = "file",
|
||||||
|
.path = "/boot/script.ipxe",
|
||||||
|
+ .epath = "/boot/script.ipxe",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -635,6 +653,7 @@ static struct uri_test uri_file_volume = {
|
||||||
|
.scheme = "file",
|
||||||
|
.host = "hpilo",
|
||||||
|
.path = "/boot/script.ipxe",
|
||||||
|
+ .epath = "/boot/script.ipxe",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -736,6 +755,7 @@ static struct uri_pxe_test uri_pxe_absolute = {
|
||||||
|
.scheme = "http",
|
||||||
|
.host = "not.a.tftp",
|
||||||
|
.path = "/uri",
|
||||||
|
+ .epath = "/uri",
|
||||||
|
},
|
||||||
|
"http://not.a.tftp/uri",
|
||||||
|
};
|
||||||
|
@@ -754,6 +774,7 @@ static struct uri_pxe_test uri_pxe_absolute_path = {
|
||||||
|
.scheme = "tftp",
|
||||||
|
.host = "192.168.0.2",
|
||||||
|
.path = "//absolute/path",
|
||||||
|
+ .epath = "//absolute/path",
|
||||||
|
},
|
||||||
|
"tftp://192.168.0.2//absolute/path",
|
||||||
|
};
|
||||||
|
@@ -772,6 +793,7 @@ static struct uri_pxe_test uri_pxe_relative_path = {
|
||||||
|
.scheme = "tftp",
|
||||||
|
.host = "192.168.0.3",
|
||||||
|
.path = "/relative/path",
|
||||||
|
+ .epath = "/relative/path",
|
||||||
|
},
|
||||||
|
"tftp://192.168.0.3/relative/path",
|
||||||
|
};
|
||||||
|
@@ -790,8 +812,9 @@ static struct uri_pxe_test uri_pxe_icky = {
|
||||||
|
.scheme = "tftp",
|
||||||
|
.host = "10.0.0.6",
|
||||||
|
.path = "/C:\\tftpboot\\icky#path",
|
||||||
|
+ .epath = "/C:\\tftpboot\\icky#path",
|
||||||
|
},
|
||||||
|
- "tftp://10.0.0.6/C%3A\\tftpboot\\icky%23path",
|
||||||
|
+ "tftp://10.0.0.6/C:\\tftpboot\\icky#path",
|
||||||
|
};
|
||||||
|
|
||||||
|
/** PXE URI with custom port */
|
||||||
|
@@ -810,6 +833,7 @@ static struct uri_pxe_test uri_pxe_port = {
|
||||||
|
.host = "192.168.0.1",
|
||||||
|
.port = "4069",
|
||||||
|
.path = "//another/path",
|
||||||
|
+ .epath = "//another/path",
|
||||||
|
},
|
||||||
|
"tftp://192.168.0.1:4069//another/path",
|
||||||
|
};
|
||||||
|
@@ -873,6 +897,7 @@ static struct uri_params_test uri_params = {
|
||||||
|
.scheme = "http",
|
||||||
|
.host = "boot.ipxe.org",
|
||||||
|
.path = "/demo/boot.php",
|
||||||
|
+ .epath = "/demo/boot.php",
|
||||||
|
},
|
||||||
|
NULL,
|
||||||
|
uri_params_list,
|
||||||
|
@@ -902,6 +927,7 @@ static struct uri_params_test uri_named_params = {
|
||||||
|
.host = "192.168.100.4",
|
||||||
|
.port = "3001",
|
||||||
|
.path = "/register",
|
||||||
|
+ .epath = "/register",
|
||||||
|
},
|
||||||
|
"foo",
|
||||||
|
uri_named_params_list,
|
||||||
|
@@ -917,6 +943,7 @@ static void uri_test_exec ( void ) {
|
||||||
|
uri_parse_format_dup_ok ( &uri_empty );
|
||||||
|
uri_parse_format_dup_ok ( &uri_boot_ipxe_org );
|
||||||
|
uri_parse_format_dup_ok ( &uri_mailto );
|
||||||
|
+ uri_parse_format_dup_ok ( &uri_host );
|
||||||
|
uri_parse_format_dup_ok ( &uri_path );
|
||||||
|
uri_parse_format_dup_ok ( &uri_path_escaped );
|
||||||
|
uri_parse_format_dup_ok ( &uri_http_all );
|
||||||
|
diff --git a/src/usr/imgmgmt.c b/src/usr/imgmgmt.c
|
||||||
|
index f8d149153a..b7fc8293d4 100644
|
||||||
|
--- a/src/usr/imgmgmt.c
|
||||||
|
+++ b/src/usr/imgmgmt.c
|
||||||
|
@@ -58,8 +58,8 @@ int imgdownload ( struct uri *uri, unsigned long timeout,
|
||||||
|
memcpy ( &uri_redacted, uri, sizeof ( uri_redacted ) );
|
||||||
|
uri_redacted.user = NULL;
|
||||||
|
uri_redacted.password = NULL;
|
||||||
|
- uri_redacted.query = NULL;
|
||||||
|
- uri_redacted.fragment = NULL;
|
||||||
|
+ uri_redacted.equery = NULL;
|
||||||
|
+ uri_redacted.efragment = NULL;
|
||||||
|
uri_string_redacted = format_uri_alloc ( &uri_redacted );
|
||||||
|
if ( ! uri_string_redacted ) {
|
||||||
|
rc = -ENOMEM;
|
||||||
|
|
||||||
|
|
||||||
17
ipxe.spec
17
ipxe.spec
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
Name: ipxe
|
Name: ipxe
|
||||||
Version: 1.21.1
|
Version: 1.21.1
|
||||||
Release: 3
|
Release: 4
|
||||||
Summary: A network boot loader
|
Summary: A network boot loader
|
||||||
Epoch: 1
|
Epoch: 1
|
||||||
License: GPLv2 with additional permissions and BSD
|
License: GPLv2 with additional permissions and BSD
|
||||||
@ -16,6 +16,10 @@ Patch0001: 0001-build-customize-configuration.patch
|
|||||||
Patch0002: 0002-Use-spec-compliant-timeouts.patch
|
Patch0002: 0002-Use-spec-compliant-timeouts.patch
|
||||||
|
|
||||||
Patch6000: backport-avoid-infinite-loop-on-allocation-failure-in.patch
|
Patch6000: backport-avoid-infinite-loop-on-allocation-failure-in.patch
|
||||||
|
Patch6001: backport-ensure-that-pci_read_config-initialises-all-fields.patch
|
||||||
|
Patch6002: backport-do-not-clear-current-working-url-when-executing-embedded-image.patch
|
||||||
|
Patch6003: backport-retain-original-encodings-for-path-query-and-fragment-fields.patch
|
||||||
|
Patch6004: backport-allow-for-relative-uris-that-include-colons-within-the-path.patch
|
||||||
|
|
||||||
%ifarch %{buildarches}
|
%ifarch %{buildarches}
|
||||||
BuildRequires: perl-interpreter perl-Getopt-Long syslinux mtools genisoimage edk2-devel
|
BuildRequires: perl-interpreter perl-Getopt-Long syslinux mtools genisoimage edk2-devel
|
||||||
@ -187,6 +191,15 @@ cd ~/rpmbuild/BUILD/%{name}-%{version}/src/bin-i386-linux/
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Wed Nov 23 2022 zhangqiumiao <zhangqiumiao1@huawei.com> - 1:1.21.1-4
|
||||||
|
- Type:bugfix
|
||||||
|
- CVE:NA
|
||||||
|
- SUG:NA
|
||||||
|
- DESC:[pci] Ensure that pci_read_config() initialises all fields
|
||||||
|
[image] Do not clear current working URI when executing embedded image
|
||||||
|
[uri] Retain original encodings for path, query, and fragment fields
|
||||||
|
[uri] Allow for relative URIs that include colons within the path
|
||||||
|
|
||||||
* Sat Mar 26 2022 wangkerong <wangkerong@h-partners.com> - 1.21.1-3
|
* Sat Mar 26 2022 wangkerong <wangkerong@h-partners.com> - 1.21.1-3
|
||||||
- enable test
|
- enable test
|
||||||
|
|
||||||
@ -208,7 +221,7 @@ cd ~/rpmbuild/BUILD/%{name}-%{version}/src/bin-i386-linux/
|
|||||||
- SUG:NA
|
- SUG:NA
|
||||||
- DESC: add epoch for roms-qemu when required by roms
|
- DESC: add epoch for roms-qemu when required by roms
|
||||||
|
|
||||||
* Tue Jun 22 2020 zhujunhao <zhujunhao8@huawei.com> - 1.20.1-1
|
* Tue Jun 23 2020 zhujunhao <zhujunhao8@huawei.com> - 1.20.1-1
|
||||||
- update to 1.20.1
|
- update to 1.20.1
|
||||||
|
|
||||||
* Mon Jan 13 2020 openEuler Buildteam <buildteam@openeuler.org> - 20190125-5
|
* Mon Jan 13 2020 openEuler Buildteam <buildteam@openeuler.org> - 20190125-5
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user