From ee154464d7f99adc9c056e871ce8b1a72cf99f64 Mon Sep 17 00:00:00 2001 From: Corey Farrell Date: Mon, 16 Jul 2018 16:08:20 -0400 Subject: [PATCH] Enable bundling of jansson, require 2.11. Change-Id: Ib3111b151d37cbda40768cf2a8a9c6cf6c5c7cbd --- CHANGES | 3 + UPGRADE-16.txt | 3 + configure | 147 ++++++++-- configure.ac | 25 +- include/asterisk/json.h | 35 +-- main/json.c | 261 ------------------ makeopts.in | 1 + third-party/Makefile | 4 +- third-party/Makefile.rules | 22 ++ third-party/{pjproject => }/apply_patches | 0 third-party/configure.m4 | 1 + third-party/jansson/.gitignore | 4 + third-party/jansson/Makefile | 99 +++++++ third-party/jansson/Makefile.rules | 16 ++ third-party/jansson/configure.m4 | 89 ++++++ third-party/jansson/jansson-2.11.tar.bz2.md5 | 1 + .../patches/0001-Improve-test-coverage.patch | 128 +++++++++ ...0017-Fix-error-handling-in-json_pack.patch | 103 +++++++ third-party/pjproject/Makefile | 45 +-- third-party/pjproject/Makefile.rules | 5 +- .../pjproject/pjproject-2.7.2.tar.bz2.md5 | 2 + third-party/versions.mak | 2 +- 22 files changed, 642 insertions(+), 354 deletions(-) rename third-party/{pjproject => }/apply_patches (100%) create mode 100644 third-party/jansson/.gitignore create mode 100644 third-party/jansson/Makefile create mode 100644 third-party/jansson/Makefile.rules create mode 100644 third-party/jansson/configure.m4 create mode 100644 third-party/jansson/jansson-2.11.tar.bz2.md5 create mode 100644 third-party/jansson/patches/0001-Improve-test-coverage.patch create mode 100644 third-party/jansson/patches/0017-Fix-error-handling-in-json_pack.patch create mode 100644 third-party/pjproject/pjproject-2.7.2.tar.bz2.md5 diff --git a/CHANGES b/CHANGES index cb3dd7a4b3..c1cd83fe2d 100644 --- a/CHANGES +++ b/CHANGES @@ -31,6 +31,9 @@ Build System MALLOC_DEBUG and vice versa. Third-party pre-compiled modules no longer need to have a special build with it enabled. + * Asterisk now depends on libjansson >= 2.11. If this version is not + available on your distro you can use `./configure --with-jansson-bundled`. + app_macro ------------------ * The app_macro module is now deprecated and by default it is no longer diff --git a/UPGRADE-16.txt b/UPGRADE-16.txt index 154a9b7ddc..8b4fdf70ad 100644 --- a/UPGRADE-16.txt +++ b/UPGRADE-16.txt @@ -50,6 +50,9 @@ Build System: MALLOC_DEBUG and vice versa. Third-party pre-compiled modules no longer need to have a special build with it enabled. + - Asterisk now depends on libjansson >= 2.11. If this version is not + available on your distro you can use `./configure --with-jansson-bundled`. + chan_dahdi: - Timeouts for reading digits from analog phones are now configurable in chan_dahdi.conf: firstdigit_timeout, interdigit_timeout, matchdigit_timeout. diff --git a/configure b/configure index 088a1420e9..c79d87a842 100755 --- a/configure +++ b/configure @@ -1072,10 +1072,7 @@ PBX_URIPARSER URIPARSER_DIR URIPARSER_INCLUDE URIPARSER_LIB -PBX_JANSSON JANSSON_DIR -JANSSON_INCLUDE -JANSSON_LIB PBX_JACK JACK_DIR JACK_INCLUDE @@ -1186,6 +1183,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 @@ -1352,6 +1354,7 @@ with_download_cache with_sounds_cache with_externals_cache enable_coverage +with_jansson_bundled with_pjproject_bundled with_asound with_bfd @@ -1448,6 +1451,7 @@ CXX CXXFLAGS CCC CXXCPP +JANSSON_CONFIGURE_OPTS PJPROJECT_CONFIGURE_OPTS PKG_CONFIG PKG_CONFIG_PATH @@ -2100,6 +2104,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 @@ -2195,6 +2200,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 @@ -9145,6 +9152,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 @@ -9160,6 +9178,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 @@ -13825,7 +13929,9 @@ fi -# Find required JSON support. +# Find required JSON support if bundled is not enabled. +if test "$JANSSON_BUNDLED" = "no" ; then + # json_sprintf is available in 2.11+ if test "x${PBX_JANSSON}" != "x1" -a "${USE_JANSSON}" != "no"; then pbxlibdir="" @@ -13840,9 +13946,9 @@ if test "x${PBX_JANSSON}" != "x1" -a "${USE_JANSSON}" != "no"; then ast_ext_lib_check_save_CFLAGS="${CFLAGS}" CFLAGS="${CFLAGS} " - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for json_dumps in -ljansson" >&5 -$as_echo_n "checking for json_dumps in -ljansson... " >&6; } -if ${ac_cv_lib_jansson_json_dumps+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for json_sprintf in -ljansson" >&5 +$as_echo_n "checking for json_sprintf in -ljansson... " >&6; } +if ${ac_cv_lib_jansson_json_sprintf+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -13856,27 +13962,27 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char json_dumps (); +char json_sprintf (); int main () { -return json_dumps (); +return json_sprintf (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_jansson_json_dumps=yes + ac_cv_lib_jansson_json_sprintf=yes else - ac_cv_lib_jansson_json_dumps=no + ac_cv_lib_jansson_json_sprintf=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_jansson_json_dumps" >&5 -$as_echo "$ac_cv_lib_jansson_json_dumps" >&6; } -if test "x$ac_cv_lib_jansson_json_dumps" = xyes; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_jansson_json_sprintf" >&5 +$as_echo "$ac_cv_lib_jansson_json_sprintf" >&6; } +if test "x$ac_cv_lib_jansson_json_sprintf" = xyes; then : AST_JANSSON_FOUND=yes else AST_JANSSON_FOUND=no @@ -13923,8 +14029,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 >= 2.11 and no system copy was found." >&5 +$as_echo "$as_me: *** Asterisk requires libjansson >= 2.11 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 9b517b1704..fc26925b9a 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.]) @@ -652,11 +661,19 @@ 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 + # json_sprintf is available in 2.11+ + AST_EXT_LIB_CHECK([JANSSON], [jansson], [json_sprintf], [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 >= 2.11 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/include/asterisk/json.h b/include/asterisk/json.h index bd6ba86b98..3da716573a 100644 --- a/include/asterisk/json.h +++ b/include/asterisk/json.h @@ -27,7 +27,7 @@ * \since 12.0.0 * * This is a very thin wrapper around the Jansson API. For more details on it, - * see its docs at http://www.digip.org/jansson/doc/2.4/apiref.html. + * see its docs at http://www.digip.org/jansson/doc/2.11/apiref.html. * * Rather than provide the multiple ways of doing things that the Jansson API * does, the Asterisk wrapper is always reference-stealing, and always NULL @@ -43,35 +43,6 @@ * wrap them with json_ref() when passing them to other \c ast_json_*() * functions. * - * \par Thread Safety - * - * Jansson (as of 2.4) provides fairly weak thread safety guarantees. The - * Asterisk wrapper improves upon that slightly. The remaining refcounting - * problems are issues when slicing/sharing/mixing instances between JSON - * objects and arrays, which we avoid. - * - * The \c ast_json_dump_* functions are thread safe for multiple concurrent - * dumps of the same object, so long as the concurrent dumps start from the same - * \c root object. But if an object is shared by other JSON objects/arrays, then - * concurrent dumps of the outer objects/arrays are not thread safe. This can be - * avoided by using ast_json_deep_copy() when sharing JSON instances between - * objects. - * - * The ast_json_ref() and ast_json_unref() functions are thread safe. Since the - * Asterisk wrapper exclusively uses the reference stealing API, Jansson won't - * be performing many refcount modifications behind our backs. There are a few - * exceptions. - * - * The first is the transitive json_decref() that occurs when \ref - * AST_JSON_OBJECT and \ref AST_JSON_ARRAY instances are deleted. This can be - * avoided by using ast_json_deep_copy() when sharing JSON instances between - * objects. - * - * The second is when using the reference borrowing specifier in - * ast_json_pack() (capital \c O). This can be avoided by using the reference - * stealing specifier (lowercase \c o) and wrapping the JSON object parameter - * with ast_json_ref() for an explicit ref-bump. - * * \par Example code * * \code @@ -907,7 +878,7 @@ struct ast_json *ast_json_load_new_file(const char *path, struct ast_json_error * \brief Helper for creating complex JSON values. * \since 12.0.0 * - * See original Jansson docs at http://www.digip.org/jansson/doc/2.4/apiref.html#apiref-pack + * See original Jansson docs at http://www.digip.org/jansson/doc/2.11/apiref.html#apiref-pack * for more details. */ struct ast_json *ast_json_pack(char const *format, ...); @@ -916,7 +887,7 @@ struct ast_json *ast_json_pack(char const *format, ...); * \brief Helper for creating complex JSON values simply. * \since 12.0.0 * - * See original Jansson docs at http://www.digip.org/jansson/doc/2.4/apiref.html#apiref-pack + * See original Jansson docs at http://www.digip.org/jansson/doc/2.11/apiref.html#apiref-pack * for more details. */ struct ast_json *ast_json_vpack(char const *format, va_list ap); diff --git a/main/json.c b/main/json.c index 7d7bd1d0be..e780c01cd7 100644 --- a/main/json.c +++ b/main/json.c @@ -44,7 +44,6 @@ #include #include -#if defined(JANSSON_THREAD_SAFE_REFCOUNT) void *ast_json_malloc(size_t size) { return ast_malloc(size); @@ -55,155 +54,6 @@ void ast_json_free(void *p) ast_free(p); } -/* No need to lock since jansson is thread safe. */ -#define SCOPED_JSON_LOCK(json) - -#else -/*! \brief Magic number, for safety checks. */ -#define JSON_MAGIC 0x1541992 - -/*! \brief Internal structure for allocated memory blocks */ -struct json_mem { - /*! Magic number, for safety checks */ - uint32_t magic; - /*! Mutext for locking this memory block */ - ast_mutex_t mutex; - /*! Linked list pointer for the free list */ - AST_LIST_ENTRY(json_mem) list; - /*! Data section of the allocation; void pointer for proper alignment */ - void *data[]; -}; - -/*! \brief Free a \ref json_mem block. */ -static void json_mem_free(struct json_mem *mem) -{ - mem->magic = 0; - ast_mutex_destroy(&mem->mutex); - ast_free(mem); -} - -/*! - * \brief Get the \ref json_mem block for a pointer allocated via - * ast_json_malloc(). - * - * This function properly handles Jansson singletons (null, true, false), and - * \c NULL. - * - * \param p Pointer, usually to a \c json_t or \ref ast_json. - * \return \ref json_mem object with extra allocation info. - */ -static inline struct json_mem *to_json_mem(void *p) -{ - struct json_mem *mem; - /* Avoid ref'ing the singleton values */ - if (p == NULL || p == json_null() || p == json_true() || - p == json_false()) { - return NULL; - } - mem = (struct json_mem *)((char *) (p) - sizeof(*mem)); - ast_assert(mem->magic == JSON_MAGIC); - return mem; -} - -/*! - * \brief Lock an \ref ast_json instance. - * - * If \a json is an immutable singleton (null, true, false), this function - * safely ignores it and returns \c NULL. Otherwise, \a json must have been - * allocates using ast_json_malloc(). - * - * \param json JSON instance to lock. - * \return \ref Corresponding \ref json_mem block. - * \return \c NULL if \a json was not allocated. - */ -static struct json_mem *json_mem_lock(struct ast_json *json) -{ - struct json_mem *mem = to_json_mem(json); - if (!mem) { - return NULL; - } - ast_mutex_lock(&mem->mutex); - return mem; -} - -/*! - * \brief Unlock a \ref json_mem instance. - * - * \param mem \ref json_mem, usually returned from json_mem_lock(). - */ -static void json_mem_unlock(struct json_mem *mem) -{ - if (!mem) { - return; - } - ast_mutex_unlock(&mem->mutex); -} - -/*! - * \brief Scoped lock for a \ref ast_json instance. - * - * \param json JSON instance to lock. - */ -#define SCOPED_JSON_LOCK(json) \ - RAII_VAR(struct json_mem *, __mem_ ## __LINE__, \ - json_mem_lock(json), json_mem_unlock) - -void *ast_json_malloc(size_t size) -{ - struct json_mem *mem = ast_malloc(size + sizeof(*mem)); - if (!mem) { - return NULL; - } - mem->magic = JSON_MAGIC; - ast_mutex_init(&mem->mutex); - return mem->data; -} - -AST_THREADSTORAGE(json_free_list_ts); - -/*! - * \brief Struct for a linked list of \ref json_mem. - */ -AST_LIST_HEAD_NOLOCK(json_mem_list, json_mem); - -/*! - * \brief Thread local list of \ref json_mem blocks to free at the end of an - * unref. - */ -static struct json_mem_list *json_free_list(void) -{ - return ast_threadstorage_get(&json_free_list_ts, - sizeof(struct json_mem_list)); -} - -void ast_json_free(void *p) -{ - struct json_mem *mem; - struct json_mem_list *free_list; - mem = to_json_mem(p); - - if (!mem) { - return; - } - - /* Since the unref is holding a lock in mem, we can't free it - * immediately. Store it off on a thread local list to be freed by - * ast_json_unref(). - */ - free_list = json_free_list(); - if (!free_list) { - ast_log(LOG_ERROR, "Error allocating free list\n"); - ast_assert(0); - /* It's not ideal to free the memory immediately, but that's the - * best we can do if the threadlocal allocation fails */ - json_mem_free(mem); - return; - } - - AST_LIST_INSERT_HEAD(free_list, mem, list); -} -#endif - void ast_json_set_alloc_funcs(void *(*malloc_fn)(size_t), void (*free_fn)(void*)) { json_set_alloc_funcs(malloc_fn, free_fn); @@ -216,42 +66,13 @@ void ast_json_reset_alloc_funcs(void) struct ast_json *ast_json_ref(struct ast_json *json) { - /* If Jansson refcounting is non-atomic; lock it. */ - SCOPED_JSON_LOCK(json); json_incref((json_t *)json); return json; } void ast_json_unref(struct ast_json *json) { -#if defined(JANSSON_THREAD_SAFE_REFCOUNT) json_decref((json_t *) json); -#else - struct json_mem_list *free_list; - struct json_mem *mem; - - if (!json) { - return; - } - - /* Jansson refcounting is non-atomic; lock it. */ - { - SCOPED_JSON_LOCK(json); - - json_decref((json_t *) json); - } - - /* Now free any objects that were ast_json_free()'s while the lock was - * held */ - free_list = json_free_list(); - if (!free_list) { - return; - } - - while ((mem = AST_LIST_REMOVE_HEAD(free_list, list))) { - json_mem_free(mem); - } -#endif } enum ast_json_type ast_json_typeof(const struct ast_json *json) @@ -421,11 +242,7 @@ struct ast_json *ast_json_false(void) struct ast_json *ast_json_boolean(int value) { -#if JANSSON_VERSION_HEX >= 0x020400 return (struct ast_json *)json_boolean(value); -#else - return value ? ast_json_true() : ast_json_false(); -#endif } struct ast_json *ast_json_null(void) @@ -593,57 +410,11 @@ int ast_json_object_update(struct ast_json *object, struct ast_json *other) } int ast_json_object_update_existing(struct ast_json *object, struct ast_json *other) { -#if JANSSON_VERSION_HEX >= 0x020300 return json_object_update_existing((json_t *)object, (json_t *)other); -#else - struct ast_json_iter *iter = ast_json_object_iter(other); - int ret = 0; - - if (object == NULL || other == NULL) { - return -1; - } - - while (iter != NULL && ret == 0) { - const char *key = ast_json_object_iter_key(iter); - - if (ast_json_object_get(object, key) != NULL) { - struct ast_json *value = ast_json_object_iter_value(iter); - - if (!value || ast_json_object_set(object, key, ast_json_ref(value))) { - ret = -1; - } - } - iter = ast_json_object_iter_next(other, iter); - } - return ret; -#endif } int ast_json_object_update_missing(struct ast_json *object, struct ast_json *other) { -#if JANSSON_VERSION_HEX >= 0x020300 return json_object_update_missing((json_t *)object, (json_t *)other); -#else - struct ast_json_iter *iter = ast_json_object_iter(other); - int ret = 0; - - if (object == NULL || other == NULL) { - return -1; - } - - while (iter != NULL && ret == 0) { - const char *key = ast_json_object_iter_key(iter); - - if (ast_json_object_get(object, key) == NULL) { - struct ast_json *value = ast_json_object_iter_value(iter); - - if (!value || ast_json_object_set(object, key, ast_json_ref(value))) { - ret = -1; - } - } - iter = ast_json_object_iter_next(other, iter); - } - return ret; -#endif } struct ast_json_iter *ast_json_object_iter(struct ast_json *object) @@ -682,14 +453,6 @@ static size_t dump_flags(enum ast_json_encoding_format format) char *ast_json_dump_string_format(struct ast_json *root, enum ast_json_encoding_format format) { - /* Jansson's json_dump*, even though it's a read operation, isn't - * thread safe for concurrent reads. Locking is necessary. - * See http://www.digip.org/jansson/doc/2.4/portability.html#thread-safety. - * - * This comment does not apply when JANSSON_THREAD_SAFE_REFCOUNT is defined, - * in that case SCOPED_JSON_LOCK is a no-op. - */ - SCOPED_JSON_LOCK(root); return json_dumps((json_t *)root, dump_flags(format)); } @@ -726,28 +489,12 @@ static int write_to_ast_str(const char *buffer, size_t size, void *data) int ast_json_dump_str_format(struct ast_json *root, struct ast_str **dst, enum ast_json_encoding_format format) { - /* Jansson's json_dump*, even though it's a read operation, isn't - * thread safe for concurrent reads. Locking is necessary. - * See http://www.digip.org/jansson/doc/2.4/portability.html#thread-safety. - * - * This comment does not apply when JANSSON_THREAD_SAFE_REFCOUNT is defined, - * in that case SCOPED_JSON_LOCK is a no-op. - */ - SCOPED_JSON_LOCK(root); return json_dump_callback((json_t *)root, write_to_ast_str, dst, dump_flags(format)); } int ast_json_dump_file_format(struct ast_json *root, FILE *output, enum ast_json_encoding_format format) { - /* Jansson's json_dump*, even though it's a read operation, isn't - * thread safe for concurrent reads. Locking is necessary. - * See http://www.digip.org/jansson/doc/2.4/portability.html#thread-safety. - * - * This comment does not apply when JANSSON_THREAD_SAFE_REFCOUNT is defined, - * in that case SCOPED_JSON_LOCK is a no-op. - */ - SCOPED_JSON_LOCK(root); if (!root || !output) { return -1; } @@ -755,14 +502,6 @@ int ast_json_dump_file_format(struct ast_json *root, FILE *output, enum ast_json } int ast_json_dump_new_file_format(struct ast_json *root, const char *path, enum ast_json_encoding_format format) { - /* Jansson's json_dump*, even though it's a read operation, isn't - * thread safe for concurrent reads. Locking is necessary. - * See http://www.digip.org/jansson/doc/2.4/portability.html#thread-safety. - * - * This comment does not apply when JANSSON_THREAD_SAFE_REFCOUNT is defined, - * in that case SCOPED_JSON_LOCK is a no-op. - */ - SCOPED_JSON_LOCK(root); if (!root || !path) { return -1; } diff --git a/makeopts.in b/makeopts.in index b52eda7ef5..cb98726db1 100644 --- a/makeopts.in +++ b/makeopts.in @@ -183,6 +183,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 4669f39cc5..476eb44017 100644 --- a/third-party/pjproject/Makefile +++ b/third-party/pjproject/Makefile @@ -89,49 +89,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)) +$(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)) -$(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)) - -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