[Asterisk-code-review] Enable bundling of jansson, require 2.11. (asterisk[16])

George Joseph asteriskteam at digium.com
Tue Jul 24 10:50:42 CDT 2018


George Joseph has submitted this change and it was merged. ( https://gerrit.asterisk.org/9525 )

Change subject: Enable bundling of jansson, require 2.11.
......................................................................

Enable bundling of jansson, require 2.11.

Change-Id: Ib3111b151d37cbda40768cf2a8a9c6cf6c5c7cbd
---
M CHANGES
M UPGRADE.txt
M configure
M configure.ac
M include/asterisk/json.h
M main/json.c
M makeopts.in
M third-party/Makefile
M third-party/Makefile.rules
R third-party/apply_patches
M third-party/configure.m4
A third-party/jansson/.gitignore
A third-party/jansson/Makefile
A third-party/jansson/Makefile.rules
A third-party/jansson/configure.m4
A third-party/jansson/jansson-2.11.tar.bz2.md5
A third-party/jansson/patches/0001-Improve-test-coverage.patch
A third-party/jansson/patches/0017-Fix-error-handling-in-json_pack.patch
M third-party/pjproject/Makefile
M third-party/pjproject/Makefile.rules
A third-party/pjproject/pjproject-2.7.2.tar.bz2.md5
M third-party/versions.mak
22 files changed, 642 insertions(+), 354 deletions(-)

Approvals:
  Kevin Harwell: Looks good to me, but someone else must approve
  Joshua Colp: Looks good to me, but someone else must approve
  George Joseph: Looks good to me, approved; Approved for Submit



diff --git a/CHANGES b/CHANGES
index cb3dd7a..c1cd83f 100644
--- a/CHANGES
+++ b/CHANGES
@@ -31,6 +31,9 @@
    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.txt b/UPGRADE.txt
index 154a9b7..8b4fdf7 100644
--- a/UPGRADE.txt
+++ b/UPGRADE.txt
@@ -50,6 +50,9 @@
    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 088a142..c79d87a 100755
--- a/configure
+++ b/configure
@@ -1072,10 +1072,7 @@
 URIPARSER_DIR
 URIPARSER_INCLUDE
 URIPARSER_LIB
-PBX_JANSSON
 JANSSON_DIR
-JANSSON_INCLUDE
-JANSSON_LIB
 PBX_JACK
 JACK_DIR
 JACK_INCLUDE
@@ -1186,6 +1183,11 @@
 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_sounds_cache
 with_externals_cache
 enable_coverage
+with_jansson_bundled
 with_pjproject_bundled
 with_asound
 with_bfd
@@ -1448,6 +1451,7 @@
 CXXFLAGS
 CCC
 CXXCPP
+JANSSON_CONFIGURE_OPTS
 PJPROJECT_CONFIGURE_OPTS
 PKG_CONFIG
 PKG_CONFIG_PATH
@@ -2100,6 +2104,7 @@
                           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 @@
   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 @@
 	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 @@
 
 
 
+	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 @@
 
 
 
-# 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 @@
 
       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 @@
 #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 @@
 
 
 
-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 9b517b1..fc26925 100644
--- a/configure.ac
+++ b/configure.ac
@@ -423,6 +423,15 @@
 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 @@
 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 bd6ba86..3da7165 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 @@
  * \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 @@
  * \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 7d7bd1d..e780c01 100644
--- a/main/json.c
+++ b/main/json.c
@@ -44,7 +44,6 @@
 #include <jansson.h>
 #include <time.h>
 
-#if defined(JANSSON_THREAD_SAFE_REFCOUNT)
 void *ast_json_malloc(size_t size)
 {
 	return ast_malloc(size);
@@ -55,155 +54,6 @@
 	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 @@
 
 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_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_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 @@
 
 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 @@
 
 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_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 b52eda7..cb98726 100644
--- a/makeopts.in
+++ b/makeopts.in
@@ -183,6 +183,7 @@
 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 3ea84d1..7b2afda 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 8306869..f02ddb1 100644
--- a/third-party/Makefile.rules
+++ b/third-party/Makefile.rules
@@ -33,3 +33,25 @@
 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 6367722..fa4736d 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 0000000..b7bfd2b
--- /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 0000000..a85efa0
--- /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 $<
+	- at 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"
+	- at 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 0000000..39112eb
--- /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 0000000..d59d861
--- /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 0000000..db4326c
--- /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 0000000..226c404
--- /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 <git at cfware.com>
+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, "<internal>", 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 0000000..affa6c9
--- /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 <mussitantesmortem at gmail.com>
+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, "<args>", 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, "<format>", json_error_invalid_format, "Unexpected format character '%c'",
+-- 
+2.17.1
+
diff --git a/third-party/pjproject/Makefile b/third-party/pjproject/Makefile
index 4669f39..476eb44 100644
--- a/third-party/pjproject/Makefile
+++ b/third-party/pjproject/Makefile
@@ -89,49 +89,22 @@
 
 _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 $<
-	- at rm -rf source pjproject-* >/dev/null 2>&1
+	- at 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"
 	- at touch source/.unpacked
 
 source/version.mak: source/.unpacked
diff --git a/third-party/pjproject/Makefile.rules b/third-party/pjproject/Makefile.rules
index ef1a702..e38024a 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 0000000..2ea6b42
--- /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 b6daf19..faf7aec 100644
--- a/third-party/versions.mak
+++ b/third-party/versions.mak
@@ -1,2 +1,2 @@
-
+JANSSON_VERSION = 2.11
 PJPROJECT_VERSION = 2.7.2

-- 
To view, visit https://gerrit.asterisk.org/9525
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings

Gerrit-Project: asterisk
Gerrit-Branch: 16
Gerrit-MessageType: merged
Gerrit-Change-Id: Ib3111b151d37cbda40768cf2a8a9c6cf6c5c7cbd
Gerrit-Change-Number: 9525
Gerrit-PatchSet: 2
Gerrit-Owner: Corey Farrell <git at cfware.com>
Gerrit-Reviewer: George Joseph <gjoseph at digium.com>
Gerrit-Reviewer: Jenkins2
Gerrit-Reviewer: Joshua Colp <jcolp at digium.com>
Gerrit-Reviewer: Kevin Harwell <kharwell at digium.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20180724/e649eb5a/attachment-0001.html>


More information about the asterisk-code-review mailing list