From: Marcin Krol Date: Mon, 20 Aug 2018 18:18:46 +0000 (+0000) Subject: - revert from jansson back to yajl, it is required for QEMU's quirky JSON X-Git-Url: https://git.tld-linux.org/?a=commitdiff_plain;h=440c6fd02965a2980ba2af8efad30e7e9513c435;p=packages%2Flibvirt.git - revert from jansson back to yajl, it is required for QEMU's quirky JSON https://bugzilla.redhat.com/show_bug.cgi?id=1614569 --- diff --git a/libvirt.spec b/libvirt.spec index ac9ec23..e24e7cc 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -42,7 +42,7 @@ Summary: Toolkit to interact with virtualization capabilities Summary(pl.UTF-8): Narzędzia współpracujące z funkcjami wirtualizacji Name: libvirt Version: 4.6.0 -Release: 1 +Release: 2 License: LGPL v2.1+ Group: Libraries Source0: http://libvirt.org/sources/libvirt-%{version}.tar.xz @@ -56,6 +56,7 @@ Patch2: %{name}-udevadm-settle.patch Patch3: bashisms.patch Patch4: %{name}-guests.init.patch Patch5: %{name}-sysctl-dir.patch +Patch6: yajl.patch URL: http://www.libvirt.org/ BuildRequires: acl-devel BuildRequires: attr-devel @@ -449,6 +450,7 @@ Moduł sekcji Wiresharka do pakietów libvirt. %patch3 -p1 %patch4 -p1 %patch5 -p1 +%patch6 -p1 %build %{__libtoolize} diff --git a/yajl.patch b/yajl.patch new file mode 100644 index 0000000..0f20679 --- /dev/null +++ b/yajl.patch @@ -0,0 +1,1848 @@ +diff -urNpa libvirt-4.6.0.orig/config-post.h libvirt-4.6.0/config-post.h +--- libvirt-4.6.0.orig/config-post.h 2018-07-28 13:26:44.376463865 +0000 ++++ libvirt-4.6.0/config-post.h 2018-08-20 18:00:20.571398013 +0000 +@@ -36,7 +36,6 @@ + # undef WITH_DEVMAPPER + # undef WITH_DTRACE_PROBES + # undef WITH_GNUTLS +-# undef WITH_JANSSON + # undef WITH_LIBSSH + # undef WITH_MACVTAP + # undef WITH_NUMACTL +@@ -44,6 +43,8 @@ + # undef WITH_SSH2 + # undef WITH_SYSTEMD_DAEMON + # undef WITH_VIRTUALPORT ++# undef WITH_YAJL ++# undef WITH_YAJL2 + #endif + + /* +diff -urNpa libvirt-4.6.0.orig/configure.ac libvirt-4.6.0/configure.ac +--- libvirt-4.6.0.orig/configure.ac 2018-07-28 13:26:44.376463865 +0000 ++++ libvirt-4.6.0/configure.ac 2018-08-20 18:01:24.611397292 +0000 +@@ -250,7 +250,6 @@ LIBVIRT_ARG_FIREWALLD + LIBVIRT_ARG_FUSE + LIBVIRT_ARG_GLUSTER + LIBVIRT_ARG_HAL +-LIBVIRT_ARG_JANSSON + LIBVIRT_ARG_LIBPCAP + LIBVIRT_ARG_LIBSSH + LIBVIRT_ARG_LIBXML +@@ -291,7 +290,6 @@ LIBVIRT_CHECK_FUSE + LIBVIRT_CHECK_GLUSTER + LIBVIRT_CHECK_GNUTLS + LIBVIRT_CHECK_HAL +-LIBVIRT_CHECK_JANSSON + LIBVIRT_CHECK_LIBNL + LIBVIRT_CHECK_LIBPARTED + LIBVIRT_CHECK_LIBPCAP +@@ -972,7 +970,6 @@ LIBVIRT_RESULT_FUSE + LIBVIRT_RESULT_GLUSTER + LIBVIRT_RESULT_GNUTLS + LIBVIRT_RESULT_HAL +-LIBVIRT_RESULT_JANSSON + LIBVIRT_RESULT_LIBNL + LIBVIRT_RESULT_LIBPCAP + LIBVIRT_RESULT_LIBSSH +diff -urNpa libvirt-4.6.0.orig/libvirt.spec.in libvirt-4.6.0/libvirt.spec.in +--- libvirt-4.6.0.orig/libvirt.spec.in 2018-08-02 03:58:35.025820949 +0000 ++++ libvirt-4.6.0/libvirt.spec.in 2018-08-20 18:00:20.572398013 +0000 +@@ -292,7 +292,7 @@ BuildRequires: libblkid-devel >= 2.17 + BuildRequires: augeas + BuildRequires: systemd-devel >= 185 + BuildRequires: libpciaccess-devel >= 0.10.9 +-BuildRequires: jansson-devel ++BuildRequires: yajl-devel + %if %{with_sanlock} + BuildRequires: sanlock-devel >= 2.4 + %endif +@@ -898,8 +898,6 @@ Requires: ncurses + Requires: gettext + # Needed by virt-pki-validate script. + Requires: gnutls-utils +-# We dlopen(libjansson.so.4), so need an explicit dep +-Requires: jansson + %if %{with_bash_completion} + Requires: %{name}-bash-completion = %{version}-%{release} + %endif +@@ -1228,7 +1226,7 @@ rm -f po/stamp-po + --without-apparmor \ + --without-hal \ + --with-udev \ +- --with-jansson \ ++ --with-yajl \ + %{?arg_sanlock} \ + --with-libpcap \ + --with-macvtap \ +diff -urNpa libvirt-4.6.0.orig/m4/virt-driver-qemu.m4 libvirt-4.6.0/m4/virt-driver-qemu.m4 +--- libvirt-4.6.0.orig/m4/virt-driver-qemu.m4 2018-07-28 13:26:44.395463693 +0000 ++++ libvirt-4.6.0/m4/virt-driver-qemu.m4 2018-08-20 18:00:20.572398013 +0000 +@@ -18,7 +18,7 @@ dnl . + dnl + + AC_DEFUN([LIBVIRT_DRIVER_ARG_QEMU], [ +- LIBVIRT_ARG_WITH_FEATURE([QEMU], [QEMU/KVM], [check]) ++ LIBVIRT_ARG_WITH_FEATURE([QEMU], [QEMU/KVM], [yes]) + LIBVIRT_ARG_WITH([QEMU_USER], [username to run QEMU system instance as], + ['platform dependent']) + LIBVIRT_ARG_WITH([QEMU_GROUP], [groupname to run QEMU system instance as], +@@ -26,13 +26,6 @@ AC_DEFUN([LIBVIRT_DRIVER_ARG_QEMU], [ + ]) + + AC_DEFUN([LIBVIRT_DRIVER_CHECK_QEMU], [ +- AC_REQUIRE([LIBVIRT_CHECK_JANSSON]) +- if test "$with_qemu:$with_jansson" = "yes:no"; then +- AC_MSG_ERROR([Jansson >= 2.5 is required to build QEMU driver]) +- fi +- if test "$with_qemu" = "check"; then +- with_qemu=$with_jansson +- fi + if test "$with_qemu" = "yes" ; then + AC_DEFINE_UNQUOTED([WITH_QEMU], 1, [whether QEMU driver is enabled]) + fi +diff -urNpa libvirt-4.6.0.orig/m4/virt-jansson.m4 libvirt-4.6.0/m4/virt-jansson.m4 +--- libvirt-4.6.0.orig/m4/virt-jansson.m4 2018-07-28 13:26:44.395463693 +0000 ++++ libvirt-4.6.0/m4/virt-jansson.m4 1970-01-01 00:00:00.000000000 +0000 +@@ -1,32 +0,0 @@ +-dnl The jansson library +-dnl +-dnl This library is free software; you can redistribute it and/or +-dnl modify it under the terms of the GNU Lesser General Public +-dnl License as published by the Free Software Foundation; either +-dnl version 2.1 of the License, or (at your option) any later version. +-dnl +-dnl This library is distributed in the hope that it will be useful, +-dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +-dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-dnl Lesser General Public License for more details. +-dnl +-dnl You should have received a copy of the GNU Lesser General Public +-dnl License along with this library. If not, see +-dnl . +-dnl +- +-AC_DEFUN([LIBVIRT_ARG_JANSSON],[ +- LIBVIRT_ARG_WITH_FEATURE([JANSSON], [jansson], [check]) +-]) +- +-AC_DEFUN([LIBVIRT_CHECK_JANSSON],[ +- dnl Jansson http://www.digip.org/jansson/ +- LIBVIRT_CHECK_PKG([JANSSON], [jansson], [2.5]) +- dnl Older versions of Jansson did not preserve the order of object keys +- dnl use this check to guard the tests that are sensitive to this +- LIBVIRT_CHECK_PKG([STABLE_ORDERING_JANSSON], [jansson], [2.8], [true]) +-]) +- +-AC_DEFUN([LIBVIRT_RESULT_JANSSON],[ +- LIBVIRT_RESULT_LIB([JANSSON]) +-]) +diff -urNpa libvirt-4.6.0.orig/m4/virt-nss.m4 libvirt-4.6.0/m4/virt-nss.m4 +--- libvirt-4.6.0.orig/m4/virt-nss.m4 2018-07-28 13:26:44.396463684 +0000 ++++ libvirt-4.6.0/m4/virt-nss.m4 2018-08-20 18:00:20.572398013 +0000 +@@ -27,9 +27,9 @@ AC_DEFUN([LIBVIRT_CHECK_NSS],[ + bsd_nss=no + fail=0 + if test "x$with_nss_plugin" != "xno" ; then +- if test "x$with_jansson" != "xyes" ; then ++ if test "x$with_yajl" != "xyes" ; then + if test "x$with_nss_plugin" = "xyes" ; then +- AC_MSG_ERROR([Can't build nss plugin without JSON support]) ++ AC_MSG_ERROR([Can't build nss plugin without yajl]) + else + with_nss_plugin=no + fi +diff -urNpa libvirt-4.6.0.orig/m4/virt-yajl.m4 libvirt-4.6.0/m4/virt-yajl.m4 +--- libvirt-4.6.0.orig/m4/virt-yajl.m4 2018-07-28 13:26:44.396463684 +0000 ++++ libvirt-4.6.0/m4/virt-yajl.m4 2018-08-20 18:00:20.572398013 +0000 +@@ -23,10 +23,31 @@ AC_DEFUN([LIBVIRT_ARG_YAJL],[ + + AC_DEFUN([LIBVIRT_CHECK_YAJL],[ + dnl YAJL JSON library http://lloyd.github.com/yajl/ +- if test "$with_yajl" = yes; then +- AC_MSG_ERROR([Compilation with YAJL is no longer supported]) ++ if test "$with_qemu:$with_yajl" = yes:check; then ++ dnl Some versions of qemu require the use of yajl; try to detect them ++ dnl here, although we do not require qemu to exist in order to compile. ++ dnl This check mirrors src/qemu/qemu_capabilities.c ++ AC_PATH_PROGS([QEMU], [qemu-kvm qemu kvm qemu-system-x86_64], ++ [], [$PATH:/usr/bin:/usr/libexec]) ++ if test -x "$QEMU"; then ++ if $QEMU -help 2>/dev/null | grep -q libvirt; then ++ with_yajl=yes ++ else ++ [qemu_version_sed='s/.*ersion \([0-9.,]*\).*/\1/'] ++ qemu_version=`$QEMU -version | sed "$qemu_version_sed"` ++ case $qemu_version in ++ [[1-9]].* | 0.15.* ) with_yajl=yes ;; ++ 0.* | '' ) ;; ++ *) AC_MSG_ERROR([Unexpected qemu version string]) ;; ++ esac ++ fi ++ fi + fi +- with_yajl=no ++ ++ LIBVIRT_CHECK_LIB_ALT([YAJL], [yajl], ++ [yajl_parse_complete], [yajl/yajl_common.h], ++ [YAJL2], [yajl], ++ [yajl_tree_parse], [yajl/yajl_common.h]) + ]) + + AC_DEFUN([LIBVIRT_RESULT_YAJL],[ +diff -urNpa libvirt-4.6.0.orig/src/libvirt_private.syms libvirt-4.6.0/src/libvirt_private.syms +--- libvirt-4.6.0.orig/src/libvirt_private.syms 2018-08-02 03:58:35.114820107 +0000 ++++ libvirt-4.6.0/src/libvirt_private.syms 2018-08-20 18:00:20.572398013 +0000 +@@ -2098,6 +2098,7 @@ virJSONValueNewNumberUint; + virJSONValueNewNumberUlong; + virJSONValueNewObject; + virJSONValueNewString; ++virJSONValueNewStringLen; + virJSONValueObjectAdd; + virJSONValueObjectAddVArgs; + virJSONValueObjectAppend; +@@ -2135,10 +2136,6 @@ virJSONValueObjectStealObject; + virJSONValueToString; + + +-# util/virjsoncompat.h +-virJSONInitialize; +- +- + # util/virkeycode.h + virKeycodeSetTypeFromString; + virKeycodeSetTypeToString; +diff -urNpa libvirt-4.6.0.orig/src/Makefile.am libvirt-4.6.0/src/Makefile.am +--- libvirt-4.6.0.orig/src/Makefile.am 2018-08-02 03:58:35.114820107 +0000 ++++ libvirt-4.6.0/src/Makefile.am 2018-08-20 18:04:33.691395163 +0000 +@@ -544,7 +544,7 @@ libvirt_admin_la_CFLAGS = \ + libvirt_admin_la_CFLAGS += \ + $(XDR_CFLAGS) \ + $(CAPNG_CFLAGS) \ +- $(JANSSON_CFLAGS) \ ++ $(YAJL_CFLAGS) \ + $(SSH2_CFLAGS) \ + $(SASL_CFLAGS) \ + $(GNUTLS_CFLAGS) \ +@@ -552,6 +552,7 @@ libvirt_admin_la_CFLAGS += \ + + libvirt_admin_la_LIBADD += \ + $(CAPNG_LIBS) \ ++ $(YAJL_LIBS) \ + $(DEVMAPPER_LIBS) \ + $(LIBXML_LIBS) \ + $(SSH2_LIBS) \ +@@ -689,7 +690,6 @@ libvirt_setuid_rpc_client_la_SOURCES = \ + util/virhashcode.c \ + util/virhostcpu.c \ + util/virjson.c \ +- util/virjsoncompat.c \ + util/virlog.c \ + util/virobject.c \ + util/virpidfile.c \ +@@ -961,8 +961,6 @@ libvirt_nss_la_SOURCES = \ + util/virhashcode.h \ + util/virjson.c \ + util/virjson.h \ +- util/virjsoncompat.c \ +- util/virjsoncompat.h \ + util/virkmod.c \ + util/virkmod.h \ + util/virlease.c \ +@@ -996,11 +994,15 @@ libvirt_nss_la_SOURCES = \ + libvirt_nss_la_CFLAGS = \ + -DLIBVIRT_NSS \ + $(AM_CFLAGS) \ +- $(JANSSON_CFLAGS) \ ++ $(YAJL_CFLAGS) \ + $(NULL) + libvirt_nss_la_LDFLAGS = \ + $(AM_LDFLAGS) \ + $(NULL) ++ ++libvirt_nss_la_LIBADD = \ ++ $(YAJL_LIBS) \ ++ $(NULL) + endif WITH_NSS + + +diff -urNpa libvirt-4.6.0.orig/src/qemu/qemu_driver.c libvirt-4.6.0/src/qemu/qemu_driver.c +--- libvirt-4.6.0.orig/src/qemu/qemu_driver.c 2018-07-31 03:31:26.316391201 +0000 ++++ libvirt-4.6.0/src/qemu/qemu_driver.c 2018-08-20 18:00:20.575398013 +0000 +@@ -2092,7 +2092,7 @@ qemuDomainReboot(virDomainPtr dom, unsig + */ + if ((!useAgent) || + (ret < 0 && (acpiRequested || !flags))) { +-#if !WITH_JANSSON ++#if !WITH_YAJL + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("ACPI reboot is not supported without the JSON monitor")); + goto endjob; +diff -urNpa libvirt-4.6.0.orig/src/remote/remote_daemon.c libvirt-4.6.0/src/remote/remote_daemon.c +--- libvirt-4.6.0.orig/src/remote/remote_daemon.c 2018-08-02 03:58:35.116820088 +0000 ++++ libvirt-4.6.0/src/remote/remote_daemon.c 2018-08-20 18:00:20.575398013 +0000 +@@ -59,7 +59,6 @@ + #include "virutil.h" + #include "virgettext.h" + #include "util/virnetdevopenvswitch.h" +-#include "virjsoncompat.h" + + #include "driver.h" + +@@ -1184,9 +1183,6 @@ int main(int argc, char **argv) { + exit(EXIT_FAILURE); + } + +- if (virJSONInitialize() < 0) +- exit(EXIT_FAILURE); +- + daemonSetupNetDevOpenvswitch(config); + + if (daemonSetupAccessManager(config) < 0) { +diff -urNpa libvirt-4.6.0.orig/src/util/Makefile.inc.am libvirt-4.6.0/src/util/Makefile.inc.am +--- libvirt-4.6.0.orig/src/util/Makefile.inc.am 2018-08-02 03:58:35.116820088 +0000 ++++ libvirt-4.6.0/src/util/Makefile.inc.am 2018-08-20 18:00:20.575398013 +0000 +@@ -86,8 +86,6 @@ UTIL_SOURCES = \ + util/viriscsi.h \ + util/virjson.c \ + util/virjson.h \ +- util/virjsoncompat.c \ +- util/virjsoncompat.h \ + util/virkeycode.c \ + util/virkeycode.h \ + util/virkeyfile.c \ +@@ -253,7 +251,7 @@ libvirt_util_la_SOURCES = \ + $(NULL) + libvirt_util_la_CFLAGS = \ + $(CAPNG_CFLAGS) \ +- $(JANSSON_CFLAGS) \ ++ $(YAJL_CFLAGS) \ + $(LIBNL_CFLAGS) \ + $(AM_CFLAGS) \ + $(AUDIT_CFLAGS) \ +@@ -266,6 +264,7 @@ libvirt_util_la_CFLAGS = \ + $(NULL) + libvirt_util_la_LIBADD = \ + $(CAPNG_LIBS) \ ++ $(YAJL_LIBS) \ + $(LIBNL_LIBS) \ + $(THREAD_LIBS) \ + $(AUDIT_LIBS) \ +diff -urNpa libvirt-4.6.0.orig/src/util/virjson.c libvirt-4.6.0/src/util/virjson.c +--- libvirt-4.6.0.orig/src/util/virjson.c 2018-08-02 03:58:35.117820079 +0000 ++++ libvirt-4.6.0/src/util/virjson.c 2018-08-20 18:00:20.576398013 +0000 +@@ -29,6 +29,22 @@ + #include "virstring.h" + #include "virutil.h" + ++#if WITH_YAJL ++# include ++# include ++ ++# ifdef WITH_YAJL2 ++# define yajl_size_t size_t ++# define VIR_YAJL_STATUS_OK(status) ((status) == yajl_status_ok) ++# else ++# define yajl_size_t unsigned int ++# define yajl_complete_parse yajl_parse_complete ++# define VIR_YAJL_STATUS_OK(status) \ ++ ((status) == yajl_status_ok || (status) == yajl_status_insufficient_data) ++# endif ++ ++#endif ++ + /* XXX fixme */ + #define VIR_FROM_THIS VIR_FROM_NONE + +@@ -72,6 +88,23 @@ struct _virJSONValue { + }; + + ++typedef struct _virJSONParserState virJSONParserState; ++typedef virJSONParserState *virJSONParserStatePtr; ++struct _virJSONParserState { ++ virJSONValuePtr value; ++ char *key; ++}; ++ ++typedef struct _virJSONParser virJSONParser; ++typedef virJSONParser *virJSONParserPtr; ++struct _virJSONParser { ++ virJSONValuePtr head; ++ virJSONParserStatePtr state; ++ size_t nstate; ++ int wrap; ++}; ++ ++ + virJSONType + virJSONValueGetType(const virJSONValue *value) + { +@@ -420,6 +453,28 @@ virJSONValueNewString(const char *data) + } + + ++virJSONValuePtr ++virJSONValueNewStringLen(const char *data, ++ size_t length) ++{ ++ virJSONValuePtr val; ++ ++ if (!data) ++ return virJSONValueNewNull(); ++ ++ if (VIR_ALLOC(val) < 0) ++ return NULL; ++ ++ val->type = VIR_JSON_TYPE_STRING; ++ if (VIR_STRNDUP(val->data.string, data, length) < 0) { ++ VIR_FREE(val); ++ return NULL; ++ } ++ ++ return val; ++} ++ ++ + static virJSONValuePtr + virJSONValueNewNumber(const char *data) + { +@@ -1436,193 +1491,446 @@ virJSONValueCopy(const virJSONValue *in) + } + + +-#if WITH_JANSSON ++#if WITH_YAJL ++static int ++virJSONParserInsertValue(virJSONParserPtr parser, ++ virJSONValuePtr value) ++{ ++ if (!parser->head) { ++ parser->head = value; ++ } else { ++ virJSONParserStatePtr state; ++ if (!parser->nstate) { ++ VIR_DEBUG("got a value to insert without a container"); ++ return -1; ++ } + +-# include "virjsoncompat.h" ++ state = &parser->state[parser->nstate-1]; + +-static virJSONValuePtr +-virJSONValueFromJansson(json_t *json) +-{ +- virJSONValuePtr ret = NULL; +- const char *key; +- json_t *cur; +- size_t i; ++ switch (state->value->type) { ++ case VIR_JSON_TYPE_OBJECT: { ++ if (!state->key) { ++ VIR_DEBUG("missing key when inserting object value"); ++ return -1; ++ } + +- switch (json_typeof(json)) { +- case JSON_OBJECT: +- ret = virJSONValueNewObject(); +- if (!ret) +- goto error; ++ if (virJSONValueObjectAppend(state->value, ++ state->key, ++ value) < 0) ++ return -1; + +- json_object_foreach(json, key, cur) { +- virJSONValuePtr val = virJSONValueFromJansson(cur); +- if (!val) +- goto error; ++ VIR_FREE(state->key); ++ } break; + +- if (virJSONValueObjectAppend(ret, key, val) < 0) { +- virJSONValueFree(val); +- goto error; ++ case VIR_JSON_TYPE_ARRAY: { ++ if (state->key) { ++ VIR_DEBUG("unexpected key when inserting array value"); ++ return -1; + } ++ ++ if (virJSONValueArrayAppend(state->value, ++ value) < 0) ++ return -1; ++ } break; ++ ++ default: ++ VIR_DEBUG("unexpected value type, not a container"); ++ return -1; + } ++ } + +- break; ++ return 0; ++} + +- case JSON_ARRAY: +- ret = virJSONValueNewArray(); +- if (!ret) +- goto error; + +- json_array_foreach(json, i, cur) { +- virJSONValuePtr val = virJSONValueFromJansson(cur); +- if (!val) +- goto error; ++static int ++virJSONParserHandleNull(void *ctx) ++{ ++ virJSONParserPtr parser = ctx; ++ virJSONValuePtr value = virJSONValueNewNull(); + +- if (virJSONValueArrayAppend(ret, val) < 0) { +- virJSONValueFree(val); +- goto error; +- } +- } +- break; ++ VIR_DEBUG("parser=%p", parser); + +- case JSON_STRING: +- ret = virJSONValueNewString(json_string_value(json)); +- break; ++ if (!value) ++ return 0; + +- case JSON_INTEGER: +- ret = virJSONValueNewNumberLong(json_integer_value(json)); +- break; ++ if (virJSONParserInsertValue(parser, value) < 0) { ++ virJSONValueFree(value); ++ return 0; ++ } + +- case JSON_REAL: +- ret = virJSONValueNewNumberDouble(json_real_value(json)); +- break; ++ return 1; ++} + +- case JSON_TRUE: +- ret = virJSONValueNewBoolean(true); +- break; + +- case JSON_FALSE: +- ret = virJSONValueNewBoolean(false); +- break; ++static int ++virJSONParserHandleBoolean(void *ctx, ++ int boolean_) ++{ ++ virJSONParserPtr parser = ctx; ++ virJSONValuePtr value = virJSONValueNewBoolean(boolean_); + +- case JSON_NULL: +- ret = virJSONValueNewNull(); +- break; ++ VIR_DEBUG("parser=%p boolean=%d", parser, boolean_); ++ ++ if (!value) ++ return 0; ++ ++ if (virJSONParserInsertValue(parser, value) < 0) { ++ virJSONValueFree(value); ++ return 0; + } + +- return ret; ++ return 1; ++} + +- error: +- virJSONValueFree(ret); +- return NULL; ++ ++static int ++virJSONParserHandleNumber(void *ctx, ++ const char *s, ++ yajl_size_t l) ++{ ++ virJSONParserPtr parser = ctx; ++ char *str; ++ virJSONValuePtr value; ++ ++ if (VIR_STRNDUP(str, s, l) < 0) ++ return -1; ++ value = virJSONValueNewNumber(str); ++ VIR_FREE(str); ++ ++ VIR_DEBUG("parser=%p str=%s", parser, str); ++ ++ if (!value) ++ return 0; ++ ++ if (virJSONParserInsertValue(parser, value) < 0) { ++ virJSONValueFree(value); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++ ++static int ++virJSONParserHandleString(void *ctx, ++ const unsigned char *stringVal, ++ yajl_size_t stringLen) ++{ ++ virJSONParserPtr parser = ctx; ++ virJSONValuePtr value = virJSONValueNewStringLen((const char *)stringVal, ++ stringLen); ++ ++ VIR_DEBUG("parser=%p str=%p", parser, (const char *)stringVal); ++ ++ if (!value) ++ return 0; ++ ++ if (virJSONParserInsertValue(parser, value) < 0) { ++ virJSONValueFree(value); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++ ++static int ++virJSONParserHandleMapKey(void *ctx, ++ const unsigned char *stringVal, ++ yajl_size_t stringLen) ++{ ++ virJSONParserPtr parser = ctx; ++ virJSONParserStatePtr state; ++ ++ VIR_DEBUG("parser=%p key=%p", parser, (const char *)stringVal); ++ ++ if (!parser->nstate) ++ return 0; ++ ++ state = &parser->state[parser->nstate-1]; ++ if (state->key) ++ return 0; ++ if (VIR_STRNDUP(state->key, (const char *)stringVal, stringLen) < 0) ++ return 0; ++ return 1; + } + ++ ++static int ++virJSONParserHandleStartMap(void *ctx) ++{ ++ virJSONParserPtr parser = ctx; ++ virJSONValuePtr value = virJSONValueNewObject(); ++ ++ VIR_DEBUG("parser=%p", parser); ++ ++ if (!value) ++ return 0; ++ ++ if (virJSONParserInsertValue(parser, value) < 0) { ++ virJSONValueFree(value); ++ return 0; ++ } ++ ++ if (VIR_REALLOC_N(parser->state, ++ parser->nstate + 1) < 0) { ++ return 0; ++ } ++ ++ parser->state[parser->nstate].value = value; ++ parser->state[parser->nstate].key = NULL; ++ parser->nstate++; ++ ++ return 1; ++} ++ ++ ++static int ++virJSONParserHandleEndMap(void *ctx) ++{ ++ virJSONParserPtr parser = ctx; ++ virJSONParserStatePtr state; ++ ++ VIR_DEBUG("parser=%p", parser); ++ ++ if (!parser->nstate) ++ return 0; ++ ++ state = &(parser->state[parser->nstate-1]); ++ if (state->key) { ++ VIR_FREE(state->key); ++ return 0; ++ } ++ ++ VIR_DELETE_ELEMENT(parser->state, parser->nstate - 1, parser->nstate); ++ ++ return 1; ++} ++ ++ ++static int ++virJSONParserHandleStartArray(void *ctx) ++{ ++ virJSONParserPtr parser = ctx; ++ virJSONValuePtr value = virJSONValueNewArray(); ++ ++ VIR_DEBUG("parser=%p", parser); ++ ++ if (!value) ++ return 0; ++ ++ if (virJSONParserInsertValue(parser, value) < 0) { ++ virJSONValueFree(value); ++ return 0; ++ } ++ ++ if (VIR_REALLOC_N(parser->state, ++ parser->nstate + 1) < 0) ++ return 0; ++ ++ parser->state[parser->nstate].value = value; ++ parser->state[parser->nstate].key = NULL; ++ parser->nstate++; ++ ++ return 1; ++} ++ ++ ++static int ++virJSONParserHandleEndArray(void *ctx) ++{ ++ virJSONParserPtr parser = ctx; ++ virJSONParserStatePtr state; ++ ++ VIR_DEBUG("parser=%p", parser); ++ ++ if (!(parser->nstate - parser->wrap)) ++ return 0; ++ ++ state = &(parser->state[parser->nstate-1]); ++ if (state->key) { ++ VIR_FREE(state->key); ++ return 0; ++ } ++ ++ VIR_DELETE_ELEMENT(parser->state, parser->nstate - 1, parser->nstate); ++ ++ return 1; ++} ++ ++ ++static const yajl_callbacks parserCallbacks = { ++ virJSONParserHandleNull, ++ virJSONParserHandleBoolean, ++ NULL, ++ NULL, ++ virJSONParserHandleNumber, ++ virJSONParserHandleString, ++ virJSONParserHandleStartMap, ++ virJSONParserHandleMapKey, ++ virJSONParserHandleEndMap, ++ virJSONParserHandleStartArray, ++ virJSONParserHandleEndArray ++}; ++ ++ ++/* XXX add an incremental streaming parser - yajl trivially supports it */ + virJSONValuePtr + virJSONValueFromString(const char *jsonstring) + { ++ yajl_handle hand; ++ virJSONParser parser = { NULL, NULL, 0, 0 }; + virJSONValuePtr ret = NULL; +- json_t *json; +- json_error_t error; +- size_t flags = JSON_REJECT_DUPLICATES | +- JSON_DECODE_ANY; ++ int rc; ++ size_t len = strlen(jsonstring); ++# ifndef WITH_YAJL2 ++ yajl_parser_config cfg = { 0, 1 }; /* Match yajl 2 default behavior */ ++ VIR_AUTOPTR(virJSONValue) tmp = NULL; ++# endif ++ ++ VIR_DEBUG("string=%s", jsonstring); ++ ++# ifdef WITH_YAJL2 ++ hand = yajl_alloc(&parserCallbacks, NULL, &parser); ++# else ++ hand = yajl_alloc(&parserCallbacks, &cfg, NULL, &parser); ++# endif ++ if (!hand) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("Unable to create JSON parser")); ++ goto cleanup; ++ } + +- if (virJSONInitialize() < 0) +- return NULL; ++ /* Yajl 2 is nice enough to default to rejecting trailing garbage. ++ * Yajl 1.0.12 has yajl_get_bytes_consumed to make that detection ++ * simpler. But we're stuck with yajl 1.0.7 on RHEL 6, which ++ * happily quits parsing at the end of a valid JSON construct, ++ * with no visibility into how much more input remains. Wrapping ++ * things in an array forces yajl to confess the truth. */ ++# ifdef WITH_YAJL2 ++ rc = yajl_parse(hand, (const unsigned char *)jsonstring, len); ++# else ++ rc = yajl_parse(hand, (const unsigned char *)"[", 1); ++ parser.wrap = 1; ++ if (VIR_YAJL_STATUS_OK(rc)) ++ rc = yajl_parse(hand, (const unsigned char *)jsonstring, len); ++ parser.wrap = 0; ++ if (VIR_YAJL_STATUS_OK(rc)) ++ rc = yajl_parse(hand, (const unsigned char *)"]", 1); ++# endif ++ if (!VIR_YAJL_STATUS_OK(rc) || ++ yajl_complete_parse(hand) != yajl_status_ok) { ++ unsigned char *errstr = yajl_get_error(hand, 1, ++ (const unsigned char*)jsonstring, ++ strlen(jsonstring)); + +- if (!(json = json_loads(jsonstring, flags, &error))) { + virReportError(VIR_ERR_INTERNAL_ERROR, +- _("failed to parse JSON %d:%d: %s"), +- error.line, error.column, error.text); +- return NULL; ++ _("cannot parse json %s: %s"), ++ jsonstring, (const char*) errstr); ++ yajl_free_error(hand, errstr); ++ virJSONValueFree(parser.head); ++ goto cleanup; + } + +- ret = virJSONValueFromJansson(json); +- json_decref(json); ++ if (parser.nstate != 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("cannot parse json %s: unterminated string/map/array"), ++ jsonstring); ++ virJSONValueFree(parser.head); ++ } else { ++ ret = parser.head; ++# ifndef WITH_YAJL2 ++ /* Undo the array wrapping above */ ++ tmp = ret; ++ ret = NULL; ++ if (virJSONValueArraySize(tmp) > 1) ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("cannot parse json %s: too many items present"), ++ jsonstring); ++ else ++ ret = virJSONValueArraySteal(tmp, 0); ++# endif ++ } ++ ++ cleanup: ++ yajl_free(hand); ++ ++ if (parser.nstate) { ++ size_t i; ++ for (i = 0; i < parser.nstate; i++) ++ VIR_FREE(parser.state[i].key); ++ VIR_FREE(parser.state); ++ } ++ ++ VIR_DEBUG("result=%p", ret); ++ + return ret; + } + + +-static json_t * +-virJSONValueToJansson(virJSONValuePtr object) ++static int ++virJSONValueToStringOne(virJSONValuePtr object, ++ yajl_gen g) + { +- json_t *ret = NULL; + size_t i; + +- switch ((virJSONType)object->type) { ++ VIR_DEBUG("object=%p type=%d gen=%p", object, object->type, g); ++ ++ switch (object->type) { + case VIR_JSON_TYPE_OBJECT: +- ret = json_object(); +- if (!ret) +- goto no_memory; ++ if (yajl_gen_map_open(g) != yajl_gen_status_ok) ++ return -1; + for (i = 0; i < object->data.object.npairs; i++) { +- virJSONObjectPairPtr cur = object->data.object.pairs + i; +- json_t *val = virJSONValueToJansson(cur->value); +- +- if (!val) +- goto error; +- if (json_object_set_new(ret, cur->key, val) < 0) { +- json_decref(val); +- goto no_memory; +- } ++ if (yajl_gen_string(g, ++ (unsigned char *)object->data.object.pairs[i].key, ++ strlen(object->data.object.pairs[i].key)) ++ != yajl_gen_status_ok) ++ return -1; ++ if (virJSONValueToStringOne(object->data.object.pairs[i].value, g) < 0) ++ return -1; + } ++ if (yajl_gen_map_close(g) != yajl_gen_status_ok) ++ return -1; + break; +- + case VIR_JSON_TYPE_ARRAY: +- ret = json_array(); +- if (!ret) +- goto no_memory; ++ if (yajl_gen_array_open(g) != yajl_gen_status_ok) ++ return -1; + for (i = 0; i < object->data.array.nvalues; i++) { +- virJSONValuePtr cur = object->data.array.values[i]; +- json_t *val = virJSONValueToJansson(cur); +- +- if (!val) +- goto error; +- if (json_array_append_new(ret, val) < 0) { +- json_decref(val); +- goto no_memory; +- } ++ if (virJSONValueToStringOne(object->data.array.values[i], g) < 0) ++ return -1; + } ++ if (yajl_gen_array_close(g) != yajl_gen_status_ok) ++ return -1; + break; + + case VIR_JSON_TYPE_STRING: +- ret = json_string(object->data.string); ++ if (yajl_gen_string(g, (unsigned char *)object->data.string, ++ strlen(object->data.string)) != yajl_gen_status_ok) ++ return -1; + break; + +- case VIR_JSON_TYPE_NUMBER: { +- long long ll_val; +- double d_val; +- if (virStrToLong_ll(object->data.number, NULL, 10, &ll_val) < 0) { +- if (virStrToDouble(object->data.number, NULL, &d_val) < 0) { +- virReportError(VIR_ERR_INTERNAL_ERROR, "%s", +- _("JSON value is not a number")); +- return NULL; +- } +- ret = json_real(d_val); +- } else { +- ret = json_integer(ll_val); +- } +- } ++ case VIR_JSON_TYPE_NUMBER: ++ if (yajl_gen_number(g, object->data.number, ++ strlen(object->data.number)) != yajl_gen_status_ok) ++ return -1; + break; + + case VIR_JSON_TYPE_BOOLEAN: +- ret = json_boolean(object->data.boolean); ++ if (yajl_gen_bool(g, object->data.boolean) != yajl_gen_status_ok) ++ return -1; + break; + + case VIR_JSON_TYPE_NULL: +- ret = json_null(); ++ if (yajl_gen_null(g) != yajl_gen_status_ok) ++ return -1; + break; + + default: +- virReportEnumRangeError(virJSONType, object->type); +- goto error; ++ return -1; + } +- if (!ret) +- goto no_memory; +- return ret; + +- no_memory: +- virReportOOMError(); +- error: +- json_decref(ret); +- return NULL; ++ return 0; + } + + +@@ -1630,27 +1938,50 @@ char * + virJSONValueToString(virJSONValuePtr object, + bool pretty) + { +- size_t flags = JSON_ENCODE_ANY; +- json_t *json; +- char *str = NULL; ++ yajl_gen g; ++ const unsigned char *str; ++ char *ret = NULL; ++ yajl_size_t len; ++# ifndef WITH_YAJL2 ++ yajl_gen_config conf = { pretty ? 1 : 0, pretty ? " " : " "}; ++# endif ++ ++ VIR_DEBUG("object=%p", object); ++ ++# ifdef WITH_YAJL2 ++ g = yajl_gen_alloc(NULL); ++ if (g) { ++ yajl_gen_config(g, yajl_gen_beautify, pretty ? 1 : 0); ++ yajl_gen_config(g, yajl_gen_indent_string, pretty ? " " : " "); ++ yajl_gen_config(g, yajl_gen_validate_utf8, 1); ++ } ++# else ++ g = yajl_gen_alloc(&conf, NULL); ++# endif ++ if (!g) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("Unable to create JSON formatter")); ++ goto cleanup; ++ } + +- if (virJSONInitialize() < 0) +- return NULL; ++ if (virJSONValueToStringOne(object, g) < 0) { ++ virReportOOMError(); ++ goto cleanup; ++ } + +- if (pretty) +- flags |= JSON_INDENT(2); +- else +- flags |= JSON_COMPACT; ++ if (yajl_gen_get_buf(g, &str, &len) != yajl_gen_status_ok) { ++ virReportOOMError(); ++ goto cleanup; ++ } + +- json = virJSONValueToJansson(object); +- if (!json) +- return NULL; ++ ignore_value(VIR_STRDUP(ret, (const char *)str)); + +- str = json_dumps(json, flags); +- if (!str) +- virReportOOMError(); +- json_decref(json); +- return str; ++ cleanup: ++ yajl_gen_free(g); ++ ++ VIR_DEBUG("result=%s", NULLSTR(ret)); ++ ++ return ret; + } + + +diff -urNpa libvirt-4.6.0.orig/src/util/virjsoncompat.c libvirt-4.6.0/src/util/virjsoncompat.c +--- libvirt-4.6.0.orig/src/util/virjsoncompat.c 2018-08-02 03:58:35.117820079 +0000 ++++ libvirt-4.6.0/src/util/virjsoncompat.c 1970-01-01 00:00:00.000000000 +0000 +@@ -1,285 +0,0 @@ +-/* +- * virjsoncompat.c: JSON object parsing/formatting +- * +- * Copyright (C) 2018 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.1 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, see +- * . +- * +- */ +- +-#include +- +-#include "virthread.h" +-#include "virerror.h" +-#define VIR_JSON_COMPAT_IMPL +-#include "virjsoncompat.h" +- +-#define VIR_FROM_THIS VIR_FROM_NONE +- +-#if WITH_JANSSON +- +-# include +- +-json_t *(*json_array_ptr)(void); +-int (*json_array_append_new_ptr)(json_t *array, json_t *value); +-json_t *(*json_array_get_ptr)(const json_t *array, size_t index); +-size_t (*json_array_size_ptr)(const json_t *array); +-void (*json_delete_ptr)(json_t *json); +-char *(*json_dumps_ptr)(const json_t *json, size_t flags); +-json_t *(*json_false_ptr)(void); +-json_t *(*json_integer_ptr)(json_int_t value); +-json_int_t (*json_integer_value_ptr)(const json_t *integer); +-json_t *(*json_loads_ptr)(const char *input, size_t flags, json_error_t *error); +-json_t *(*json_null_ptr)(void); +-json_t *(*json_object_ptr)(void); +-void *(*json_object_iter_ptr)(json_t *object); +-const char *(*json_object_iter_key_ptr)(void *iter); +-void *(*json_object_iter_next_ptr)(json_t *object, void *iter); +-json_t *(*json_object_iter_value_ptr)(void *iter); +-void *(*json_object_key_to_iter_ptr)(const char *key); +-int (*json_object_set_new_ptr)(json_t *object, const char *key, json_t *value); +-json_t *(*json_real_ptr)(double value); +-double (*json_real_value_ptr)(const json_t *real); +-json_t *(*json_string_ptr)(const char *value); +-const char *(*json_string_value_ptr)(const json_t *string); +-json_t *(*json_true_ptr)(void); +- +- +-static int +-virJSONJanssonOnceInit(void) +-{ +- void *handle = dlopen("libjansson.so.4", RTLD_LAZY|RTLD_LOCAL|RTLD_NODELETE); +- if (!handle) { +- virReportError(VIR_ERR_NO_SUPPORT, +- _("libjansson.so.4 JSON library not available: %s"), dlerror()); +- return -1; +- } +- +-# define LOAD(name) \ +- do { \ +- if (!(name ## _ptr = dlsym(handle, #name))) { \ +- virReportError(VIR_ERR_NO_SUPPORT, \ +- _("missing symbol '%s' in libjansson.so.4: %s"), #name, dlerror()); \ +- return -1; \ +- } \ +- } while (0) +- +- LOAD(json_array); +- LOAD(json_array_append_new); +- LOAD(json_array_get); +- LOAD(json_array_size); +- LOAD(json_delete); +- LOAD(json_dumps); +- LOAD(json_false); +- LOAD(json_integer); +- LOAD(json_integer_value); +- LOAD(json_loads); +- LOAD(json_null); +- LOAD(json_object); +- LOAD(json_object_iter); +- LOAD(json_object_iter_key); +- LOAD(json_object_iter_next); +- LOAD(json_object_iter_value); +- LOAD(json_object_key_to_iter); +- LOAD(json_object_set_new); +- LOAD(json_real); +- LOAD(json_real_value); +- LOAD(json_string); +- LOAD(json_string_value); +- LOAD(json_true); +- +- return 0; +-} +- +-VIR_ONCE_GLOBAL_INIT(virJSONJansson); +- +-int +-virJSONInitialize(void) +-{ +- return virJSONJanssonInitialize(); +-} +- +-json_t * +-json_array_impl(void) +-{ +- return json_array_ptr(); +-} +- +- +-int +-json_array_append_new_impl(json_t *array, json_t *value) +-{ +- return json_array_append_new_ptr(array, value); +-} +- +- +-json_t * +-json_array_get_impl(const json_t *array, size_t index) +-{ +- return json_array_get_ptr(array, index); +-} +- +- +-size_t +-json_array_size_impl(const json_t *array) +-{ +- return json_array_size_ptr(array); +-} +- +- +-void +-json_delete_impl(json_t *json) +-{ +- return json_delete_ptr(json); +-} +- +- +-char * +-json_dumps_impl(const json_t *json, size_t flags) +-{ +- return json_dumps_ptr(json, flags); +-} +- +- +-json_t * +-json_false_impl(void) +-{ +- return json_false_ptr(); +-} +- +- +-json_t * +-json_integer_impl(json_int_t value) +-{ +- return json_integer_ptr(value); +-} +- +- +-json_int_t +-json_integer_value_impl(const json_t *integer) +-{ +- return json_integer_value_ptr(integer); +-} +- +- +-json_t * +-json_loads_impl(const char *input, size_t flags, json_error_t *error) +-{ +- return json_loads_ptr(input, flags, error); +-} +- +- +-json_t * +-json_null_impl(void) +-{ +- return json_null_ptr(); +-} +- +- +-json_t * +-json_object_impl(void) +-{ +- return json_object_ptr(); +-} +- +- +-void * +-json_object_iter_impl(json_t *object) +-{ +- return json_object_iter_ptr(object); +-} +- +- +-const char * +-json_object_iter_key_impl(void *iter) +-{ +- return json_object_iter_key_ptr(iter); +-} +- +- +-void * +-json_object_iter_next_impl(json_t *object, void *iter) +-{ +- return json_object_iter_next_ptr(object, iter); +-} +- +- +-json_t * +-json_object_iter_value_impl(void *iter) +-{ +- return json_object_iter_value_ptr(iter); +-} +- +- +-void * +-json_object_key_to_iter_impl(const char *key) +-{ +- return json_object_key_to_iter_ptr(key); +-} +- +- +-int +-json_object_set_new_impl(json_t *object, const char *key, json_t *value) +-{ +- return json_object_set_new_ptr(object, key, value); +-} +- +- +-json_t * +-json_real_impl(double value) +-{ +- return json_real_ptr(value); +-} +- +- +-double +-json_real_value_impl(const json_t *real) +-{ +- return json_real_value_ptr(real); +-} +- +- +-json_t * +-json_string_impl(const char *value) +-{ +- return json_string_ptr(value); +-} +- +- +-const char * +-json_string_value_impl(const json_t *string) +-{ +- return json_string_value_ptr(string); +-} +- +- +-json_t * +-json_true_impl(void) +-{ +- return json_true_ptr(); +-} +- +- +-#else /* !WITH_JANSSON */ +- +- +-int +-virJSONInitialize(void) +-{ +- return 0; +-} +- +- +-#endif /* !WITH_JANSSON */ +diff -urNpa libvirt-4.6.0.orig/src/util/virjsoncompat.h libvirt-4.6.0/src/util/virjsoncompat.h +--- libvirt-4.6.0.orig/src/util/virjsoncompat.h 2018-08-02 03:58:35.117820079 +0000 ++++ libvirt-4.6.0/src/util/virjsoncompat.h 1970-01-01 00:00:00.000000000 +0000 +@@ -1,88 +0,0 @@ +-/* +- * virjsoncompat.h: JSON object parsing/formatting +- * +- * Copyright (C) 2018 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.1 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, see +- * . +- * +- */ +- +- +-#ifndef __VIR_JSON_COMPAT_H_ +-# define __VIR_JSON_COMPAT_H_ +- +-# if WITH_JANSSON +-# ifndef VIR_JSON_COMPAT_IMPL +- +-# define json_array json_array_impl +-# define json_array_append_new json_array_append_new_impl +-# define json_array_get json_array_get_impl +-# define json_array_size json_array_size_impl +-# define json_delete json_delete_impl +-# define json_dumps json_dumps_impl +-# define json_false json_false_impl +-# define json_integer json_integer_impl +-# define json_integer_value json_integer_value_impl +-# define json_loads json_loads_impl +-# define json_null json_null_impl +-# define json_object json_object_impl +-# define json_object_iter json_object_iter_impl +-# define json_object_iter_key json_object_iter_key_impl +-# define json_object_iter_next json_object_iter_next_impl +-# define json_object_iter_value json_object_iter_value_impl +-# define json_object_key_to_iter json_object_key_to_iter_impl +-# define json_object_set_new json_object_set_new_impl +-# define json_real json_real_impl +-# define json_real_value json_real_value_impl +-# define json_string json_string_impl +-# define json_string_value json_string_value_impl +-# define json_true json_true_impl +- +-# endif /* ! VIR_JSON_COMPAT_IMPL */ +- +-# include +- +-# ifdef VIR_JSON_COMPAT_IMPL +- +-json_t *json_array_impl(void); +-int json_array_append_new_impl(json_t *array, json_t *value); +-json_t *json_array_get_impl(const json_t *array, size_t index); +-size_t json_array_size_impl(const json_t *array); +-void json_delete_impl(json_t *json); +-char *json_dumps_impl(const json_t *json, size_t flags); +-json_t *json_false_impl(void); +-json_t *json_integer_impl(json_int_t value); +-json_int_t json_integer_value_impl(const json_t *integer); +-json_t *json_loads_impl(const char *input, size_t flags, json_error_t *error); +-json_t *json_null_impl(void); +-json_t *json_object_impl(void); +-void *json_object_iter_impl(json_t *object); +-const char *json_object_iter_key_impl(void *iter); +-void *json_object_iter_next_impl(json_t *object, void *iter); +-json_t *json_object_iter_value_impl(void *iter); +-void *json_object_key_to_iter_impl(const char *key); +-int json_object_set_new_impl(json_t *object, const char *key, json_t *value); +-json_t *json_real_impl(double value); +-double json_real_value_impl(const json_t *real); +-json_t *json_string_impl(const char *value); +-const char *json_string_value_impl(const json_t *string); +-json_t *json_true_impl(void); +- +-# endif /* VIR_JSON_COMPAT_IMPL */ +-# endif /* WITH_JANSSON */ +- +-int virJSONInitialize(void); +- +-#endif /* __VIR_JSON_COMPAT_H_ */ +diff -urNpa libvirt-4.6.0.orig/src/util/virjson.h libvirt-4.6.0/src/util/virjson.h +--- libvirt-4.6.0.orig/src/util/virjson.h 2018-07-28 13:26:44.464463065 +0000 ++++ libvirt-4.6.0/src/util/virjson.h 2018-08-20 18:00:20.576398013 +0000 +@@ -59,6 +59,7 @@ int virJSONValueObjectAddVArgs(virJSONVa + + + virJSONValuePtr virJSONValueNewString(const char *data); ++virJSONValuePtr virJSONValueNewStringLen(const char *data, size_t length); + virJSONValuePtr virJSONValueNewNumberInt(int data); + virJSONValuePtr virJSONValueNewNumberUint(unsigned int data); + virJSONValuePtr virJSONValueNewNumberLong(long long data); +diff -urNpa libvirt-4.6.0.orig/tests/cputest.c libvirt-4.6.0/tests/cputest.c +--- libvirt-4.6.0.orig/tests/cputest.c 2018-07-28 13:26:44.475462965 +0000 ++++ libvirt-4.6.0/tests/cputest.c 2018-08-20 18:00:20.576398013 +0000 +@@ -40,7 +40,7 @@ + #include "cpu/cpu_map.h" + #include "virstring.h" + +-#if WITH_QEMU && WITH_JANSSON ++#if WITH_QEMU && WITH_YAJL + # include "testutilsqemu.h" + # include "qemumonitortestutils.h" + # define __QEMU_CAPSPRIV_H_ALLOW__ +@@ -67,7 +67,7 @@ struct data { + int result; + }; + +-#if WITH_QEMU && WITH_JANSSON ++#if WITH_QEMU && WITH_YAJL + static virQEMUDriver driver; + #endif + +@@ -479,7 +479,7 @@ typedef enum { + JSON_MODELS_REQUIRED, + } cpuTestCPUIDJson; + +-#if WITH_QEMU && WITH_JANSSON ++#if WITH_QEMU && WITH_YAJL + static virQEMUCapsPtr + cpuTestMakeQEMUCaps(const struct data *data) + { +@@ -554,7 +554,7 @@ cpuTestGetCPUModels(const struct data *d + return 0; + } + +-#else /* if WITH_QEMU && WITH_JANSSON */ ++#else /* if WITH_QEMU && WITH_YAJL */ + + static int + cpuTestGetCPUModels(const struct data *data, +@@ -834,7 +834,7 @@ cpuTestUpdateLive(const void *arg) + } + + +-#if WITH_QEMU && WITH_JANSSON ++#if WITH_QEMU && WITH_YAJL + static int + cpuTestJSONCPUID(const void *arg) + { +@@ -911,7 +911,7 @@ mymain(void) + virDomainCapsCPUModelsPtr ppc_models = NULL; + int ret = 0; + +-#if WITH_QEMU && WITH_JANSSON ++#if WITH_QEMU && WITH_YAJL + if (qemuTestDriverInit(&driver) < 0) + return EXIT_FAILURE; + +@@ -1004,7 +1004,7 @@ mymain(void) + host "/" cpu " (" #models ")", \ + host, cpu, models, 0, result) + +-#if WITH_QEMU && WITH_JANSSON ++#if WITH_QEMU && WITH_YAJL + # define DO_TEST_JSON(arch, host, json) \ + do { \ + if (json == JSON_MODELS) { \ +@@ -1205,7 +1205,7 @@ mymain(void) + DO_TEST_CPUID(VIR_ARCH_X86_64, "Xeon-X5460", JSON_NONE); + + cleanup: +-#if WITH_QEMU && WITH_JANSSON ++#if WITH_QEMU && WITH_YAJL + qemuTestDriverFree(&driver); + #endif + +diff -urNpa libvirt-4.6.0.orig/tests/libxlxml2domconfigtest.c libvirt-4.6.0/tests/libxlxml2domconfigtest.c +--- libvirt-4.6.0.orig/tests/libxlxml2domconfigtest.c 2018-08-06 09:22:16.558995687 +0000 ++++ libvirt-4.6.0/tests/libxlxml2domconfigtest.c 2018-08-20 18:00:20.576398013 +0000 +@@ -33,7 +33,7 @@ + + #include "testutils.h" + +-#if defined(WITH_LIBXL) && defined(WITH_JANSSON) && defined(HAVE_LIBXL_DOMAIN_CONFIG_FROM_JSON) ++#if defined(WITH_LIBXL) && defined(WITH_YAJL) && defined(HAVE_LIBXL_DOMAIN_CONFIG_FROM_JSON) + + # include "internal.h" + # include "viralloc.h" +@@ -228,4 +228,4 @@ int main(void) + return EXIT_AM_SKIP; + } + +-#endif /* WITH_LIBXL && WITH_JANSSON && HAVE_LIBXL_DOMAIN_CONFIG_FROM_JSON */ ++#endif /* WITH_LIBXL && WITH_YAJL && HAVE_LIBXL_DOMAIN_CONFIG_FROM_JSON */ +diff -urNpa libvirt-4.6.0.orig/tests/Makefile.am libvirt-4.6.0/tests/Makefile.am +--- libvirt-4.6.0.orig/tests/Makefile.am 2018-07-28 13:26:44.475462965 +0000 ++++ libvirt-4.6.0/tests/Makefile.am 2018-08-20 18:00:20.576398013 +0000 +@@ -46,7 +46,7 @@ AM_CFLAGS = \ + $(SASL_CFLAGS) \ + $(SELINUX_CFLAGS) \ + $(APPARMOR_CFLAGS) \ +- $(JANSSON_CFLAGS) \ ++ $(YAJL_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + $(XDR_CFLAGS) \ + $(WARN_CFLAGS) +@@ -331,9 +331,9 @@ if WITH_CIL + test_programs += objectlocking + endif WITH_CIL + +-if WITH_JANSSON ++if WITH_YAJL + test_programs += virjsontest +-endif WITH_JANSSON ++endif WITH_YAJL + + test_programs += \ + networkxml2xmltest \ +@@ -1219,15 +1219,15 @@ virdeterministichashmock_la_LIBADD = $(M + + test_libraries += virdeterministichashmock.la + +-if WITH_JANSSON ++if WITH_YAJL + virmacmaptest_SOURCES = \ + virmacmaptest.c testutils.h testutils.c + virmacmaptest_LDADD = $(LDADDS) + + test_programs += virmacmaptest +-else ! WITH_JANSSON ++else ! WITH_YAJL + EXTRA_DIST += virmacmaptest.c +-endif ! WITH_JANSSON ++endif ! WITH_YAJL + + virnetdevtest_SOURCES = \ + virnetdevtest.c testutils.h testutils.c +diff -urNpa libvirt-4.6.0.orig/tests/qemuagenttest.c libvirt-4.6.0/tests/qemuagenttest.c +--- libvirt-4.6.0.orig/tests/qemuagenttest.c 2018-07-28 13:26:44.477462947 +0000 ++++ libvirt-4.6.0/tests/qemuagenttest.c 2018-08-20 18:00:20.576398013 +0000 +@@ -907,8 +907,8 @@ mymain(void) + { + int ret = 0; + +-#if !WITH_STABLE_ORDERING_JANSSON +- fputs("libvirt not compiled with recent enough Jansson, skipping this test\n", stderr); ++#if !WITH_YAJL ++ fputs("libvirt not compiled with JSON support, skipping this test\n", stderr); + return EXIT_AM_SKIP; + #endif + +diff -urNpa libvirt-4.6.0.orig/tests/qemublocktest.c libvirt-4.6.0/tests/qemublocktest.c +--- libvirt-4.6.0.orig/tests/qemublocktest.c 2018-07-28 13:26:44.477462947 +0000 ++++ libvirt-4.6.0/tests/qemublocktest.c 2018-08-20 18:00:20.577398013 +0000 +@@ -309,7 +309,6 @@ testQemuDiskXMLToPropsValidateFile(const + goto cleanup; + + virBufferAdd(&buf, jsonstr, -1); +- virBufferAddLit(&buf, "\n"); + VIR_FREE(jsonstr); + } + +@@ -337,11 +336,6 @@ mymain(void) + char *capslatest_x86_64 = NULL; + virQEMUCapsPtr caps_x86_64 = NULL; + +-#if !WITH_STABLE_ORDERING_JANSSON +- fputs("libvirt not compiled with recent enough Jansson, skipping this test\n", stderr); +- return EXIT_AM_SKIP; +-#endif +- + if (qemuTestDriverInit(&driver) < 0) + return EXIT_FAILURE; + +diff -urNpa libvirt-4.6.0.orig/tests/qemucapabilitiestest.c libvirt-4.6.0/tests/qemucapabilitiestest.c +--- libvirt-4.6.0.orig/tests/qemucapabilitiestest.c 2018-07-28 13:26:44.484462883 +0000 ++++ libvirt-4.6.0/tests/qemucapabilitiestest.c 2018-08-20 18:00:20.577398013 +0000 +@@ -141,12 +141,7 @@ mymain(void) + int ret = 0; + testQemuData data; + +-#if !WITH_STABLE_ORDERING_JANSSON +- fputs("libvirt not compiled with recent enough Jansson, skipping this test\n", stderr); +- return EXIT_AM_SKIP; +-#endif +- +-#if !WITH_JANSSON ++#if !WITH_YAJL + fputs("libvirt not compiled with JSON support, skipping this test\n", stderr); + return EXIT_AM_SKIP; + #endif +diff -urNpa libvirt-4.6.0.orig/tests/qemucaps2xmltest.c libvirt-4.6.0/tests/qemucaps2xmltest.c +--- libvirt-4.6.0.orig/tests/qemucaps2xmltest.c 2018-07-28 13:26:44.484462883 +0000 ++++ libvirt-4.6.0/tests/qemucaps2xmltest.c 2018-08-20 18:00:20.577398013 +0000 +@@ -165,7 +165,7 @@ mymain(void) + + testQemuData data; + +-#if !WITH_JANSSON ++#if !WITH_YAJL + fputs("libvirt not compiled with JSON support, skipping this test\n", stderr); + return EXIT_AM_SKIP; + #endif +diff -urNpa libvirt-4.6.0.orig/tests/qemucapsprobemock.c libvirt-4.6.0/tests/qemucapsprobemock.c +--- libvirt-4.6.0.orig/tests/qemucapsprobemock.c 2018-08-02 03:58:35.117820079 +0000 ++++ libvirt-4.6.0/tests/qemucapsprobemock.c 2018-08-20 18:00:20.577398013 +0000 +@@ -76,7 +76,6 @@ qemuMonitorSend(qemuMonitorPtr mon, + printLineSkipEmpty("\n", stdout); + + printLineSkipEmpty(reformatted, stdout); +- printLineSkipEmpty("\n", stdout); + VIR_FREE(reformatted); + + return realQemuMonitorSend(mon, msg); +@@ -117,7 +116,6 @@ qemuMonitorJSONIOProcessLine(qemuMonitor + printLineSkipEmpty("\n", stdout); + + printLineSkipEmpty(json, stdout); +- printLineSkipEmpty("\n", stdout); + } + + cleanup: +diff -urNpa libvirt-4.6.0.orig/tests/qemucommandutiltest.c libvirt-4.6.0/tests/qemucommandutiltest.c +--- libvirt-4.6.0.orig/tests/qemucommandutiltest.c 2018-07-28 13:26:44.484462883 +0000 ++++ libvirt-4.6.0/tests/qemucommandutiltest.c 2018-08-20 18:00:20.577398013 +0000 +@@ -76,12 +76,7 @@ mymain(void) + int ret = 0; + testQemuCommandBuildObjectFromJSONData data1; + +-#if !WITH_STABLE_ORDERING_JANSSON +- fputs("libvirt not compiled with recent enough Jansson, skipping this test\n", stderr); +- return EXIT_AM_SKIP; +-#endif +- +-#if !WITH_JANSSON ++#if !WITH_YAJL + fputs("libvirt not compiled with JSON support, skipping this test\n", stderr); + return EXIT_AM_SKIP; + #endif +diff -urNpa libvirt-4.6.0.orig/tests/qemuhotplugtest.c libvirt-4.6.0/tests/qemuhotplugtest.c +--- libvirt-4.6.0.orig/tests/qemuhotplugtest.c 2018-07-28 13:26:44.484462883 +0000 ++++ libvirt-4.6.0/tests/qemuhotplugtest.c 2018-08-20 18:00:20.577398013 +0000 +@@ -593,12 +593,7 @@ mymain(void) + struct qemuHotplugTestData data = {0}; + struct testQemuHotplugCpuParams cpudata; + +-#if !WITH_STABLE_ORDERING_JANSSON +- fputs("libvirt not compiled with recent enough Jansson, skipping this test\n", stderr); +- return EXIT_AM_SKIP; +-#endif +- +-#if !WITH_JANSSON ++#if !WITH_YAJL + fputs("libvirt not compiled with JSON support, skipping this test\n", stderr); + return EXIT_AM_SKIP; + #endif +diff -urNpa libvirt-4.6.0.orig/tests/qemumigparamsdata/empty.json libvirt-4.6.0/tests/qemumigparamsdata/empty.json +--- libvirt-4.6.0.orig/tests/qemumigparamsdata/empty.json 2018-07-28 13:26:44.484462883 +0000 ++++ libvirt-4.6.0/tests/qemumigparamsdata/empty.json 2018-08-20 18:00:20.577398013 +0000 +@@ -1 +1,3 @@ +-{} ++{ ++ ++} +diff -urNpa libvirt-4.6.0.orig/tests/qemumigparamsdata/unsupported.json libvirt-4.6.0/tests/qemumigparamsdata/unsupported.json +--- libvirt-4.6.0.orig/tests/qemumigparamsdata/unsupported.json 2018-07-28 13:26:44.485462874 +0000 ++++ libvirt-4.6.0/tests/qemumigparamsdata/unsupported.json 2018-08-20 18:00:20.577398013 +0000 +@@ -1 +1,3 @@ +-{} ++{ ++ ++} +diff -urNpa libvirt-4.6.0.orig/tests/qemumigparamstest.c libvirt-4.6.0/tests/qemumigparamstest.c +--- libvirt-4.6.0.orig/tests/qemumigparamstest.c 2018-07-28 13:26:44.485462874 +0000 ++++ libvirt-4.6.0/tests/qemumigparamstest.c 2018-08-20 18:00:20.577398013 +0000 +@@ -203,12 +203,7 @@ mymain(void) + virQEMUDriver driver; + int ret = 0; + +-#if !WITH_STABLE_ORDERING_JANSSON +- fputs("libvirt not compiled with recent enough Jansson, skipping this test\n", stderr); +- return EXIT_AM_SKIP; +-#endif +- +-#if !WITH_JANSSON ++#if !WITH_YAJL + fputs("libvirt not compiled with JSON support, skipping this test\n", stderr); + return EXIT_AM_SKIP; + #endif +diff -urNpa libvirt-4.6.0.orig/tests/qemumonitorjsontest.c libvirt-4.6.0/tests/qemumonitorjsontest.c +--- libvirt-4.6.0.orig/tests/qemumonitorjsontest.c 2018-07-28 13:26:44.485462874 +0000 ++++ libvirt-4.6.0/tests/qemumonitorjsontest.c 2018-08-20 18:00:20.578398013 +0000 +@@ -2863,12 +2863,7 @@ mymain(void) + virJSONValuePtr metaschema = NULL; + char *metaschemastr = NULL; + +-#if !WITH_STABLE_ORDERING_JANSSON +- fputs("libvirt not compiled with recent enough Jansson, skipping this test\n", stderr); +- return EXIT_AM_SKIP; +-#endif +- +-#if !WITH_JANSSON ++#if !WITH_YAJL + fputs("libvirt not compiled with JSON support, skipping this test\n", stderr); + return EXIT_AM_SKIP; + #endif +diff -urNpa libvirt-4.6.0.orig/tests/virjsontest.c libvirt-4.6.0/tests/virjsontest.c +--- libvirt-4.6.0.orig/tests/virjsontest.c 2018-07-28 13:26:44.505462692 +0000 ++++ libvirt-4.6.0/tests/virjsontest.c 2018-08-20 18:00:20.578398013 +0000 +@@ -479,11 +479,6 @@ mymain(void) + { + int ret = 0; + +-#if !WITH_STABLE_ORDERING_JANSSON +- fputs("libvirt not compiled with recent enough Jansson, skipping this test\n", stderr); +- return EXIT_AM_SKIP; +-#endif +- + #define DO_TEST_FULL(name, cmd, doc, expect, pass) \ + do { \ + struct testInfo info = { doc, expect, pass }; \ +diff -urNpa libvirt-4.6.0.orig/tests/virmacmaptest.c libvirt-4.6.0/tests/virmacmaptest.c +--- libvirt-4.6.0.orig/tests/virmacmaptest.c 2018-07-28 13:26:44.505462692 +0000 ++++ libvirt-4.6.0/tests/virmacmaptest.c 2018-08-20 18:00:20.578398013 +0000 +@@ -157,11 +157,6 @@ mymain(void) + int ret = 0; + virMacMapPtr mgr = NULL; + +-#if !WITH_STABLE_ORDERING_JANSSON +- fputs("libvirt not compiled with recent enough Jansson, skipping this test\n", stderr); +- return EXIT_AM_SKIP; +-#endif +- + #define DO_TEST_BASIC(f, d, ...) \ + do { \ + const char * const m[] = {__VA_ARGS__, NULL }; \ +diff -urNpa libvirt-4.6.0.orig/tests/virmacmaptestdata/empty.json libvirt-4.6.0/tests/virmacmaptestdata/empty.json +--- libvirt-4.6.0.orig/tests/virmacmaptestdata/empty.json 2018-07-28 13:26:44.505462692 +0000 ++++ libvirt-4.6.0/tests/virmacmaptestdata/empty.json 2018-08-20 18:00:20.578398013 +0000 +@@ -1 +1,3 @@ +-[] ++[ ++ ++] +diff -urNpa libvirt-4.6.0.orig/tests/virmocklibxl.c libvirt-4.6.0/tests/virmocklibxl.c +--- libvirt-4.6.0.orig/tests/virmocklibxl.c 2018-07-28 13:26:44.505462692 +0000 ++++ libvirt-4.6.0/tests/virmocklibxl.c 2018-08-20 18:00:20.578398013 +0000 +@@ -22,7 +22,7 @@ + + #include + +-#if defined(WITH_LIBXL) && defined(WITH_JANSSON) ++#if defined(WITH_LIBXL) && defined(WITH_YAJL) + # include "virmock.h" + # include + # include +@@ -136,4 +136,4 @@ VIR_MOCK_IMPL_RET_ARGS(stat, int, + return real_stat(path, sb); + } + +-#endif /* WITH_LIBXL && WITH_JANSSON */ ++#endif /* WITH_LIBXL && WITH_YAJL */ +diff -urNpa libvirt-4.6.0.orig/tests/virnetdaemontest.c libvirt-4.6.0/tests/virnetdaemontest.c +--- libvirt-4.6.0.orig/tests/virnetdaemontest.c 2018-07-28 13:26:44.506462683 +0000 ++++ libvirt-4.6.0/tests/virnetdaemontest.c 2018-08-20 18:00:20.578398013 +0000 +@@ -26,7 +26,7 @@ + + #define VIR_FROM_THIS VIR_FROM_RPC + +-#if defined(HAVE_SOCKETPAIR) && defined(WITH_JANSSON) ++#if defined(HAVE_SOCKETPAIR) && defined(WITH_YAJL) + struct testClientPriv { + int magic; + }; +@@ -375,11 +375,6 @@ mymain(void) + int ret = 0; + const char *server_names[] = { "testServer0", "testServer1" }; + +-# if !WITH_STABLE_ORDERING_JANSSON +- fputs("libvirt not compiled with recent enough Jansson, skipping this test\n", stderr); +- return EXIT_AM_SKIP; +-# endif +- + if (virInitialize() < 0 || + virEventRegisterDefaultImpl() < 0) { + virDispatchError(NULL); +diff -urNpa libvirt-4.6.0.orig/tests/virstoragetest.c libvirt-4.6.0/tests/virstoragetest.c +--- libvirt-4.6.0.orig/tests/virstoragetest.c 2018-07-28 13:26:44.506462683 +0000 ++++ libvirt-4.6.0/tests/virstoragetest.c 2018-08-20 18:00:20.578398013 +0000 +@@ -1317,7 +1317,7 @@ mymain(void) + " \n" + "\n"); + +-#ifdef WITH_JANSSON ++#ifdef WITH_YAJL + TEST_BACKING_PARSE("json:", NULL); + TEST_BACKING_PARSE("json:asdgsdfg", NULL); + TEST_BACKING_PARSE("json:{}", NULL); +@@ -1581,7 +1581,7 @@ mymain(void) + "\n" + " \n" + "\n"); +-#endif /* WITH_JANSSON */ ++#endif /* WITH_YAJL */ + + cleanup: + /* Final cleanup */