diff --git a/0001-Introduce-a-wrapper-around-xmlParseURI.patch b/0001-Introduce-a-wrapper-around-xmlParseURI.patch new file mode 100644 index 0000000..63fb2b0 --- /dev/null +++ b/0001-Introduce-a-wrapper-around-xmlParseURI.patch @@ -0,0 +1,451 @@ +From 66dbffd38377abeb64144990421e52293613840a Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Thu, 15 Feb 2018 15:55:35 +0000 +Subject: [PATCH 1/3] Introduce a wrapper around xmlParseURI. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We only use xmlParseURI to parse our own "homebrew" URIs, for example +the ones used by guestfish --add or virt-v2v. Unfortunately +xmlParseURI cannot handle URIs with spaces or other non-RFC-compliant +characters so simple commands like these fail: + + $ guestfish -a 'ssh://example.com/virtual machine.img' + guestfish: --add: could not parse URI 'ssh://example.com/virtual machine.img' + + $ guestfish -a 'ssh://example.com/バーチャルマシン.img' + guestfish: --add: could not parse URI 'ssh://example.com/バーチャルマシン.img' + +This is a usability problem. However since these are not expected to +be generic RFC-compliant URIs we can perform the required +percent-escaping ourselves instead of demanding that the user does +this. + +Note that the wrapper function should not be used on real URLs or +libvirt URLs. +--- + common/mlxml/Makefile.am | 1 + + common/mlxml/xml-c.c | 45 +++++++++-- + common/mlxml/xml.ml | 1 + + common/mlxml/xml.mli | 4 + + common/options/uri.c | 5 +- + common/utils/Makefile.am | 2 + + common/utils/libxml2-utils.c | 178 +++++++++++++++++++++++++++++++++++++++++++ + common/utils/libxml2-utils.h | 27 +++++++ + v2v/input_vmx.ml | 8 +- + v2v/virt-v2v.pod | 5 +- + 10 files changed, 258 insertions(+), 18 deletions(-) + create mode 100644 common/utils/libxml2-utils.c + create mode 100644 common/utils/libxml2-utils.h + +diff --git a/common/mlxml/Makefile.am b/common/mlxml/Makefile.am +index 083c7a64b..739b58ae4 100644 +--- a/common/mlxml/Makefile.am ++++ b/common/mlxml/Makefile.am +@@ -53,6 +53,7 @@ libmlxml_a_CPPFLAGS = \ + -I. \ + -I$(top_builddir) \ + -I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \ ++ -I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \ + -I$(shell $(OCAMLC) -where) + libmlxml_a_CFLAGS = \ + $(WARN_CFLAGS) $(WERROR_CFLAGS) \ +diff --git a/common/mlxml/xml-c.c b/common/mlxml/xml-c.c +index 3ebecb25e..6dcdb5ccb 100644 +--- a/common/mlxml/xml-c.c ++++ b/common/mlxml/xml-c.c +@@ -27,17 +27,21 @@ + #include + #include + #include ++#include + + #include + #include + #include + #include + #include ++#include + + #include + #include + #include + ++#include "libxml2-utils.h" ++ + #pragma GCC diagnostic ignored "-Wmissing-prototypes" + + /* xmlDocPtr type */ +@@ -426,16 +430,11 @@ mllib_xml_doc_get_root_element (value docv) + } + } + +-value +-mllib_xml_parse_uri (value strv) ++static value ++Val_uri (xmlURIPtr uri) + { +- CAMLparam1 (strv); ++ CAMLparam0 (); + CAMLlocal3 (rv, sv, ov); +- xmlURIPtr uri; +- +- uri = xmlParseURI (String_val (strv)); +- if (uri == NULL) +- caml_invalid_argument ("parse_uri: unable to parse URI"); + + rv = caml_alloc_tuple (9); + +@@ -514,7 +513,37 @@ mllib_xml_parse_uri (value strv) + else ov = Val_int (0); + Store_field (rv, 8, ov); + ++ CAMLreturn (rv); ++} ++ ++value ++mllib_xml_parse_uri (value strv) ++{ ++ CAMLparam1 (strv); ++ CAMLlocal1 (rv); ++ xmlURIPtr uri; ++ ++ uri = xmlParseURI (String_val (strv)); ++ if (uri == NULL) ++ caml_invalid_argument ("parse_uri: unable to parse URI"); ++ ++ rv = Val_uri (uri); + xmlFreeURI (uri); ++ CAMLreturn (rv); ++} + ++value ++mllib_xml_parse_nonstandard_uri (value strv) ++{ ++ CAMLparam1 (strv); ++ CAMLlocal1 (rv); ++ xmlURIPtr uri; ++ ++ uri = guestfs_int_parse_nonstandard_uri (String_val (strv)); ++ if (uri == NULL) ++ unix_error (errno, (char *) "Xml.parse_uri", strv); ++ ++ rv = Val_uri (uri); ++ xmlFreeURI (uri); + CAMLreturn (rv); + } +diff --git a/common/mlxml/xml.ml b/common/mlxml/xml.ml +index 5b5c09c00..faeea35ee 100644 +--- a/common/mlxml/xml.ml ++++ b/common/mlxml/xml.ml +@@ -162,3 +162,4 @@ type uri = { + } + + external parse_uri : string -> uri = "mllib_xml_parse_uri" ++external parse_nonstandard_uri : string -> uri = "mllib_xml_parse_nonstandard_uri" +diff --git a/common/mlxml/xml.mli b/common/mlxml/xml.mli +index f561bd673..73c2fdd4b 100644 +--- a/common/mlxml/xml.mli ++++ b/common/mlxml/xml.mli +@@ -115,3 +115,7 @@ val parse_uri : string -> uri + Note this is different from the {!URI} module which is specialized + for parsing the [-a] parameter on the command line. This function + exposes the full [xmlParseURI] interface. *) ++ ++val parse_nonstandard_uri : string -> uri ++(** Similar to {!parse_uri} but only for use with our non-standard ++ URIs. See [guestfs_int_parse_nonstandard_uri] in [common/utils]. *) +diff --git a/common/options/uri.c b/common/options/uri.c +index ac36bccb2..88a5f0560 100644 +--- a/common/options/uri.c ++++ b/common/options/uri.c +@@ -38,6 +38,7 @@ + + #include "guestfs.h" + #include "guestfs-utils.h" ++#include "libxml2-utils.h" + #include "uri.h" + + static int is_uri (const char *arg); +@@ -114,9 +115,9 @@ parse (const char *arg, char **path_ret, char **protocol_ret, + CLEANUP_FREE char *socket = NULL; + char *path; + +- uri = xmlParseURI (arg); ++ uri = guestfs_int_parse_nonstandard_uri (arg); + if (!uri) { +- fprintf (stderr, _("%s: --add: could not parse URI ‘%s’\n"), ++ fprintf (stderr, _("%s: --add: could not parse URI ‘%s’: %m\n"), + getprogname (), arg); + return -1; + } +diff --git a/common/utils/Makefile.am b/common/utils/Makefile.am +index 143e2c141..1fa98f992 100644 +--- a/common/utils/Makefile.am ++++ b/common/utils/Makefile.am +@@ -26,6 +26,8 @@ libutils_la_SOURCES = \ + gnulib-cleanups.c \ + guestfs-utils.h \ + libxml2-cleanups.c \ ++ libxml2-utils.c \ ++ libxml2-utils.h \ + utils.c + libutils_la_CPPFLAGS = \ + -DGUESTFS_WARN_DEPRECATED=1 \ +diff --git a/common/utils/libxml2-utils.c b/common/utils/libxml2-utils.c +new file mode 100644 +index 000000000..8a05aa5b1 +--- /dev/null ++++ b/common/utils/libxml2-utils.c +@@ -0,0 +1,178 @@ ++/* libguestfs ++ * Copyright (C) 2017 Red Hat Inc. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/** ++ * Utility functions using libxml2. ++ * ++ * These functions these I call internal library functions ++ * such as C, C or C, or any C. ++ */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "c-ctype.h" ++ ++/* NB: MUST NOT include "guestfs-internal.h". */ ++#include "guestfs.h" ++#include "guestfs-utils.h" ++#include "libxml2-utils.h" ++ ++static char *local_string_to_utf8 (/* const */ char *input); ++ ++/** ++ * This is a wrapper around C. That function cannot ++ * handle spaces and some non-ASCII characters found in URIs. This ++ * wrapper URI-encodes those before calling C and returns ++ * the URI structure. ++ * ++ * This function should B be called for the URIs that libguestfs ++ * has invented, for things like guestfish I<--add> and virt-v2v. ++ * ++ * For real URIs or libvirt URIs this may cause corruption in corner ++ * cases. (See L ++ * describing some of the complexity involved in dealing with real ++ * URI). ++ * ++ * On error, returns C and sets C appropriately. ++ * ++ * Caller must call C on the returned structure or use the ++ * C cleanup macro. ++ */ ++xmlURIPtr ++guestfs_int_parse_nonstandard_uri (const char *arg) ++{ ++ CLEANUP_FREE char *uri = NULL; ++ CLEANUP_FREE char *escaped_uri = NULL; ++ static const char hexdigit[] = "0123456789abcdef"; ++ size_t i, j, len; ++ xmlURIPtr ret; ++ ++ /* Convert the string to UTF-8. */ ++ uri = local_string_to_utf8 ((char *) arg); ++ if (uri == NULL) ++ return NULL; ++ ++ /* Since we know the URI is in well-formed UTF-8 we can iterate over ++ * the bytes to do the escaping. The output of this will never be ++ * more than 3 times larger (each byte might be rewritten as ‘%XX’). ++ */ ++ len = strlen (uri); ++ escaped_uri = malloc (3*len + 1); ++ if (escaped_uri == NULL) ++ return NULL; ++ ++ for (i = j = 0; i < strlen (uri); ++i) { ++ /* See RFC 3986 appendix A. Note this leaves existing %-encoded ++ * escapes alone. ++ */ ++ if (c_isalnum (uri[i]) || ++ strchr ("%-._~:/?#[]@!$&'()*+,;=", uri[i]) != NULL) ++ escaped_uri[j++] = uri[i]; ++ else { ++ escaped_uri[j++] = '%'; ++ escaped_uri[j++] = hexdigit [(((unsigned char) uri[i]) >> 4) & 0xf]; ++ escaped_uri[j++] = hexdigit [((unsigned char) uri[i]) & 0xf]; ++ } ++ } ++ escaped_uri[j++] = '\0'; ++ ++ /* libxml2 xmlParseURI does not reliably set errno, so it's likely ++ * best to ignore whatever errno is returned and overwrite it with ++ * EINVAL. ++ */ ++ ret = xmlParseURI (escaped_uri); ++ if (ret == NULL) { ++ errno = EINVAL; ++ return NULL; ++ } ++ ++ return ret; ++} ++ ++/* Would be const, but the interface to iconv is not const-correct on ++ * all platforms. The input string is not touched. ++ */ ++static char * ++local_string_to_utf8 (/* const */ char *input) ++{ ++ iconv_t ic; ++ size_t len, inlen, outlen, outalloc, r, prev; ++ int err; ++ char *out, *inp, *outp; ++ ++ /* Convert from input locale to UTF-8. */ ++ ic = iconv_open ("UTF-8", nl_langinfo (CODESET)); ++ if (ic == (iconv_t) -1) ++ return NULL; ++ ++ len = strlen (input); ++ outalloc = len; /* Initial guess. */ ++ ++ again: ++ inlen = len; ++ outlen = outalloc; ++ out = malloc (outlen + 1); ++ if (out == NULL) { ++ err = errno; ++ iconv_close (ic); ++ errno = err; ++ return NULL; ++ } ++ inp = input; ++ outp = out; ++ ++ r = iconv (ic, (ICONV_CONST char **) &inp, &inlen, &outp, &outlen); ++ if (r == (size_t) -1) { ++ if (errno == E2BIG) { ++ err = errno; ++ prev = outalloc; ++ /* Try again with a larger output buffer. */ ++ free (out); ++ outalloc *= 2; ++ if (outalloc < prev) { ++ iconv_close (ic); ++ errno = err; ++ return NULL; ++ } ++ goto again; ++ } ++ else { ++ /* Else some other conversion failure, eg. EILSEQ, EINVAL. */ ++ err = errno; ++ iconv_close (ic); ++ free (out); ++ errno = err; ++ return NULL; ++ } ++ } ++ ++ *outp = '\0'; ++ iconv_close (ic); ++ ++ return out; ++} +diff --git a/common/utils/libxml2-utils.h b/common/utils/libxml2-utils.h +new file mode 100644 +index 000000000..d9916ea58 +--- /dev/null ++++ b/common/utils/libxml2-utils.h +@@ -0,0 +1,27 @@ ++/* libguestfs ++ * Copyright (C) 2017 Red Hat Inc. ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#ifndef GUESTFS_LIBXML2_UTILS_H_ ++#define GUESTFS_LIBXML2_UTILS_H_ ++ ++#include ++ ++/* libxml2-utils.c */ ++extern xmlURIPtr guestfs_int_parse_nonstandard_uri (const char *uri); ++ ++#endif /* GUESTFS_LIBXML2_UTILS_H_ */ +diff --git a/v2v/input_vmx.ml b/v2v/input_vmx.ml +index a8b33f66f..b97fac700 100644 +--- a/v2v/input_vmx.ml ++++ b/v2v/input_vmx.ml +@@ -38,11 +38,11 @@ type vmx_source = + let vmx_source_of_arg input_transport arg = + match input_transport, arg with + | None, arg -> File arg +- | Some `SSH, arg -> ++ | Some `SSH, uri -> + let uri = +- try Xml.parse_uri arg +- with Invalid_argument _ -> +- error (f_"remote vmx ‘%s’ could not be parsed as a URI") arg in ++ try Xml.parse_nonstandard_uri uri ++ with exn -> ++ error (f_"could not parse URI: %s") (Printexc.to_string exn) in + if uri.Xml.uri_scheme <> None && uri.Xml.uri_scheme <> Some "ssh" then + error (f_"vmx URI start with ‘ssh://...’"); + if uri.Xml.uri_server = None then +diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod +index e30cc03fb..c67b67e48 100644 +--- a/v2v/virt-v2v.pod ++++ b/v2v/virt-v2v.pod +@@ -1458,10 +1458,7 @@ authorized_keys. + When using the SSH input transport you must specify a remote + C URI pointing to the VMX file. A typical URI looks like: + +- ssh://root@esxi.example.com/vmfs/volumes/datastore1/my%20guest/my%20guest.vmx +- +-Any space must be escaped with C<%20> and other non-ASCII characters +-may also need to be URI-escaped. ++ ssh://root@esxi.example.com/vmfs/volumes/datastore1/my guest/my guest.vmx + + The username is not required if it is the same as your local username. + +-- +2.16.1 + diff --git a/0002-common-extract-UTF-8-conversion-function.patch b/0002-common-extract-UTF-8-conversion-function.patch new file mode 100644 index 0000000..a2d8350 --- /dev/null +++ b/0002-common-extract-UTF-8-conversion-function.patch @@ -0,0 +1,224 @@ +From 10d1eacdac98575d0d8ce81bc04d74b12bf43cab Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?= +Date: Thu, 15 Feb 2018 17:38:19 +0100 +Subject: [PATCH 2/3] common: extract UTF-8 conversion function + +libxml2-utils.c local_string_to_utf8() function could easily be reused +in other places. This commit extracts it with a new parameter to allow +giving the encoding of the input string and publishes it in +guestfs-utils.h as guestfs_int_string_to_utf8() +--- + common/utils/guestfs-utils.h | 11 +++++++ + common/utils/libxml2-utils.c | 69 +------------------------------------------- + common/utils/utils.c | 64 ++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 76 insertions(+), 68 deletions(-) + +diff --git a/common/utils/guestfs-utils.h b/common/utils/guestfs-utils.h +index 90e7c3dd9..86da693bc 100644 +--- a/common/utils/guestfs-utils.h ++++ b/common/utils/guestfs-utils.h +@@ -33,6 +33,7 @@ + #define GUESTFS_UTILS_H_ + + #include ++#include + + #include "guestfs-internal-all.h" + #include "cleanups.h" +@@ -70,6 +71,16 @@ extern int guestfs_int_is_fifo (int64_t mode); + extern int guestfs_int_is_lnk (int64_t mode); + extern int guestfs_int_is_sock (int64_t mode); + extern char *guestfs_int_full_path (const char *dir, const char *name); ++extern char *guestfs_int_string_to_utf8 (/* const */ char *input, const char *encoding); ++ ++/* Would be const, but the interface to iconv is not const-correct on ++ * all platforms. The input string is not touched. ++ */ ++static inline char * ++guestfs_int_local_string_to_utf8 (/* const */ char *input) ++{ ++ return guestfs_int_string_to_utf8 (input, nl_langinfo (CODESET)); ++} + + /* Not all language bindings know how to deal with Pointer arguments. + * Those that don't will use this macro which complains noisily and +diff --git a/common/utils/libxml2-utils.c b/common/utils/libxml2-utils.c +index 8a05aa5b1..a71db30dd 100644 +--- a/common/utils/libxml2-utils.c ++++ b/common/utils/libxml2-utils.c +@@ -30,8 +30,6 @@ + #include + #include + #include +-#include +-#include + + #include + +@@ -42,8 +40,6 @@ + #include "guestfs-utils.h" + #include "libxml2-utils.h" + +-static char *local_string_to_utf8 (/* const */ char *input); +- + /** + * This is a wrapper around C. That function cannot + * handle spaces and some non-ASCII characters found in URIs. This +@@ -73,7 +69,7 @@ guestfs_int_parse_nonstandard_uri (const char *arg) + xmlURIPtr ret; + + /* Convert the string to UTF-8. */ +- uri = local_string_to_utf8 ((char *) arg); ++ uri = guestfs_int_local_string_to_utf8 ((char *) arg); + if (uri == NULL) + return NULL; + +@@ -113,66 +109,3 @@ guestfs_int_parse_nonstandard_uri (const char *arg) + + return ret; + } +- +-/* Would be const, but the interface to iconv is not const-correct on +- * all platforms. The input string is not touched. +- */ +-static char * +-local_string_to_utf8 (/* const */ char *input) +-{ +- iconv_t ic; +- size_t len, inlen, outlen, outalloc, r, prev; +- int err; +- char *out, *inp, *outp; +- +- /* Convert from input locale to UTF-8. */ +- ic = iconv_open ("UTF-8", nl_langinfo (CODESET)); +- if (ic == (iconv_t) -1) +- return NULL; +- +- len = strlen (input); +- outalloc = len; /* Initial guess. */ +- +- again: +- inlen = len; +- outlen = outalloc; +- out = malloc (outlen + 1); +- if (out == NULL) { +- err = errno; +- iconv_close (ic); +- errno = err; +- return NULL; +- } +- inp = input; +- outp = out; +- +- r = iconv (ic, (ICONV_CONST char **) &inp, &inlen, &outp, &outlen); +- if (r == (size_t) -1) { +- if (errno == E2BIG) { +- err = errno; +- prev = outalloc; +- /* Try again with a larger output buffer. */ +- free (out); +- outalloc *= 2; +- if (outalloc < prev) { +- iconv_close (ic); +- errno = err; +- return NULL; +- } +- goto again; +- } +- else { +- /* Else some other conversion failure, eg. EILSEQ, EINVAL. */ +- err = errno; +- iconv_close (ic); +- free (out); +- errno = err; +- return NULL; +- } +- } +- +- *outp = '\0'; +- iconv_close (ic); +- +- return out; +-} +diff --git a/common/utils/utils.c b/common/utils/utils.c +index 22af62b0f..faef7c089 100644 +--- a/common/utils/utils.c ++++ b/common/utils/utils.c +@@ -35,6 +35,7 @@ + #include + #include + #include ++#include + + /* NB: MUST NOT require linking to gnulib, because that will break the + * Python 'sdist' which includes a copy of this file. It's OK to +@@ -733,3 +734,66 @@ guestfs_int_full_path (const char *dir, const char *name) + + return path; + } ++ ++/* Would be const, but the interface to iconv is not const-correct on ++ * all platforms. The input string is not touched. ++ */ ++char * ++guestfs_int_string_to_utf8 (/* const */ char *input, const char *encoding) ++{ ++ iconv_t ic; ++ size_t len, inlen, outlen, outalloc, r, prev; ++ int err; ++ char *out, *inp, *outp; ++ ++ /* Convert from input encoding to UTF-8. */ ++ ic = iconv_open ("UTF-8", encoding); ++ if (ic == (iconv_t) -1) ++ return NULL; ++ ++ len = strlen (input); ++ outalloc = len; /* Initial guess. */ ++ ++ again: ++ inlen = len; ++ outlen = outalloc; ++ out = malloc (outlen + 1); ++ if (out == NULL) { ++ err = errno; ++ iconv_close (ic); ++ errno = err; ++ return NULL; ++ } ++ inp = input; ++ outp = out; ++ ++ r = iconv (ic, (ICONV_CONST char **) &inp, &inlen, &outp, &outlen); ++ if (r == (size_t) -1) { ++ if (errno == E2BIG) { ++ err = errno; ++ prev = outalloc; ++ /* Try again with a larger output buffer. */ ++ free (out); ++ outalloc *= 2; ++ if (outalloc < prev) { ++ iconv_close (ic); ++ errno = err; ++ return NULL; ++ } ++ goto again; ++ } ++ else { ++ /* Else some other conversion failure, eg. EILSEQ, EINVAL. */ ++ err = errno; ++ iconv_close (ic); ++ free (out); ++ errno = err; ++ return NULL; ++ } ++ } ++ ++ *outp = '\0'; ++ iconv_close (ic); ++ ++ return out; ++} +-- +2.16.1 + diff --git a/0003-inspector-rpm-summary-and-description-may-not-be-utf.patch b/0003-inspector-rpm-summary-and-description-may-not-be-utf.patch new file mode 100644 index 0000000..3d1ea62 --- /dev/null +++ b/0003-inspector-rpm-summary-and-description-may-not-be-utf.patch @@ -0,0 +1,132 @@ +From 2a20ad737e4682b9f304b6c3ba6116f4cc195541 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?= +Date: Wed, 14 Feb 2018 10:21:42 +0100 +Subject: [PATCH 3/3] inspector: rpm summary and description may not be utf-8 + +The application inspection code assumes the data in the RPM database +are encoded in UTF-8. However this is not always the case. + +As a basic workaround, try to parse the string to UTF-8 and if that +fails, try converting it from latin-1. +--- + inspector/expected-fedora.img.xml | 4 ++++ + lib/inspect-apps.c | 30 +++++++++++++++++++++++---- + test-data/phony-guests/fedora-packages.db.txt | 4 ++-- + 3 files changed, 32 insertions(+), 6 deletions(-) + +diff --git a/inspector/expected-fedora.img.xml b/inspector/expected-fedora.img.xml +index df6060a73..c29f9770e 100644 +--- a/inspector/expected-fedora.img.xml ++++ b/inspector/expected-fedora.img.xml +@@ -34,12 +34,16 @@ + 1.0 + 1.fc14 + x86_64 ++ summary with ö ++ description with ö + + + test2 + 2.0 + 2.fc14 + x86_64 ++ summary with ö ++ description with ö + + + test3 +diff --git a/lib/inspect-apps.c b/lib/inspect-apps.c +index f0cf16b38..fdea85188 100644 +--- a/lib/inspect-apps.c ++++ b/lib/inspect-apps.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + + #ifdef HAVE_ENDIAN_H + #include +@@ -43,6 +44,7 @@ + #include "guestfs.h" + #include "guestfs-internal.h" + #include "guestfs-internal-actions.h" ++#include "guestfs-utils.h" + #include "structs-cleanups.h" + + #ifdef DB_DUMP +@@ -251,7 +253,7 @@ get_rpm_header_tag (guestfs_h *g, const unsigned char *header_start, + /* This function parses the RPM header structure to pull out various + * tag strings (version, release, arch, etc.). For more detail on the + * header format, see: +- * http://www.rpm.org/max-rpm/s1-rpm-file-format-rpm-file-format.html#S2-RPM-FILE-FORMAT-HEADER ++ * http://rpm.org/devel_doc/file_format.html#24-header-format + */ + + /* The minimum header size that makes sense here is 24 bytes. Four +@@ -301,6 +303,20 @@ struct read_package_data { + struct guestfs_application2_list *apps; + }; + ++static char * ++to_utf8 (guestfs_h *g, char *input) ++{ ++ char *out = NULL; ++ ++ out = guestfs_int_string_to_utf8 (input, "UTF-8"); ++ if (!out) { ++ out = guestfs_int_string_to_utf8 (input, "ISO-8859-1"); ++ perrorf (g, "Not an UTF-8 or latin-1 string: '%s'", input); ++ } ++ ++ return out; ++} ++ + static int + read_package (guestfs_h *g, + const unsigned char *key, size_t keylen, +@@ -311,7 +327,7 @@ read_package (guestfs_h *g, + struct rpm_name nkey, *entry; + CLEANUP_FREE char *version = NULL, *release = NULL, + *epoch_str = NULL, *arch = NULL, *url = NULL, *summary = NULL, +- *description = NULL; ++ *description = NULL, *summary_raw = NULL, *description_raw = NULL; + int32_t epoch; + + /* This function reads one (key, value) pair from the Packages +@@ -342,8 +358,14 @@ read_package (guestfs_h *g, + epoch_str = get_rpm_header_tag (g, value, valuelen, RPMTAG_EPOCH, 'i'); + arch = get_rpm_header_tag (g, value, valuelen, RPMTAG_ARCH, 's'); + url = get_rpm_header_tag (g, value, valuelen, RPMTAG_URL, 's'); +- summary = get_rpm_header_tag (g, value, valuelen, RPMTAG_SUMMARY, 's'); +- description = get_rpm_header_tag (g, value, valuelen, RPMTAG_DESCRIPTION, 's'); ++ summary_raw = get_rpm_header_tag (g, value, valuelen, RPMTAG_SUMMARY, 's'); ++ description_raw = get_rpm_header_tag (g, value, valuelen, RPMTAG_DESCRIPTION, 's'); ++ ++ /* Try (not too hard) to get UTF-8 */ ++ if (summary_raw) ++ summary = to_utf8 (g, summary_raw); ++ if (description_raw) ++ description = to_utf8 (g, description_raw); + + /* The epoch is stored as big-endian integer. */ + if (epoch_str) +diff --git a/test-data/phony-guests/fedora-packages.db.txt b/test-data/phony-guests/fedora-packages.db.txt +index f16a5aa76..927d6eb5f 100644 +--- a/test-data/phony-guests/fedora-packages.db.txt ++++ b/test-data/phony-guests/fedora-packages.db.txt +@@ -5,9 +5,9 @@ h_nelem=3 + db_pagesize=4096 + HEADER=END + \01\00\00\00 +- \00\00\00\03\00\00\00\11\00\00\03\e9\00\00\00\00\00\00\00\00\00\00\00\00\00\00\03\ea\00\00\00\00\00\00\00\04\00\00\00\00\00\00\03\fe\00\00\00\00\00\00\00\0b\00\00\00\001.0\001.fc14\00x86_64\00 ++ \00\00\00\05\00\00\00\33\00\00\03\e9\00\00\00\00\00\00\00\00\00\00\00\00\00\00\03\ea\00\00\00\00\00\00\00\04\00\00\00\00\00\00\03\fe\00\00\00\00\00\00\00\0b\00\00\00\00\00\00\03\ec\00\00\00\00\00\00\00\12\00\00\00\00\00\00\03\ed\00\00\00\00\00\00\00\21\00\00\00\001.0\001.fc14\00x86_64\00summary with \f6\00description with \f6\00 + \02\00\00\00 +- \00\00\00\03\00\00\00\11\00\00\03\e9\00\00\00\00\00\00\00\00\00\00\00\00\00\00\03\ea\00\00\00\00\00\00\00\04\00\00\00\00\00\00\03\fe\00\00\00\00\00\00\00\0b\00\00\00\002.0\002.fc14\00x86_64\00 ++ \00\00\00\05\00\00\00\35\00\00\03\e9\00\00\00\00\00\00\00\00\00\00\00\00\00\00\03\ea\00\00\00\00\00\00\00\04\00\00\00\00\00\00\03\fe\00\00\00\00\00\00\00\0b\00\00\00\00\00\00\03\ec\00\00\00\00\00\00\00\12\00\00\00\00\00\00\03\ed\00\00\00\00\00\00\00\22\00\00\00\002.0\002.fc14\00x86_64\00summary with \c3\b6\00description with \c3\b6\00 + \03\00\00\00 + \00\00\00\03\00\00\00\11\00\00\03\e9\00\00\00\00\00\00\00\00\00\00\00\00\00\00\03\ea\00\00\00\00\00\00\00\04\00\00\00\00\00\00\03\fe\00\00\00\00\00\00\00\0b\00\00\00\003.0\003.fc14\00x86_64\00 + DATA=END +-- +2.16.1 + diff --git a/0a55098f-builder-repository-fix-compute_short_id-for-sles-X.0.patch b/0a55098f-builder-repository-fix-compute_short_id-for-sles-X.0.patch new file mode 100644 index 0000000..af62e81 --- /dev/null +++ b/0a55098f-builder-repository-fix-compute_short_id-for-sles-X.0.patch @@ -0,0 +1,28 @@ +From 0a55098f661457b3a4e17b8f5cdd7540d53aec32 Mon Sep 17 00:00:00 2001 +From: Pino Toscano +Date: Thu, 22 Feb 2018 18:39:37 +0100 +Subject: [PATCH] builder-repository: fix compute_short_id for sles X.0 + +It needs to check for the minor version, not major version. + +Fixes commit a442d2c3217f709128f0e377f88649fb6ba90f45. +--- + builder/repository_main.ml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/builder/repository_main.ml b/builder/repository_main.ml +index bb440563b..9932fbae4 100644 +--- a/builder/repository_main.ml ++++ b/builder/repository_main.ml +@@ -178,7 +178,7 @@ let compute_short_id distro major minor = + sprintf "%s%d" distro major + | ("fedora"|"mageia") -> + sprintf "%s%d" distro major +- | "sles" when major = 0 -> ++ | "sles" when minor = 0 -> + sprintf "%s%d" distro major + | "sles" -> + sprintf "%s%dsp%d" distro major minor +-- +2.16.1 + diff --git a/libguestfs.changes b/libguestfs.changes index ba1aa13..600a24c 100644 --- a/libguestfs.changes +++ b/libguestfs.changes @@ -1,3 +1,16 @@ +------------------------------------------------------------------- +Tue Feb 27 13:14:35 UTC 2018 - cbosdonnat@suse.com + +- Remove unneeded createrepo build dependency (bsc#1082689) +- builder-repository: fix SLES short id computation + Patch added: + 0a55098f-builder-repository-fix-compute_short_id-for-sles-X.0.patch +- Fix handling of Latin-1 encoding in rpmdb (bsc#1075803) + Patches added: + 0001-Introduce-a-wrapper-around-xmlParseURI.patch + 0002-common-extract-UTF-8-conversion-function.patch + 0003-inspector-rpm-summary-and-description-may-not-be-utf.patch + ------------------------------------------------------------------- Fri Feb 23 08:53:30 UTC 2018 - adam.majer@suse.de diff --git a/libguestfs.spec b/libguestfs.spec index 8e375b6..693d751 100644 --- a/libguestfs.spec +++ b/libguestfs.spec @@ -97,7 +97,6 @@ BuildRequires: ncurses-devel %if %{with perl_bindings} BuildRequires: perl(Module::Build) %endif -BuildRequires: createrepo BuildRequires: db48-utils BuildRequires: dhcp-client BuildRequires: pcre-devel @@ -140,9 +139,16 @@ BuildRequires: gtk2-devel Url: http://libguestfs.org/ BuildRoot: %{_tmppath}/%{name}-%{version}-build Summary: Compatibility package for guestfs-tools +# Upstream patches License: GPL-2.0 Group: System/Filesystems Patch0: d0e5a819-python-Fix-missing-additional-backslashes.patch +Patch1: 0a55098f-builder-repository-fix-compute_short_id-for-sles-X.0.patch +# Pending upstram review +Patch50: 0001-Introduce-a-wrapper-around-xmlParseURI.patch +Patch51: 0002-common-extract-UTF-8-conversion-function.patch +Patch52: 0003-inspector-rpm-summary-and-description-may-not-be-utf.patch +# Our patches Patch100: appliance.patch Source0: http://download.libguestfs.org/1.38-stable/libguestfs-%{version}.tar.gz @@ -554,6 +560,10 @@ It can import a variety of guest operating systems from libvirt-managed hosts. : _ignore_exclusive_arch '%{?_ignore_exclusive_arch}' %setup -q -a 789653 %patch0 -p1 +%patch1 -p1 +%patch50 -p1 +%patch51 -p1 +%patch52 -p1 %patch100 -p1 %build