--- /dev/null
+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 <http://www.gnu.org/licenses/>.
+ 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 <http://www.gnu.org/licenses/>.
+-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 <yajl/yajl_gen.h>
++# include <yajl/yajl_parse.h>
++
++# 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
+- * <http://www.gnu.org/licenses/>.
+- *
+- */
+-
+-#include <config.h>
+-
+-#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 <dlfcn.h>
+-
+-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
+- * <http://www.gnu.org/licenses/>.
+- *
+- */
+-
+-
+-#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 <jansson.h>
+-
+-# 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 <config.h>
+
+-#if defined(WITH_LIBXL) && defined(WITH_JANSSON)
++#if defined(WITH_LIBXL) && defined(WITH_YAJL)
+ # include "virmock.h"
+ # include <sys/stat.h>
+ # include <unistd.h>
+@@ -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)
+ " <host name='example.org' port='6000'/>\n"
+ "</source>\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)
+ "<source protocol='vxhs' name='c6718f6b-0401-441d-a8c3-1f0064d75ee0'>\n"
+ " <host name='example.com' port='9999'/>\n"
+ "</source>\n");
+-#endif /* WITH_JANSSON */
++#endif /* WITH_YAJL */
+
+ cleanup:
+ /* Final cleanup */