From: Corey Farrell Date: Mon, 16 Jul 2018 20:08:20 +0000 (-0400) Subject: Enable bundling of jansson. X-Git-Tag: 15.6.0-rc1~58^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8cc8c0178d157adf0c1feb6cedbd86004cdfcee3;p=thirdparty%2Fasterisk.git Enable bundling of jansson. Change-Id: Ib3111b151d37cbda40768cf2a8a9c6cf6c5c7cbd --- diff --git a/configure b/configure index bde00f8b4b..8c7e9a7252 100755 --- a/configure +++ b/configure @@ -1082,10 +1082,7 @@ PBX_URIPARSER URIPARSER_DIR URIPARSER_INCLUDE URIPARSER_LIB -PBX_JANSSON JANSSON_DIR -JANSSON_INCLUDE -JANSSON_LIB PBX_JACK JACK_DIR JACK_INCLUDE @@ -1200,6 +1197,11 @@ PBX_PJPROJECT PJPROJECT_DIR PJPROJECT_BUNDLED PJPROJECT_CONFIGURE_OPTS +JANSSON_INCLUDE +JANSSON_LIB +PBX_JANSSON +JANSSON_BUNDLED +JANSSON_CONFIGURE_OPTS AST_C_COMPILER_FAMILY AST_CLANG_BLOCKS AST_CLANG_BLOCKS_LIBS @@ -1366,6 +1368,7 @@ with_download_cache with_sounds_cache with_externals_cache enable_coverage +with_jansson_bundled with_pjproject_bundled with_asound with_bfd @@ -1465,6 +1468,7 @@ CXX CXXFLAGS CCC CXXCPP +JANSSON_CONFIGURE_OPTS PJPROJECT_CONFIGURE_OPTS PKG_CONFIG PKG_CONFIG_PATH @@ -2117,6 +2121,7 @@ Optional Packages: use cached sound tarfiles in PATH --with-externals-cache=PATH use cached external module tarfiles in PATH + --with-jansson-bundled Use bundled jansson library --with-pjproject-bundled Use bundled pjproject libraries (default) --with-asound=PATH use Advanced Linux Sound Architecture files in PATH @@ -2216,6 +2221,8 @@ Some influential environment variables: CXX C++ compiler command CXXFLAGS C++ compiler flags CXXCPP C++ preprocessor + JANSSON_CONFIGURE_OPTS + Additional configure options to pass to bundled jansson PJPROJECT_CONFIGURE_OPTS Additional configure options to pass to bundled pjproject PKG_CONFIG path to pkg-config utility @@ -9166,6 +9173,17 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="$save_CFLAGS" +JANSSON_BUNDLED=no + +# Check whether --with-jansson-bundled was given. +if test "${with_jansson_bundled+set}" = set; then : + withval=$with_jansson_bundled; case "${withval}" in + y|yes) JANSSON_BUNDLED=yes ;; + *) JANSSON_BUNDLED=no ;; + esac +fi + + PJPROJECT_BUNDLED=yes @@ -9181,6 +9199,92 @@ fi + if test "$JANSSON_BUNDLED" = "yes" ; then + + if test "${ac_mandatory_list#*JANSSON*}" != "$ac_mandatory_list" ; then + as_fn_error $? "--with-jansson and --with-jansson-bundled can't both be specified" "$LINENO" 5 + fi + + ac_mandatory_list="$ac_mandatory_list JANSSON" + JANSSON_DIR="${ac_pwd}/third-party/jansson" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for embedded jansson (may have to download)" >&5 +$as_echo_n "checking for embedded jansson (may have to download)... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: configuring" >&5 +$as_echo "configuring" >&6; } + + if test "x${DOWNLOAD_TO_STDOUT}" = "x" ; then + as_fn_error $? "A download utility (wget, curl, or fetch) is required to download bundled jansson" "$LINENO" 5 + fi + if test "${BZIP2}" = ":" ; then + as_fn_error $? "bzip2 is required to extract the jansson tar file" "$LINENO" 5 + fi + if test "${TAR}" = ":" ; then + as_fn_error $? "tar is required to extract the jansson tar file" "$LINENO" 5 + fi + if test "${PATCH}" = ":" ; then + as_fn_error $? "patch is required to configure bundled jansson" "$LINENO" 5 + fi + if test "${SED}" = ":" ; then + as_fn_error $? "sed is required to configure bundled jansson" "$LINENO" 5 + fi + if test "${NM}" = ":" ; then + as_fn_error $? "nm is required to build bundled jansson" "$LINENO" 5 + fi + if test "${MD5}" = ":" ; then + as_fn_error $? "md5sum is required to build bundled jansson" "$LINENO" 5 + fi + if test "${CAT}" = ":" ; then + as_fn_error $? "cat is required to build bundled jansson" "$LINENO" 5 + fi + if test "${CUT}" = ":" ; then + as_fn_error $? "cut is required to build bundled jansson" "$LINENO" 5 + fi + if test "${GREP}" = ":" ; then + as_fn_error $? "grep is required to build bundled jansson" "$LINENO" 5 + fi + + + this_host=$(./config.sub $(./config.guess)) + if test "$build" != "$this_host" ; then + JANSSON_CONFIGURE_OPTS+=" --build=$build" + fi + if test "$host" != "$this_host" ; then + JANSSON_CONFIGURE_OPTS+=" --host=$host" + fi + + export TAR PATCH SED NM EXTERNALS_CACHE_DIR AST_DOWNLOAD_CACHE DOWNLOAD_TO_STDOUT DOWNLOAD_TIMEOUT DOWNLOAD MD5 CAT CUT GREP + export NOISY_BUILD + ${GNU_MAKE} --quiet --no-print-directory -C ${JANSSON_DIR} \ + JANSSON_CONFIGURE_OPTS="$JANSSON_CONFIGURE_OPTS" \ + EXTERNALS_CACHE_DIR="${EXTERNALS_CACHE_DIR:-${AST_DOWNLOAD_CACHE}}" \ + configure + if test $? -ne 0 ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: Unable to configure ${JANSSON_DIR}" >&5 +$as_echo "$as_me: Unable to configure ${JANSSON_DIR}" >&6;} + as_fn_error $? "Re-run the ./configure command with 'NOISY_BUILD=yes' appended to see error details." "$LINENO" 5 + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for bundled jansson" >&5 +$as_echo_n "checking for bundled jansson... " >&6; } + + JANSSON_INCLUDE=-I${JANSSON_DIR}/dest/include + JANSSON_CFLAGS="$JANSSON_INCLUDE" + JANSSON_LIB="-L${JANSSON_DIR}/dest/lib -ljansson" + PBX_JANSSON=1 + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + + fi + + if test "$PJPROJECT_BUNDLED" = "yes" ; then if test "${ac_mandatory_list#*PJPROJECT*}" != "$ac_mandatory_list" ; then @@ -14346,7 +14450,8 @@ fi -# Find required JSON support. +# Find required JSON support if bundled is not enabled. +if test "$JANSSON_BUNDLED" = "no" ; then if test "x${PBX_JANSSON}" != "x1" -a "${USE_JANSSON}" != "no"; then pbxlibdir="" @@ -14444,8 +14549,17 @@ fi -if test "${PBX_JANSSON}" != 1; then - as_fn_error $? "*** JSON support not found (this typically means the libjansson development package is missing)" "$LINENO" 5 + if test "${PBX_JANSSON}" != 1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: *** Asterisk requires libjansson and no system copy was found." >&5 +$as_echo "$as_me: *** Asterisk requires libjansson and no system copy was found." >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: *** Please install the 'libjansson' development package or" >&5 +$as_echo "$as_me: *** Please install the 'libjansson' development package or" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: *** use './configure --with-jansson-bundled'" >&5 +$as_echo "$as_me: *** use './configure --with-jansson-bundled'" >&6;} + exit 1 + fi +else + PBX_JANSSON=1 fi # See if clock_gettime is in librt diff --git a/configure.ac b/configure.ac index 3a01d5ab2d..408801977a 100644 --- a/configure.ac +++ b/configure.ac @@ -423,6 +423,15 @@ AC_SUBST(AST_CODE_COVERAGE) AST_CHECK_RAII() AST_CHECK_STRSEP_ARRAY_BOUNDS() +JANSSON_BUNDLED=no +AC_ARG_WITH([jansson-bundled], + [AS_HELP_STRING([--with-jansson-bundled], + [Use bundled jansson library])], + [case "${withval}" in + y|yes) JANSSON_BUNDLED=yes ;; + *) JANSSON_BUNDLED=no ;; + esac]) + PJPROJECT_BUNDLED=yes AH_TEMPLATE(m4_bpatsubst([[HAVE_PJPROJECT_BUNDLED]], [(.*)]), [Define to 1 when using the bundled pjproject.]) @@ -699,11 +708,18 @@ fi AC_SUBST(UUID_INCLUDE) AC_SUBST(UUID_LIB) -# Find required JSON support. -AST_EXT_LIB_CHECK([JANSSON], [jansson], [json_dumps], [jansson.h]) +# Find required JSON support if bundled is not enabled. +if test "$JANSSON_BUNDLED" = "no" ; then + AST_EXT_LIB_CHECK([JANSSON], [jansson], [json_dumps], [jansson.h]) -if test "${PBX_JANSSON}" != 1; then - AC_MSG_ERROR([*** JSON support not found (this typically means the libjansson development package is missing)]) + if test "${PBX_JANSSON}" != 1; then + AC_MSG_NOTICE(*** Asterisk requires libjansson and no system copy was found.) + AC_MSG_NOTICE(*** Please install the 'libjansson' development package or) + AC_MSG_NOTICE(*** use './configure --with-jansson-bundled') + exit 1 + fi +else + PBX_JANSSON=1 fi # See if clock_gettime is in librt diff --git a/makeopts.in b/makeopts.in index 44c281043e..cce8392c25 100644 --- a/makeopts.in +++ b/makeopts.in @@ -189,6 +189,7 @@ IODBC_LIB=@IODBC_LIB@ JACK_INCLUDE=@JACK_INCLUDE@ JACK_LIB=@JACK_LIB@ +JANSSON_BUNDLED=@JANSSON_BUNDLED@ JANSSON_INCLUDE=@JANSSON_INCLUDE@ JANSSON_LIB=@JANSSON_LIB@ diff --git a/third-party/Makefile b/third-party/Makefile index 3ea84d1055..7b2afdac32 100644 --- a/third-party/Makefile +++ b/third-party/Makefile @@ -1,10 +1,10 @@ include Makefile.rules -TP_SUBDIRS := pjproject +TP_SUBDIRS := pjproject jansson # Sub directories that contain special install/uninstall targets must be explicitly listed # to prevent accidentally running the package's default install target. -TP_INSTALL_SUBDIRS := pjproject +TP_INSTALL_SUBDIRS := pjproject jansson .PHONY: all dist-clean distclean install clean moduleinfo makeopts uninstall $(TP_SUBDIRS) diff --git a/third-party/Makefile.rules b/third-party/Makefile.rules index 8306869f9f..f02ddb1f82 100644 --- a/third-party/Makefile.rules +++ b/third-party/Makefile.rules @@ -33,3 +33,25 @@ export GREP export DOWNLOAD export DOWNLOAD_TO_STDOUT export DOWNLOAD_TIMEOUT + +DOWNLOAD_DIR := $(or $(EXTERNALS_CACHE_DIR),$(TMPDIR),$(wildcard /tmp),.) + +# These depend on the subpackage defining TARBALL_FILE. +TARBALL_EXISTS = test -f $(DOWNLOAD_DIR)/$(TARBALL_FILE) -a -f $(TARBALL_MD5) + +define TARBALL_VERIFY + ($(SHELL_ECHO_PREFIX) Verifying $(DOWNLOAD_DIR)/$(TARBALL_FILE) &&\ + tarball_sum=$$($(CAT) $(DOWNLOAD_DIR)/$(TARBALL_FILE) | $(MD5) | $(CUT) -d' ' -f1) ;\ + required_sum=$$($(GREP) -e $(TARBALL_FILE) $(TARBALL_MD5) | $(CUT) -d' ' -f1) ;\ + if [ -z "$$required_sum" -o "$$tarball_sum" != "$$required_sum" ] ; then $(SHELL_ECHO_PREFIX) Verify failed ; exit 1 ;\ + else $(SHELL_ECHO_PREFIX) Verify successful ; exit 0 ; fi; ) +endef + +define TARBALL_DOWNLOAD + ($(SHELL_ECHO_PREFIX) Downloading $(TARBALL_URL) to $(DOWNLOAD_DIR)/$(TARBALL_FILE) ;\ + $(DOWNLOAD_TO_STDOUT) $(call DOWNLOAD_TIMEOUT,5,60) $(TARBALL_URL) > $(DOWNLOAD_DIR)/$(TARBALL_FILE) &&\ + $(TARBALL_VERIFY)) +endef + +TARBALL_URL = $(PACKAGE_URL)/$(TARBALL_FILE) +TARBALL_MD5 = $(TARBALL_FILE).md5 diff --git a/third-party/pjproject/apply_patches b/third-party/apply_patches similarity index 100% rename from third-party/pjproject/apply_patches rename to third-party/apply_patches diff --git a/third-party/configure.m4 b/third-party/configure.m4 index 6367722d07..fa4736d15b 100644 --- a/third-party/configure.m4 +++ b/third-party/configure.m4 @@ -5,5 +5,6 @@ AC_DEFUN([THIRD_PARTY_CONFIGURE], [ + JANSSON_CONFIGURE() PJPROJECT_CONFIGURE() ]) diff --git a/third-party/jansson/.gitignore b/third-party/jansson/.gitignore new file mode 100644 index 0000000000..b7bfd2b878 --- /dev/null +++ b/third-party/jansson/.gitignore @@ -0,0 +1,4 @@ +source/ +dest/ +**.bz2 +.rebuild_needed diff --git a/third-party/jansson/Makefile b/third-party/jansson/Makefile new file mode 100644 index 0000000000..a85efa0c6b --- /dev/null +++ b/third-party/jansson/Makefile @@ -0,0 +1,99 @@ +.PHONY: _all all _install install clean distclean configure + +.NOTPARALLEL: + +include ../versions.mak +export JANSSON_DIR := $(shell pwd -P) + +SPECIAL_TARGETS := + +ifneq ($(findstring configure,$(MAKECMDGOALS)),) +# Run from $(ASTTOPDIR)/configure + SPECIAL_TARGETS += configure +endif + +ifeq ($(findstring clean,$(MAKECMDGOALS)),clean) +# clean or distclean + SPECIAL_TARGETS += clean +endif + +ifeq ($(findstring uninstall,$(MAKECMDGOALS)),uninstall) + SPECIAL_TARGETS += uninstall +endif + + +ifneq ($(wildcard ../../makeopts),) + include ../../makeopts +endif + +ifeq ($(SPECIAL_TARGETS),) +# Run locally or from $(ASTTOPDIR)/Makefile. All include files should be present + ifeq ($(wildcard ../../makeopts),) + $(error ASTTOPDIR/configure hasn't been run) + endif + + ifeq ($(JANSSON_BUNDLED),yes) + ifneq ($(wildcard ../../menuselect.makeopts),) + include ../../menuselect.makeopts + else + $(warning ASTTOPDIR/menuselect hasn't been run yet. Can't find debug options.) + endif + + all: _all + install: _install + else + all install: + endif +endif + +include ../../Makefile.rules +include ../Makefile.rules +include Makefile.rules + +ECHO_PREFIX := $(ECHO_PREFIX) echo '[jansson] ' +SHELL_ECHO_PREFIX := echo '[jansson] ' + +_all: source/config.status + $(ECHO_PREFIX) Building bundled jansson. + $(CMD_PREFIX) (cd source; make) + $(CMD_PREFIX) (cd source; make install) + +.DELETE_ON_ERROR: + +$(DOWNLOAD_DIR)/$(TARBALL_FILE): ../versions.mak + $(CMD_PREFIX) ($(TARBALL_EXISTS) && $(TARBALL_VERIFY) && touch $@) || (rm -rf $@ ;\ + $(TARBALL_DOWNLOAD)) || (rm -rf $@ ;\ + $(SHELL_ECHO_PREFIX) Retrying download ; $(TARBALL_DOWNLOAD)) + +source/.unpacked: $(DOWNLOAD_DIR)/$(TARBALL_FILE) + $(CMD_PREFIX) $(TARBALL_VERIFY) || (rm -rf $@ ;\ + $(SHELL_ECHO_PREFIX) Retrying download ; $(TARBALL_DOWNLOAD)) + $(ECHO_PREFIX) Unpacking $< + -@rm -rf source jansson-*/ >/dev/null 2>&1 + $(CMD_PREFIX) $(TAR) -xjf $< + @mv jansson-$(JANSSON_VERSION) source + $(ECHO_PREFIX) Applying patches "$(realpath patches)" "$(realpath .)/source" + $(CMD_PREFIX) ../apply_patches $(QUIET_CONFIGURE) "$(realpath patches)" "$(realpath .)/source" + -@touch source/.unpacked + +.rebuild_needed: $(wildcard ../../.lastclean) + $(ECHO_PREFIX) Rebuilding + $(CMD_PREFIX) $(MAKE) clean $(REALLY_QUIET) + +source/config.status: source/.unpacked Makefile.rules .rebuild_needed + $(ECHO_PREFIX) Configuring + $(CMD_PREFIX) (cd source ; ./configure $(QUIET_CONFIGURE) $(JANSSON_CONFIG_OPTS) --disable-shared --enable-static --prefix=$(JANSSON_DIR)/dest) + +configure: source/config.status + +_install: _all + +uninstall: + +clean: + $(ECHO_PREFIX) Cleaning + +-$(CMD_PREFIX) test -d source dest && $(SUBMAKE) -C source clean || : + +distclean: + $(ECHO_PREFIX) Distcleaning + -$(CMD_PREFIX) rm -rf source jansson-*.tar.bz2 .rebuild_needed diff --git a/third-party/jansson/Makefile.rules b/third-party/jansson/Makefile.rules new file mode 100644 index 0000000000..39112eb511 --- /dev/null +++ b/third-party/jansson/Makefile.rules @@ -0,0 +1,16 @@ +# We switched download locations so Asterisk users don't bombard the Digip +# site with download requests. +# +# For future reference when upgrading bundled JANSSON the next time +# JANSSON is released. +# Digip's download URL. +# PACKAGE_URL ?= http://www.digip.org/jansson/releases/ + +PACKAGE_URL ?= https://raw.githubusercontent.com/asterisk/third-party/master/jansson/$(JANSSON_VERSION) +TARBALL_FILE = jansson-$(JANSSON_VERSION).tar.bz2 + +# JANSSON_CONFIGURE_OPTS could come from the command line or could be +# set/modified by configure.m4 if the build or host tuples aren't the same +# as the current build environment (cross-compile). + +JANSSON_CONFIG_OPTS = $(JANSSON_CONFIGURE_OPTS) diff --git a/third-party/jansson/configure.m4 b/third-party/jansson/configure.m4 new file mode 100644 index 0000000000..d59d861257 --- /dev/null +++ b/third-party/jansson/configure.m4 @@ -0,0 +1,89 @@ +# +# If this file is changed, be sure to run ASTTOPDIR/bootstrap.sh +# before committing. +# + +AC_DEFUN([_JANSSON_CONFIGURE], +[ + if test "${ac_mandatory_list#*JANSSON*}" != "$ac_mandatory_list" ; then + AC_MSG_ERROR(--with-jansson and --with-jansson-bundled can't both be specified) + fi + + ac_mandatory_list="$ac_mandatory_list JANSSON" + JANSSON_DIR="${ac_pwd}/third-party/jansson" + + AC_MSG_CHECKING(for embedded jansson (may have to download)) + AC_MSG_RESULT(configuring) + + if test "x${DOWNLOAD_TO_STDOUT}" = "x" ; then + AC_MSG_ERROR(A download utility (wget, curl, or fetch) is required to download bundled jansson) + fi + if test "${BZIP2}" = ":" ; then + AC_MSG_ERROR(bzip2 is required to extract the jansson tar file) + fi + if test "${TAR}" = ":" ; then + AC_MSG_ERROR(tar is required to extract the jansson tar file) + fi + if test "${PATCH}" = ":" ; then + AC_MSG_ERROR(patch is required to configure bundled jansson) + fi + if test "${SED}" = ":" ; then + AC_MSG_ERROR(sed is required to configure bundled jansson) + fi + if test "${NM}" = ":" ; then + AC_MSG_ERROR(nm is required to build bundled jansson) + fi + if test "${MD5}" = ":" ; then + AC_MSG_ERROR(md5sum is required to build bundled jansson) + fi + if test "${CAT}" = ":" ; then + AC_MSG_ERROR(cat is required to build bundled jansson) + fi + if test "${CUT}" = ":" ; then + AC_MSG_ERROR(cut is required to build bundled jansson) + fi + if test "${GREP}" = ":" ; then + AC_MSG_ERROR(grep is required to build bundled jansson) + fi + + AC_ARG_VAR([JANSSON_CONFIGURE_OPTS],[Additional configure options to pass to bundled jansson]) + this_host=$(./config.sub $(./config.guess)) + if test "$build" != "$this_host" ; then + JANSSON_CONFIGURE_OPTS+=" --build=$build" + fi + if test "$host" != "$this_host" ; then + JANSSON_CONFIGURE_OPTS+=" --host=$host" + fi + + export TAR PATCH SED NM EXTERNALS_CACHE_DIR AST_DOWNLOAD_CACHE DOWNLOAD_TO_STDOUT DOWNLOAD_TIMEOUT DOWNLOAD MD5 CAT CUT GREP + export NOISY_BUILD + ${GNU_MAKE} --quiet --no-print-directory -C ${JANSSON_DIR} \ + JANSSON_CONFIGURE_OPTS="$JANSSON_CONFIGURE_OPTS" \ + EXTERNALS_CACHE_DIR="${EXTERNALS_CACHE_DIR:-${AST_DOWNLOAD_CACHE}}" \ + configure + if test $? -ne 0 ; then + AC_MSG_RESULT(failed) + AC_MSG_NOTICE(Unable to configure ${JANSSON_DIR}) + AC_MSG_ERROR(Re-run the ./configure command with 'NOISY_BUILD=yes' appended to see error details.) + fi + + AC_MSG_CHECKING(for bundled jansson) + + JANSSON_INCLUDE=-I${JANSSON_DIR}/dest/include + JANSSON_CFLAGS="$JANSSON_INCLUDE" + JANSSON_LIB="-L${JANSSON_DIR}/dest/lib -ljansson" + PBX_JANSSON=1 + + AC_SUBST([JANSSON_BUNDLED]) + AC_SUBST([PBX_JANSSON]) + AC_SUBST([JANSSON_LIB]) + AC_SUBST([JANSSON_INCLUDE]) + AC_MSG_RESULT(yes) +]) + +AC_DEFUN([JANSSON_CONFIGURE], +[ + if test "$JANSSON_BUNDLED" = "yes" ; then + _JANSSON_CONFIGURE() + fi +]) diff --git a/third-party/jansson/jansson-2.11.tar.bz2.md5 b/third-party/jansson/jansson-2.11.tar.bz2.md5 new file mode 100644 index 0000000000..db4326ce0c --- /dev/null +++ b/third-party/jansson/jansson-2.11.tar.bz2.md5 @@ -0,0 +1 @@ +289ca8cbd2df31de9bda7e5220754d25 jansson-2.11.tar.bz2 diff --git a/third-party/jansson/patches/0001-Improve-test-coverage.patch b/third-party/jansson/patches/0001-Improve-test-coverage.patch new file mode 100644 index 0000000000..226c404163 --- /dev/null +++ b/third-party/jansson/patches/0001-Improve-test-coverage.patch @@ -0,0 +1,128 @@ +From 73c22de51672cb40fdc29c95331923d4dcebb6fa Mon Sep 17 00:00:00 2001 +From: Corey Farrell +Date: Tue, 13 Feb 2018 04:35:37 -0500 +Subject: [PATCH 01/22] Improve test coverage. + +Changes to test/ removed for bundled use in Asterisk. + +* Test equality of different length strings. +* Add tab to json_pack whitespace test. +* Test json_sprintf with empty result and invalid UTF. +* Test json_get_alloc_funcs with NULL arguments. +* Test invalid arguments. +* Add test_chaos to test allocation failure code paths. +* Remove redundant json_is_string checks from json_string_equal and + json_string_copy. Both functions are static and can only be called + with a json string. + +Fixes to issues found by test_chaos: +* Fix crash on OOM in pack_unpack.c:read_string(). +* Unconditionally free string in string_create upon allocation failure. + Update load.c:parse_value() to reflect this. This resolves a leak on + allocation failure for pack_unpack.c:pack_string() and + value.c:json_sprintf(). + +Although not visible from CodeCoverage these changes significantly +increase branch coverage. Especially in src/value.c where we previously +covered 67.4% of branches and now cover 96.3% of branches. +--- + CMakeLists.txt | 1 + + src/load.c | 6 +- + src/pack_unpack.c | 5 +- + src/value.c | 9 +- + test/.gitignore | 1 + + test/suites/api/Makefile.am | 2 + + test/suites/api/test_array.c | 73 +++++++++++++++++ + test/suites/api/test_chaos.c | 115 ++++++++++++++++++++++++++ + test/suites/api/test_equal.c | 7 ++ + test/suites/api/test_memory_funcs.c | 7 ++ + test/suites/api/test_number.c | 36 ++++++++ + test/suites/api/test_object.c | 122 ++++++++++++++++++++++++++++ + test/suites/api/test_pack.c | 10 ++- + test/suites/api/test_simple.c | 52 ++++++++++++ + test/suites/api/test_sprintf.c | 12 +++ + 15 files changed, 444 insertions(+), 14 deletions(-) + create mode 100644 test/suites/api/test_chaos.c + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 16cf552..2f6cfec 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -487,6 +487,7 @@ if (NOT JANSSON_WITHOUT_TESTS) + set(api_tests + test_array + test_copy ++ test_chaos + test_dump + test_dump_callback + test_equal +diff --git a/src/load.c b/src/load.c +index deb36f3..25efe2e 100644 +--- a/src/load.c ++++ b/src/load.c +@@ -829,10 +829,8 @@ static json_t *parse_value(lex_t *lex, size_t flags, json_error_t *error) + } + + json = jsonp_stringn_nocheck_own(value, len); +- if(json) { +- lex->value.string.val = NULL; +- lex->value.string.len = 0; +- } ++ lex->value.string.val = NULL; ++ lex->value.string.len = 0; + break; + } + +diff --git a/src/pack_unpack.c b/src/pack_unpack.c +index 153f64d..19dbf93 100644 +--- a/src/pack_unpack.c ++++ b/src/pack_unpack.c +@@ -159,7 +159,10 @@ static char *read_string(scanner_t *s, va_list *ap, + return (char *)str; + } + +- strbuffer_init(&strbuff); ++ if(strbuffer_init(&strbuff)) { ++ set_error(s, "", json_error_out_of_memory, "Out of memory"); ++ s->has_error = 1; ++ } + + while(1) { + str = va_arg(*ap, const char *); +diff --git a/src/value.c b/src/value.c +index b3b3141..29a978c 100644 +--- a/src/value.c ++++ b/src/value.c +@@ -652,8 +652,7 @@ static json_t *string_create(const char *value, size_t len, int own) + + string = jsonp_malloc(sizeof(json_string_t)); + if(!string) { +- if(!own) +- jsonp_free(v); ++ jsonp_free(v); + return NULL; + } + json_init(&string->json, JSON_STRING); +@@ -768,9 +767,6 @@ static int json_string_equal(const json_t *string1, const json_t *string2) + { + json_string_t *s1, *s2; + +- if(!json_is_string(string1) || !json_is_string(string2)) +- return 0; +- + s1 = json_to_string(string1); + s2 = json_to_string(string2); + return s1->length == s2->length && !memcmp(s1->value, s2->value, s1->length); +@@ -780,9 +776,6 @@ static json_t *json_string_copy(const json_t *string) + { + json_string_t *s; + +- if(!json_is_string(string)) +- return NULL; +- + s = json_to_string(string); + return json_stringn_nocheck(s->value, s->length); + } +-- +2.17.1 + diff --git a/third-party/jansson/patches/0017-Fix-error-handling-in-json_pack.patch b/third-party/jansson/patches/0017-Fix-error-handling-in-json_pack.patch new file mode 100644 index 0000000000..affa6c9dfe --- /dev/null +++ b/third-party/jansson/patches/0017-Fix-error-handling-in-json_pack.patch @@ -0,0 +1,103 @@ +From 15105b66b4df387037b670ac713584194ea10c2f Mon Sep 17 00:00:00 2001 +From: Maxim Zhukov +Date: Mon, 12 Mar 2018 17:39:04 +0300 +Subject: [PATCH 17/22] Fix error handling in json_pack + +Changes to test/ removed. + +Fixed a bug where the error message was not filled if an empty object +was passed to the json_pack. + +Fixes #271 +--- + src/pack_unpack.c | 64 ++++++++++++++++++------------------- + test/suites/api/test_pack.c | 8 +++++ + 2 files changed, 40 insertions(+), 32 deletions(-) + +diff --git a/src/pack_unpack.c b/src/pack_unpack.c +index 4026fd9..6461c06 100644 +--- a/src/pack_unpack.c ++++ b/src/pack_unpack.c +@@ -348,6 +348,36 @@ static json_t *pack_string(scanner_t *s, va_list *ap) + } + } + ++static json_t *pack_object_inter(scanner_t *s, va_list *ap, int need_incref) ++{ ++ json_t *json; ++ char ntoken; ++ ++ next_token(s); ++ ntoken = token(s); ++ ++ if (ntoken != '?') ++ prev_token(s); ++ ++ json = va_arg(*ap, json_t *); ++ ++ if (json) ++ return need_incref ? json_incref(json) : json; ++ ++ switch (ntoken) { ++ case '?': ++ return json_null(); ++ case '*': ++ return NULL; ++ default: ++ break; ++ } ++ ++ set_error(s, "", json_error_null_value, "NULL object key"); ++ s->has_error = 1; ++ return NULL; ++} ++ + static json_t *pack(scanner_t *s, va_list *ap) + { + switch(token(s)) { +@@ -376,40 +406,10 @@ static json_t *pack(scanner_t *s, va_list *ap) + return json_real(va_arg(*ap, double)); + + case 'O': /* a json_t object; increments refcount */ +- { +- int nullable; +- json_t *json; +- +- next_token(s); +- nullable = token(s) == '?'; +- if (!nullable) +- prev_token(s); +- +- json = va_arg(*ap, json_t *); +- if (!json && nullable) { +- return json_null(); +- } else { +- return json_incref(json); +- } +- } ++ return pack_object_inter(s, ap, 1); + + case 'o': /* a json_t object; doesn't increment refcount */ +- { +- int nullable; +- json_t *json; +- +- next_token(s); +- nullable = token(s) == '?'; +- if (!nullable) +- prev_token(s); +- +- json = va_arg(*ap, json_t *); +- if (!json && nullable) { +- return json_null(); +- } else { +- return json; +- } +- } ++ return pack_object_inter(s, ap, 0); + + default: + set_error(s, "", json_error_invalid_format, "Unexpected format character '%c'", +-- +2.17.1 + diff --git a/third-party/pjproject/Makefile b/third-party/pjproject/Makefile index dbd2a88646..c1548c992c 100644 --- a/third-party/pjproject/Makefile +++ b/third-party/pjproject/Makefile @@ -86,49 +86,22 @@ SHELL_ECHO_PREFIX := echo '[pjproject] ' _all: $(TARGETS) -define tarball_exists - (if [ -f $(TARBALL) -a -f $(PJMD5SUM) ] ; then exit 0 ;\ - else exit 1; fi; ) -endef - -define verify_tarball - ($(SHELL_ECHO_PREFIX) Verifying $(TARBALL) &&\ - tarball_sum=$$($(CAT) $(TARBALL) | $(MD5) | $(CUT) -d' ' -f1) ;\ - required_sum=$$($(GREP) -e $(TARBALL_FILE) $(PJMD5SUM) | $(CUT) -d' ' -f1) ;\ - if [ -z "$$required_sum" -o "$$tarball_sum" != "$$required_sum" ] ; then $(SHELL_ECHO_PREFIX) Verify failed ; exit 1 ;\ - else $(SHELL_ECHO_PREFIX) Verify successful ; exit 0 ; fi; ) -endef - -define download_from_pjproject - ($(SHELL_ECHO_PREFIX) Downloading $(TARBALL_URL) to $(TARBALL) ;\ - $(DOWNLOAD_TO_STDOUT) $(call DOWNLOAD_TIMEOUT,5,60) $(TARBALL_URL) > $(TARBALL) &&\ - $(SHELL_ECHO_PREFIX) Downloading $(PJPROJECT_URL)/MD5SUM.TXT to $(PJMD5SUM) &&\ - $(DOWNLOAD_TO_STDOUT) $(call DOWNLOAD_TIMEOUT,5,60) $(PJPROJECT_URL)/MD5SUM.TXT > $(PJMD5SUM) &&\ - $(verify_tarball)) -endef - .DELETE_ON_ERROR: -DOWNLOAD_DIR := $(or $(EXTERNALS_CACHE_DIR),$(TMPDIR),$(wildcard /tmp),.) -TARBALL_FILE = pjproject-$(PJPROJECT_VERSION).tar.bz2 -TARBALL = $(DOWNLOAD_DIR)/$(TARBALL_FILE) -TARBALL_URL = $(PJPROJECT_URL)/$(TARBALL_FILE) -PJMD5SUM = $(patsubst %.tar.bz2,%.md5,$(TARBALL)) - -$(TARBALL): ../versions.mak - $(CMD_PREFIX) ($(tarball_exists) && $(verify_tarball) && touch $@) || (rm -rf $@ ;\ - $(download_from_pjproject)) || (rm -rf $@ ;\ - $(SHELL_ECHO_PREFIX) Retrying download ; $(download_from_pjproject)) +$(DOWNLOAD_DIR)/$(TARBALL_FILE): ../versions.mak + $(CMD_PREFIX) ($(TARBALL_EXISTS) && $(TARBALL_VERIFY) && touch $@) || (rm -rf $@ ;\ + $(TARBALL_DOWNLOAD)) || (rm -rf $@ ;\ + $(SHELL_ECHO_PREFIX) Retrying download ; $(TARBALL_DOWNLOAD)) -source/.unpacked: $(DOWNLOAD_DIR)/pjproject-$(PJPROJECT_VERSION).tar.bz2 - $(CMD_PREFIX) $(verify_tarball) || (rm -rf $@ ;\ - $(SHELL_ECHO_PREFIX) Retrying download ; $(download_from_pjproject)) +source/.unpacked: $(DOWNLOAD_DIR)/$(TARBALL_FILE) + $(CMD_PREFIX) $(TARBALL_VERIFY) || (rm -rf $@ ;\ + $(SHELL_ECHO_PREFIX) Retrying download ; $(TARBALL_DOWNLOAD)) $(ECHO_PREFIX) Unpacking $< - -@rm -rf source pjproject-* >/dev/null 2>&1 + -@rm -rf source pjproject-*/ >/dev/null 2>&1 $(CMD_PREFIX) $(TAR) -xjf $< @mv pjproject-$(PJPROJECT_VERSION) source $(ECHO_PREFIX) Applying patches "$(realpath patches)" "$(realpath .)/source" - $(CMD_PREFIX) ./apply_patches $(QUIET_CONFIGURE) "$(realpath patches)" "$(realpath .)/source" + $(CMD_PREFIX) ../apply_patches $(QUIET_CONFIGURE) "$(realpath patches)" "$(realpath .)/source" -@touch source/.unpacked source/version.mak: source/.unpacked diff --git a/third-party/pjproject/Makefile.rules b/third-party/pjproject/Makefile.rules index ef1a702906..e38024a460 100644 --- a/third-party/pjproject/Makefile.rules +++ b/third-party/pjproject/Makefile.rules @@ -4,9 +4,10 @@ # For future reference when upgrading bundled PJPROJECT the next time # PJPROJECT is released. # Teluu's download URL. -# PJPROJECT_URL ?= http://www.pjsip.org/release/$(PJPROJECT_VERSION) +# PACKAGE_URL ?= http://www.pjsip.org/release/$(PJPROJECT_VERSION) -PJPROJECT_URL ?= https://raw.githubusercontent.com/asterisk/third-party/master/pjproject/$(PJPROJECT_VERSION) +PACKAGE_URL ?= https://raw.githubusercontent.com/asterisk/third-party/master/pjproject/$(PJPROJECT_VERSION) +TARBALL_FILE = pjproject-$(PJPROJECT_VERSION).tar.bz2 # PJPROJECT_CONFIGURE_OPTS could come from the command line or could be # set/modified by configure.m4 if the build or host tuples aren't the same diff --git a/third-party/pjproject/pjproject-2.7.2.tar.bz2.md5 b/third-party/pjproject/pjproject-2.7.2.tar.bz2.md5 new file mode 100644 index 0000000000..2ea6b429bc --- /dev/null +++ b/third-party/pjproject/pjproject-2.7.2.tar.bz2.md5 @@ -0,0 +1,2 @@ +8119f0d91a00b6f553099e6ee5358ade *pjproject-2.7.2.zip +fa3f0bc098c4bff48ddd92db1c016a7a pjproject-2.7.2.tar.bz2 diff --git a/third-party/versions.mak b/third-party/versions.mak index b6daf19892..faf7aecfb7 100644 --- a/third-party/versions.mak +++ b/third-party/versions.mak @@ -1,2 +1,2 @@ - +JANSSON_VERSION = 2.11 PJPROJECT_VERSION = 2.7.2