Hello community,

here is the log from the commit of package libguestfs for openSUSE:Factory 
checked in at 2018-03-01 12:07:41
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libguestfs (Old)
 and      /work/SRC/openSUSE:Factory/.libguestfs.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libguestfs"

Thu Mar  1 12:07:41 2018 rev:61 rq:580951 version:1.38.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/libguestfs/libguestfs.changes    2018-02-23 
15:32:23.420902968 +0100
+++ /work/SRC/openSUSE:Factory/.libguestfs.new/libguestfs.changes       
2018-03-01 12:07:41.802339646 +0100
@@ -1,0 +2,13 @@
+Tue Feb 27 13:14:35 UTC 2018 - cbosdon...@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
+
+-------------------------------------------------------------------

New:
----
  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
  0a55098f-builder-repository-fix-compute_short_id-for-sles-X.0.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libguestfs.spec ++++++
--- /var/tmp/diff_new_pack.JfUvgA/_old  2018-03-01 12:07:42.838302459 +0100
+++ /var/tmp/diff_new_pack.JfUvgA/_new  2018-03-01 12:07:42.842302316 +0100
@@ -97,7 +97,6 @@
 %if %{with perl_bindings}
 BuildRequires:  perl(Module::Build)
 %endif
-BuildRequires:  createrepo
 BuildRequires:  db48-utils
 BuildRequires:  dhcp-client
 BuildRequires:  pcre-devel
@@ -140,9 +139,16 @@
 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 @@
 : _ignore_exclusive_arch '%{?_ignore_exclusive_arch}'
 %setup -q -a 789653
 %patch0 -p1
+%patch1 -p1
+%patch50 -p1
+%patch51 -p1
+%patch52 -p1
 %patch100 -p1
 
 %build

++++++ 0001-Introduce-a-wrapper-around-xmlParseURI.patch ++++++
>From 66dbffd38377abeb64144990421e52293613840a Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjo...@redhat.com>
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 <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <errno.h>
 
 #include <caml/alloc.h>
 #include <caml/custom.h>
 #include <caml/fail.h>
 #include <caml/memory.h>
 #include <caml/mlvalues.h>
+#include <caml/unixsupport.h>
 
 #include <libxml/xpath.h>
 #include <libxml/xpathInternals.h>
 #include <libxml/uri.h>
 
+#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<must not> call internal library functions
+ * such as C<safe_*>, C<error> or C<perrorf>, or any C<guestfs_int_*>.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <locale.h>
+#include <langinfo.h>
+#include <iconv.h>
+
+#include <libxml/uri.h>
+
+#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<xmlParseURI>.  That function cannot
+ * handle spaces and some non-ASCII characters found in URIs.  This
+ * wrapper URI-encodes those before calling C<xmlParseURI> and returns
+ * the URI structure.
+ *
+ * This function should B<only> 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<https://news.ycombinator.com/item?id=11673058>
+ * describing some of the complexity involved in dealing with real
+ * URI).
+ *
+ * On error, returns C<NULL> and sets C<errno> appropriately.
+ *
+ * Caller must call C<xmlFreeURI> on the returned structure or use the
+ * C<CLEANUP_XMLFREEURI> 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 <libxml/uri.h>
+
+/* 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<ssh://...> URI pointing to the VMX file.  A typical URI looks like:
 
- ssh://r...@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://r...@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

++++++ 0002-common-extract-UTF-8-conversion-function.patch ++++++
>From 10d1eacdac98575d0d8ce81bc04d74b12bf43cab Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?= <cbosdon...@suse.com>
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 <stdbool.h>
+#include <langinfo.h>
 
 #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 <string.h>
 #include <errno.h>
 #include <locale.h>
-#include <langinfo.h>
-#include <iconv.h>
 
 #include <libxml/uri.h>
 
@@ -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<xmlParseURI>.  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 <sys/types.h>
 #include <sys/wait.h>
 #include <libintl.h>
+#include <iconv.h>
 
 /* 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

++++++ 0003-inspector-rpm-summary-and-description-may-not-be-utf.patch ++++++
>From 2a20ad737e4682b9f304b6c3ba6116f4cc195541 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?= <cbosdon...@suse.com>
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 @@
         <version>1.0</version>
         <release>1.fc14</release>
         <arch>x86_64</arch>
+        <summary>summary with ö</summary>
+        <description>description with ö</description>
       </application>
       <application>
         <name>test2</name>
         <version>2.0</version>
         <release>2.fc14</release>
         <arch>x86_64</arch>
+        <summary>summary with ö</summary>
+        <description>description with ö</description>
       </application>
       <application>
         <name>test3</name>
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 <stdlib.h>
 #include <unistd.h>
 #include <string.h>
+#include <iconv.h>
 
 #ifdef HAVE_ENDIAN_H
 #include <endian.h>
@@ -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

++++++ 0a55098f-builder-repository-fix-compute_short_id-for-sles-X.0.patch 
++++++
>From 0a55098f661457b3a4e17b8f5cdd7540d53aec32 Mon Sep 17 00:00:00 2001
From: Pino Toscano <ptosc...@redhat.com>
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


Reply via email to