From: Martin Vidner Date: Wed, 11 Dec 2019 13:54:58 +0000 (+0100) Subject: Using json-c instead of rapidjson X-Git-Tag: v0.8.7^2~8 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=0a31e0465163eaf3e1a6380ee10f1747cc8618bb;p=thirdparty%2Fsnapper.git Using json-c instead of rapidjson https://github.com/json-c/json-c Already in SLE, is also a dependency for systemd via libcryptsetup. --- diff --git a/Dockerfile.debian b/Dockerfile.debian index 8e6a89bd..2ec22930 100644 --- a/Dockerfile.debian +++ b/Dockerfile.debian @@ -21,13 +21,13 @@ RUN apt-get update && \ libboost-test-dev \ libboost-thread-dev \ libdbus-1-dev \ + libjson-c-dev \ libmount-dev \ libpam-dev \ libtool \ libxml2-dev \ libz-dev \ locales-all \ - rapidjson-dev \ ruby-dbus \ xsltproc diff --git a/Dockerfile.fedora b/Dockerfile.fedora index ab56e3e7..5bbe3211 100644 --- a/Dockerfile.fedora +++ b/Dockerfile.fedora @@ -12,6 +12,7 @@ RUN dnf -y install \ gettext \ glibc-langpack-de \ glibc-langpack-en \ + json-c-devel \ libacl-devel \ libmount-devel \ libtool \ @@ -20,7 +21,6 @@ RUN dnf -y install \ make \ pam-devel \ pkgconfig \ - rapidjson-devel \ rpm-build RUN mkdir -p /usr/src/app diff --git a/Dockerfile.leap b/Dockerfile.leap index 5596a63d..76f0f5d8 100644 --- a/Dockerfile.leap +++ b/Dockerfile.leap @@ -22,13 +22,13 @@ RUN RUBY_VERSION=ruby:`rpm --eval '%{rb_ver}'` && \ libboost_test-devel \ libboost_thread-devel \ libbtrfs-devel \ + libjson-c-devel \ libmount-devel \ libtool \ libxml2-devel \ libxslt \ obs-service-source_validator \ pam-devel \ - rapidjson-devel \ rpm-build \ "rubygem($RUBY_VERSION:ruby-dbus)" \ which diff --git a/Dockerfile.tumbleweed b/Dockerfile.tumbleweed index 187ab754..ea4cf4f6 100644 --- a/Dockerfile.tumbleweed +++ b/Dockerfile.tumbleweed @@ -22,13 +22,13 @@ RUN RUBY_VERSION=ruby:`rpm --eval '%{rb_ver}'` && \ libboost_test-devel \ libboost_thread-devel \ libbtrfs-devel \ + libjson-c-devel \ libmount-devel \ libtool \ libxml2-devel \ libxslt \ obs-service-source_validator \ pam-devel \ - rapidjson-devel \ rpm-build \ "rubygem($RUBY_VERSION:ruby-dbus)" \ which diff --git a/Dockerfile.ubuntu b/Dockerfile.ubuntu index 0cc6bdee..7f566f31 100644 --- a/Dockerfile.ubuntu +++ b/Dockerfile.ubuntu @@ -23,12 +23,12 @@ RUN apt-get update && \ libboost-test-dev \ libboost-thread-dev \ libdbus-1-dev \ + libjson-c-dev \ libmount-dev \ libpam-dev \ libtool \ libxml2-dev \ libz-dev \ - rapidjson-dev \ ruby-dbus \ xsltproc diff --git a/configure.ac b/configure.ac index 4379a766..0558ce42 100644 --- a/configure.ac +++ b/configure.ac @@ -148,6 +148,9 @@ fi PKG_CHECK_MODULES(DBUS, dbus-1) PKG_CHECK_MODULES(XML2, libxml-2.0) +if test "x$with_zypp" = "xyes"; then + PKG_CHECK_MODULES(JSONC, json-c) +fi AC_CHECK_HEADER(acl/libacl.h,[],[AC_MSG_ERROR([Cannout find libacl headers. Please install libacl-devel])]) diff --git a/snapper.spec.in b/snapper.spec.in index 553e5ded..dcdae402 100644 --- a/snapper.spec.in +++ b/snapper.spec.in @@ -72,7 +72,11 @@ BuildRequires: xsltproc BuildRequires: libzypp(plugin:commit) %endif BuildRequires: pam-devel -BuildRequires: rapidjson-devel +%if 0%{?fedora_version} +BuildRequires: json-c-devel +%else +BuildRequires: libjson-c-devel +%endif Requires: diffutils Requires: libsnapper@LIBVERSION_MAJOR@ = %version %if 0%{?suse_version} diff --git a/zypp-plugin/Makefile.am b/zypp-plugin/Makefile.am index 65687334..7ce5339c 100644 --- a/zypp-plugin/Makefile.am +++ b/zypp-plugin/Makefile.am @@ -5,7 +5,7 @@ if HAVE_ZYPP plugindir = /usr/lib/zypp/plugins/commit plugin_PROGRAMS = snapper-zypp-plugin -AM_CPPFLAGS = $(DBUS_CFLAGS) $(XML2_CFLAGS) +AM_CPPFLAGS = $(DBUS_CFLAGS) $(XML2_CFLAGS) $(JSONC_CFLAGS) AM_CXXFLAGS = -Wsuggest-override snapper_zypp_plugin_SOURCES = \ snapper_zypp_plugin.cc \ @@ -15,6 +15,7 @@ snapper_zypp_plugin_LDFLAGS = \ ../client/libclient.la \ ../snapper/libsnapper.la \ ../dbus/libdbus.la \ + $(JSONC_LIBS) \ -lboost_regex endif diff --git a/zypp-plugin/snapper_zypp_plugin.cc b/zypp-plugin/snapper_zypp_plugin.cc index 28aa2789..9f27a901 100644 --- a/zypp-plugin/snapper_zypp_plugin.cc +++ b/zypp-plugin/snapper_zypp_plugin.cc @@ -15,7 +15,11 @@ #include using namespace std; -#include +#include +// a collision with client/errors.h +#ifdef error_description +#undef error_description +#endif #include "dbus/DBusConnection.h" #include "snapper/Exception.h" @@ -315,29 +319,64 @@ map SnapperZyppPlugin::get_userdata(const Message& msg) { return result; } +static +json_object * object_get(json_object * obj, const char * name) { + json_object * result; + if (!json_object_object_get_ex(obj, name, &result)) { + cerr << "ERROR:" << '"' << name << "\" not found" << endl; + return NULL; + } + return result; +} + set SnapperZyppPlugin::get_solvables(const Message& msg, Phase phase) { set result; - rapidjson::Document doc; - const char * c_body = msg.body.c_str(); - cerr << "DEBUG:" << "parsing zypp JSON: " << c_body << endl; - if (doc.Parse(c_body).HasParseError()) { - cerr << "ERROR:" << "parsing zypp JSON failed" << endl; + json_tokener * tok = json_tokener_new(); + json_object * zypp = json_tokener_parse_ex(tok, msg.body.c_str(), msg.body.size()); + json_tokener_error jerr = json_tokener_get_error(tok); + if (jerr != json_tokener_success) { + cerr << "ERROR:" << "parsing zypp JSON failed: " + << json_tokener_error_desc(jerr) << endl; return result; } + + // JSON structure: + // {"TransactionStepList":[{"type":"?","stage":"?","solvable":{"n":"mypackage"}}]} // https://doc.opensuse.org/projects/libzypp/SLE12SP2/plugin-commit.html - using rapidjson::Value; - const Value& steps = doc["TransactionStepList"]; - for (Value::ConstValueIterator it = steps.Begin(); it != steps.End(); ++it) { - const Value& step = *it; - if (step.HasMember("type")) { - if (phase == Phase::BEFORE || step.HasMember("stage")) { - const Value& solvable = step["solvable"]; - const Value& name = solvable["n"]; - // FIXME: what happens when the doc structure is different? - result.insert(name.GetString()); - } - } + json_object * steps = object_get(zypp, "TransactionStepList"); + if (!steps) + return result; + + if (json_object_get_type(steps) == json_type_array) { + size_t i, len = json_object_array_length(steps); + printf("steps: %zu\n", len); + for (i = 0; i < len; ++i) { + json_object * step = json_object_array_get_idx(steps, i); + bool have_type = json_object_object_get_ex(step, "type", NULL); + bool have_stage = json_object_object_get_ex(step, "stage", NULL); + if (have_type && (phase == Phase::BEFORE || have_stage)) { + json_object * solvable = object_get(step, "solvable"); + if (!solvable) { + cerr << "ERROR:" << "in item #" << i << endl; + continue; + } + json_object * name = object_get(solvable, "n"); + if (!name) { + cerr << "ERROR:" << "in item #" << i << endl; + continue; + } + if (json_object_get_type(name) != json_type_string) { + cerr << "ERROR:" << "\"n\" is not a string" << endl; + cerr << "ERROR:" << "in item #" << i << endl; + continue; + } + else { + const char * prize = json_object_get_string(name); + result.insert(prize); + } + } + } } return result; diff --git a/zypp-plugin/testsuite/4-badjson.test b/zypp-plugin/testsuite/4-badjson.test index 71333e8c..78744e90 100755 --- a/zypp-plugin/testsuite/4-badjson.test +++ b/zypp-plugin/testsuite/4-badjson.test @@ -5,10 +5,8 @@ set -u . test-helper.sh -mock_snapperd_setup || { echo "1..0 # SKIP"; exit; } - # http://testanything.org/ -echo 1..1 +echo 1..2 test_bad_json() { local JSON=("${1?JSON payload expected}") @@ -19,10 +17,18 @@ test_bad_json() { stomp_message PLUGINEND "" "" } -TEST="1 - It complains about bad JSON" +TEST="1 - It complains about malformed JSON" +STDERR=$(test_bad_json '{ malformed.1415926 ]' | runit "" 2>&1 >/dev/null || :) +echo "$STDERR" +if [[ ! "$STDERR" =~ parsing.*JSON.failed ]]; then + echo -n "not " +fi +echo "ok $TEST" + +TEST="2 - It complains about invalid JSON" STDERR=$(test_bad_json '{"well-formed": "but-invalid"}' | runit "" 2>&1 >/dev/null || :) echo "$STDERR" -if [[ ! "$STDERR" =~ rapidjson.*Assertion.*failed ]]; then +if [[ ! "$STDERR" =~ TransactionStepList.*not.found ]]; then echo -n "not " fi echo "ok $TEST"