Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package libjansson for openSUSE:Factory 
checked in at 2026-07-02 22:13:50
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libjansson (Old)
 and      /work/SRC/openSUSE:Factory/.libjansson.new.1982 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libjansson"

Thu Jul  2 22:13:50 2026 rev:17 rq:1363118 version:2.15.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/libjansson/libjansson.changes    2026-02-07 
15:33:16.144980723 +0100
+++ /work/SRC/openSUSE:Factory/.libjansson.new.1982/libjansson.changes  
2026-07-02 22:19:07.232805503 +0200
@@ -1,0 +2,11 @@
+Thu Jul  2 06:43:20 UTC 2026 - Paolo Stivanin <[email protected]>
+
+- Update to 2.15.1:
+  * Include the object key or array index in unpack type mismatch error
+    messages (@cwalther in #731)
+  * Reject negative string length in the json_pack s# and +# formats
+    (@akheron in #740)
+  * Limit recursion depth in dump, equal and deep copy to prevent stack
+    overflow (@akheron in #741)
+
+-------------------------------------------------------------------

Old:
----
  jansson-2.15.0.tar.bz2
  jansson-2.15.0.tar.bz2.asc

New:
----
  jansson-2.15.1.tar.bz2
  jansson-2.15.1.tar.bz2.asc

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libjansson.spec ++++++
--- /var/tmp/diff_new_pack.KqJFIF/_old  2026-07-02 22:19:07.892828177 +0200
+++ /var/tmp/diff_new_pack.KqJFIF/_new  2026-07-02 22:19:07.896828315 +0200
@@ -18,7 +18,7 @@
 
 %define lname   libjansson4
 Name:           libjansson
-Version:        2.15.0
+Version:        2.15.1
 Release:        0
 Summary:        C library for encoding, decoding and manipulating JSON data
 License:        MIT

++++++ jansson-2.15.0.tar.bz2 -> jansson-2.15.1.tar.bz2 ++++++
++++ 8268 lines of diff (skipped)
++++    retrying with extended exclude list
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/jansson-2.15.0/CHANGES new/jansson-2.15.1/CHANGES
--- old/jansson-2.15.0/CHANGES  2026-01-24 21:54:33.000000000 +0100
+++ new/jansson-2.15.1/CHANGES  2026-07-01 20:35:59.000000000 +0200
@@ -1,3 +1,27 @@
+Version 2.15.1
+==============
+
+Released 2026-06-30
+
+* Fixes:
+
+  - Include the object key or array index in unpack type mismatch error
+    messages (@cwalther in #731)
+  - Reject negative string length in the `json_pack` `s#` and `+#` formats
+    (@akheron in #740)
+  - Limit recursion depth in dump, equal and deep copy to prevent stack
+    overflow (@akheron in #741)
+
+* Build:
+
+  - Only export symbols starting with `json_` and `jansson_` from the CMake
+    build (@shyjun in #705)
+  - Include `jansson_private_config.h` only if `HAVE_CONFIG_H` is enabled
+    (@jaeyoonjung in #704)
+  - Add a configurable pkg-config install path to the CMake build
+    (@akallabeth in #721)
+  - Only use `--default-symver` when the linker supports it (@kraj in #744)
+
 Version 2.15.0
 ==============
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/jansson-2.15.0/CMakeLists.txt new/jansson-2.15.1/CMakeLists.txt
--- old/jansson-2.15.0/CMakeLists.txt   2026-01-24 21:54:33.000000000 +0100
+++ new/jansson-2.15.1/CMakeLists.txt   2026-07-01 20:35:59.000000000 +0200
@@ -36,10 +36,10 @@
 # set (JANSSON_VERSION "2.3.1")
 # set (JANSSON_SOVERSION 2)
 
-set(JANSSON_DISPLAY_VERSION "2.15.0")
+set(JANSSON_DISPLAY_VERSION "2.15.1")
 
 # This is what is required to match the same numbers as automake's
-set(JANSSON_VERSION "4.15.0")
+set(JANSSON_VERSION "4.15.1")
 set(JANSSON_SOVERSION 4)
 
 # for CheckFunctionKeywords
@@ -322,6 +322,9 @@
 # some linkers may only support --version-script
       file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/jansson.sym" 
"JANSSON_${JANSSON_SOVERSION} {
     global:
+          json_*;
+          jansson_*;
+    local:
           *;
 };
 ")
@@ -601,6 +604,9 @@
 
 set(JANSSON_INSTALL_CMAKE_DIR ${DEF_INSTALL_CMAKE_DIR} CACHE PATH 
"Installation directory for CMake files")
 
+set(DEF_INSTALL_PKGCONF_DIR lib/pkgconfig)
+set(JANSSON_INSTALL_PKGCONF_DIR ${DEF_INSTALL_PKGCONF_DIR} CACHE PATH 
"Installation directory for pkg-config files")
+
 # Create pkg-conf file.
 # (We use the same files as ./configure does, so we
 #  have to defined the same variables used there).
@@ -658,7 +664,7 @@
   # Install the pkg-config.
   install(FILES
           ${CMAKE_CURRENT_BINARY_DIR}/jansson.pc
-          DESTINATION lib/pkgconfig)
+          DESTINATION ${JANSSON_INSTALL_PKGCONF_DIR})
 
   # Install the configs.
   install(FILES
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/jansson-2.15.0/configure.ac new/jansson-2.15.1/configure.ac
--- old/jansson-2.15.0/configure.ac     2026-01-24 21:54:32.000000000 +0100
+++ new/jansson-2.15.1/configure.ac     2026-07-01 20:35:59.000000000 +0200
@@ -1,5 +1,5 @@
 AC_PREREQ([2.60])
-AC_INIT([jansson], [2.15.0], [https://github.com/akheron/jansson/issues])
+AC_INIT([jansson], [2.15.1], [https://github.com/akheron/jansson/issues])
 
 AC_CONFIG_AUX_DIR([.])
 AM_INIT_AUTOMAKE([1.10 foreign])
@@ -135,7 +135,16 @@
 
 # Enable symbol versioning on GNU libc
 JSON_SYMVER_LDFLAGS=
-AC_CHECK_DECL([__GLIBC__], [JSON_SYMVER_LDFLAGS=-Wl,--default-symver])
+AC_CHECK_DECL([__GLIBC__], [
+    saved_LDFLAGS="$LDFLAGS"
+    LDFLAGS="$LDFLAGS -Wl,--default-symver"
+    AC_MSG_CHECKING([whether the linker accepts -Wl,--default-symver])
+    AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+        [AC_MSG_RESULT([yes])
+         JSON_SYMVER_LDFLAGS=-Wl,--default-symver],
+        [AC_MSG_RESULT([no])])
+    LDFLAGS="$saved_LDFLAGS"
+])
 AC_SUBST([JSON_SYMVER_LDFLAGS])
 
 AC_ARG_ENABLE([dtoa],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/jansson-2.15.0/doc/apiref.rst new/jansson-2.15.1/doc/apiref.rst
--- old/jansson-2.15.0/doc/apiref.rst   2026-01-24 21:50:09.000000000 +0100
+++ new/jansson-2.15.1/doc/apiref.rst   2026-07-01 20:34:38.000000000 +0200
@@ -1535,7 +1535,9 @@
     .. versionadded:: 2.11
 
 ``s#`` (string) [const char \*, int]
-    Convert a UTF-8 buffer of a given length to a JSON string.
+    Convert a UTF-8 buffer of a given length to a JSON string. The
+    length must not be negative; a negative length results in a
+    ``json_error_invalid_argument`` error.
 
     .. versionadded:: 2.5
 
@@ -1865,13 +1867,15 @@
   if their types are equal. (Because these values are singletons,
   their equality can actually be tested with ``==``.)
 
+* Values nested more deeply than ``JSON_PARSER_MAX_DEPTH`` are not
+  recursed into, and thus cosidered unequal, to avoid stack exhaustion.
+
 .. function:: int json_equal(json_t *value1, json_t *value2)
 
    Returns 1 if *value1* and *value2* are equal, as defined above.
    Returns 0 if they are unequal or one or both of the pointers are
    *NULL*.
 
-
 Copying
 =======
 
@@ -1899,7 +1903,9 @@
 
    .. refcounting:: new
 
-   Returns a deep copy of *value*, or *NULL* on error.
+   Returns a deep copy of *value*, or *NULL* on error. Copying fails if
+   *value* is nested more deeply than ``JSON_PARSER_MAX_DEPTH``, to avoid
+   stack exhaustion.
 
 
 .. _apiref-custom-memory-allocation:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/jansson-2.15.0/doc/conf.py new/jansson-2.15.1/doc/conf.py
--- old/jansson-2.15.0/doc/conf.py      2026-01-24 21:54:32.000000000 +0100
+++ new/jansson-2.15.1/doc/conf.py      2026-07-01 20:35:59.000000000 +0200
@@ -48,7 +48,7 @@
 # built documents.
 #
 # The short X.Y version.
-version = '2.15.0'
+version = '2.15.1'
 # The full version, including alpha/beta/rc tags.
 release = version
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/jansson-2.15.0/scripts/clang-format-check.log 
new/jansson-2.15.1/scripts/clang-format-check.log
--- old/jansson-2.15.0/scripts/clang-format-check.log   1970-01-01 
01:00:00.000000000 +0100
+++ new/jansson-2.15.1/scripts/clang-format-check.log   2026-06-13 
14:06:37.000000000 +0200
@@ -0,0 +1,46 @@
+Checking android/jansson_config.h
+Checking doc/github_commits.c
+Checking examples/simple_parse.c
+Checking src/dtoa.c
+Checking src/dump.c
+Checking src/error.c
+Checking src/hashtable.c
+Checking src/hashtable.h
+Checking src/hashtable_seed.c
+Checking src/jansson.h
+Checking src/jansson_private.h
+Checking src/load.c
+Checking src/lookup3.h
+Checking src/memory.c
+Checking src/pack_unpack.c
+Checking src/strbuffer.c
+Checking src/strbuffer.h
+Checking src/strconv.c
+Checking src/utf.c
+Checking src/utf.h
+Checking src/value.c
+Checking src/version.c
+Checking test/bin/json_process.c
+Checking test/ossfuzz/testinput.h
+Checking test/suites/api/test_array.c
+Checking test/suites/api/test_chaos.c
+Checking test/suites/api/test_chaos_realloc.c
+Checking test/suites/api/test_copy.c
+Checking test/suites/api/test_dump.c
+Checking test/suites/api/test_dump_callback.c
+Checking test/suites/api/test_equal.c
+Checking test/suites/api/test_fixed_size.c
+Checking test/suites/api/test_load.c
+Checking test/suites/api/test_load_callback.c
+Checking test/suites/api/test_loadb.c
+Checking test/suites/api/test_memory_funcs.c
+Checking test/suites/api/test_memory_funcs_realloc.c
+Checking test/suites/api/test_number.c
+Checking test/suites/api/test_object.c
+Checking test/suites/api/test_pack.c
+Checking test/suites/api/test_simple.c
+Checking test/suites/api/test_sprintf.c
+Checking test/suites/api/test_unpack.c
+Checking test/suites/api/test_version.c
+Checking test/suites/api/util.h
+PASS scripts/clang-format-check (exit status: 0)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/jansson-2.15.0/scripts/clang-format-check.trs 
new/jansson-2.15.1/scripts/clang-format-check.trs
--- old/jansson-2.15.0/scripts/clang-format-check.trs   1970-01-01 
01:00:00.000000000 +0100
+++ new/jansson-2.15.1/scripts/clang-format-check.trs   2026-06-13 
14:06:37.000000000 +0200
@@ -0,0 +1,4 @@
+:test-result: PASS
+:global-test-result: PASS
+:recheck: no
+:copy-in-global-log: no
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/jansson-2.15.0/src/Makefile.am new/jansson-2.15.1/src/Makefile.am
--- old/jansson-2.15.0/src/Makefile.am  2026-01-24 21:54:33.000000000 +0100
+++ new/jansson-2.15.1/src/Makefile.am  2026-07-01 20:35:59.000000000 +0200
@@ -30,6 +30,6 @@
 libjansson_la_LDFLAGS = \
        -no-undefined \
        -export-symbols-regex '^json_|^jansson_' \
-       -version-info 19:0:15 \
+       -version-info 19:1:15 \
        @JSON_SYMVER_LDFLAGS@ \
        @JSON_BSYMBOLIC_LDFLAGS@
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/jansson-2.15.0/src/dump.c new/jansson-2.15.1/src/dump.c
--- old/jansson-2.15.0/src/dump.c       2026-01-22 07:37:04.000000000 +0100
+++ new/jansson-2.15.1/src/dump.c       2026-07-01 20:34:38.000000000 +0200
@@ -221,6 +221,9 @@
     if (!json)
         return -1;
 
+    if (depth >= JSON_PARSER_MAX_DEPTH)
+        return -1;
+
     switch (json_typeof(json)) {
         case JSON_NULL:
             return dump("null", 4, data);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/jansson-2.15.0/src/jansson.h new/jansson-2.15.1/src/jansson.h
--- old/jansson-2.15.0/src/jansson.h    2026-01-24 21:54:32.000000000 +0100
+++ new/jansson-2.15.1/src/jansson.h    2026-07-01 20:35:59.000000000 +0200
@@ -22,10 +22,10 @@
 
 #define JANSSON_MAJOR_VERSION 2
 #define JANSSON_MINOR_VERSION 15
-#define JANSSON_MICRO_VERSION 0
+#define JANSSON_MICRO_VERSION 1
 
 /* Micro version is omitted if it's 0 */
-#define JANSSON_VERSION "2.15.0"
+#define JANSSON_VERSION "2.15.1"
 
 /* Version as a 3-byte hex number, e.g. 0x010201 == 1.2.1. Use this
    for numeric comparisons, e.g. #if JANSSON_VERSION_HEX >= ... */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/jansson-2.15.0/src/jansson_private.h 
new/jansson-2.15.1/src/jansson_private.h
--- old/jansson-2.15.0/src/jansson_private.h    2026-01-22 07:37:04.000000000 
+0100
+++ new/jansson-2.15.1/src/jansson_private.h    2026-07-01 20:34:38.000000000 
+0200
@@ -10,7 +10,9 @@
 
 #include "hashtable.h"
 #include "jansson.h"
+#ifdef HAVE_CONFIG_H
 #include "jansson_private_config.h"
+#endif
 #include "strbuffer.h"
 #include <stddef.h>
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/jansson-2.15.0/src/pack_unpack.c new/jansson-2.15.1/src/pack_unpack.c
--- old/jansson-2.15.0/src/pack_unpack.c        2026-01-22 07:37:04.000000000 
+0100
+++ new/jansson-2.15.1/src/pack_unpack.c        2026-07-01 20:34:38.000000000 
+0200
@@ -173,7 +173,15 @@
         next_token(s);
 
         if (token(s) == '#') {
-            length = va_arg(*ap, int);
+            int len = va_arg(*ap, int);
+            if (len < 0) {
+                set_error(s, "<args>", json_error_invalid_argument,
+                          "Invalid length for %s: %d", purpose, len);
+                s->has_error = 1;
+                length = 0;
+            } else {
+                length = (size_t)len;
+            }
         } else if (token(s) == '%') {
             length = va_arg(*ap, size_t);
         } else {
@@ -460,9 +468,10 @@
     }
 }
 
-static int unpack(scanner_t *s, json_t *root, va_list *ap);
+static int unpack(scanner_t *s, json_t *root, va_list *ap, const char *key);
 
-static int unpack_object(scanner_t *s, json_t *root, va_list *ap) {
+static int unpack_object(scanner_t *s, json_t *root, va_list *ap,
+                         const char *parent_key) {
     int ret = -1;
     int strict = 0;
     int gotopt = 0;
@@ -480,8 +489,9 @@
     }
 
     if (root && !json_is_object(root)) {
-        set_error(s, "<validation>", json_error_wrong_type, "Expected object, 
got %s",
-                  type_name(root));
+        set_error(s, "<validation>", json_error_wrong_type, "Expected object, 
got %s%s%s",
+                  type_name(root), parent_key ? " for key " : "",
+                  parent_key ? parent_key : "");
         goto out;
     }
     next_token(s);
@@ -543,7 +553,7 @@
             }
         }
 
-        if (unpack(s, value, ap))
+        if (unpack(s, value, ap, key))
             goto out;
 
         hashtable_set(&key_set, key, key_len, json_null());
@@ -597,13 +607,14 @@
     return ret;
 }
 
-static int unpack_array(scanner_t *s, json_t *root, va_list *ap) {
+static int unpack_array(scanner_t *s, json_t *root, va_list *ap, const char 
*parent_key) {
     size_t i = 0;
     int strict = 0;
 
     if (root && !json_is_array(root)) {
-        set_error(s, "<validation>", json_error_wrong_type, "Expected array, 
got %s",
-                  type_name(root));
+        set_error(s, "<validation>", json_error_wrong_type, "Expected array, 
got %s%s%s",
+                  type_name(root), parent_key ? " for key " : "",
+                  parent_key ? parent_key : "");
         return -1;
     }
     next_token(s);
@@ -648,7 +659,7 @@
             }
         }
 
-        if (unpack(s, value, ap))
+        if (unpack(s, value, ap, NULL))
             return -1;
 
         next_token(s);
@@ -668,18 +679,19 @@
     return 0;
 }
 
-static int unpack(scanner_t *s, json_t *root, va_list *ap) {
+static int unpack(scanner_t *s, json_t *root, va_list *ap, const char *key) {
     switch (token(s)) {
         case '{':
-            return unpack_object(s, root, ap);
+            return unpack_object(s, root, ap, key);
 
         case '[':
-            return unpack_array(s, root, ap);
+            return unpack_array(s, root, ap, key);
 
         case 's':
             if (root && !json_is_string(root)) {
                 set_error(s, "<validation>", json_error_wrong_type,
-                          "Expected string, got %s", type_name(root));
+                          "Expected string, got %s%s%s", type_name(root),
+                          key ? " for key " : "", key ? key : "");
                 return -1;
             }
 
@@ -716,7 +728,8 @@
         case 'i':
             if (root && !json_is_integer(root)) {
                 set_error(s, "<validation>", json_error_wrong_type,
-                          "Expected integer, got %s", type_name(root));
+                          "Expected integer, got %s%s%s", type_name(root),
+                          key ? " for key " : "", key ? key : "");
                 return -1;
             }
 
@@ -731,7 +744,8 @@
         case 'I':
             if (root && !json_is_integer(root)) {
                 set_error(s, "<validation>", json_error_wrong_type,
-                          "Expected integer, got %s", type_name(root));
+                          "Expected integer, got %s%s%s", type_name(root),
+                          key ? " for key " : "", key ? key : "");
                 return -1;
             }
 
@@ -746,7 +760,8 @@
         case 'b':
             if (root && !json_is_boolean(root)) {
                 set_error(s, "<validation>", json_error_wrong_type,
-                          "Expected true or false, got %s", type_name(root));
+                          "Expected true or false, got %s%s%s", 
type_name(root),
+                          key ? " for key " : "", key ? key : "");
                 return -1;
             }
 
@@ -761,7 +776,8 @@
         case 'f':
             if (root && !json_is_real(root)) {
                 set_error(s, "<validation>", json_error_wrong_type,
-                          "Expected real, got %s", type_name(root));
+                          "Expected real, got %s%s%s", type_name(root),
+                          key ? " for key " : "", key ? key : "");
                 return -1;
             }
 
@@ -776,7 +792,8 @@
         case 'F':
             if (root && !json_is_number(root)) {
                 set_error(s, "<validation>", json_error_wrong_type,
-                          "Expected real or integer, got %s", type_name(root));
+                          "Expected real or integer, got %s%s%s", 
type_name(root),
+                          key ? " for key " : "", key ? key : "");
                 return -1;
             }
 
@@ -806,7 +823,8 @@
             /* Never assign, just validate */
             if (root && !json_is_null(root)) {
                 set_error(s, "<validation>", json_error_wrong_type,
-                          "Expected null, got %s", type_name(root));
+                          "Expected null, got %s%s%s", type_name(root),
+                          key ? " for key " : "", key ? key : "");
                 return -1;
             }
             return 0;
@@ -898,7 +916,7 @@
     next_token(&s);
 
     va_copy(ap_copy, ap);
-    if (unpack(&s, root, &ap_copy)) {
+    if (unpack(&s, root, &ap_copy, NULL)) {
         va_end(ap_copy);
         return -1;
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/jansson-2.15.0/src/value.c new/jansson-2.15.1/src/value.c
--- old/jansson-2.15.0/src/value.c      2026-01-22 07:37:04.000000000 +0100
+++ new/jansson-2.15.1/src/value.c      2026-07-01 20:34:38.000000000 +0200
@@ -37,7 +37,8 @@
 static JSON_INLINE int isinf(double x) { return !isnan(x) && isnan(x - x); }
 #endif
 
-json_t *do_deep_copy(const json_t *json, hashtable_t *parents);
+static int do_equal(const json_t *json1, const json_t *json2, int depth);
+json_t *do_deep_copy(const json_t *json, hashtable_t *parents, int depth);
 
 static JSON_INLINE void json_init(json_t *json, json_type type) {
     json->type = type;
@@ -352,7 +353,7 @@
     return hashtable_key_to_iter(key);
 }
 
-static int json_object_equal(const json_t *object1, const json_t *object2) {
+static int json_object_equal(const json_t *object1, const json_t *object2, int 
depth) {
     const char *key;
     size_t key_len;
     const json_t *value1, *value2;
@@ -363,7 +364,7 @@
     json_object_keylen_foreach((json_t *)object1, key, key_len, value1) {
         value2 = json_object_getn(object2, key, key_len);
 
-        if (!json_equal(value1, value2))
+        if (!do_equal(value1, value2, depth + 1))
             return 0;
     }
 
@@ -387,7 +388,8 @@
     return result;
 }
 
-static json_t *json_object_deep_copy(const json_t *object, hashtable_t 
*parents) {
+static json_t *json_object_deep_copy(const json_t *object, hashtable_t 
*parents,
+                                     int depth) {
     json_t *result;
     void *iter;
     char loop_key[LOOP_KEY_LEN];
@@ -412,7 +414,7 @@
         value = json_object_iter_value(iter);
 
         if (json_object_setn_new_nocheck(result, key, key_len,
-                                         do_deep_copy(value, parents))) {
+                                         do_deep_copy(value, parents, depth + 
1))) {
             json_decref(result);
             result = NULL;
             break;
@@ -638,7 +640,7 @@
     return 0;
 }
 
-static int json_array_equal(const json_t *array1, const json_t *array2) {
+static int json_array_equal(const json_t *array1, const json_t *array2, int 
depth) {
     size_t i, size;
 
     size = json_array_size(array1);
@@ -651,7 +653,7 @@
         value1 = json_array_get(array1, i);
         value2 = json_array_get(array2, i);
 
-        if (!json_equal(value1, value2))
+        if (!do_equal(value1, value2, depth + 1))
             return 0;
     }
 
@@ -672,7 +674,8 @@
     return result;
 }
 
-static json_t *json_array_deep_copy(const json_t *array, hashtable_t *parents) 
{
+static json_t *json_array_deep_copy(const json_t *array, hashtable_t *parents,
+                                    int depth) {
     json_t *result;
     size_t i;
     char loop_key[LOOP_KEY_LEN];
@@ -686,8 +689,8 @@
         goto out;
 
     for (i = 0; i < json_array_size(array); i++) {
-        if (json_array_append_new(result,
-                                  do_deep_copy(json_array_get(array, i), 
parents))) {
+        if (json_array_append_new(
+                result, do_deep_copy(json_array_get(array, i), parents, depth 
+ 1))) {
             json_decref(result);
             result = NULL;
             break;
@@ -1017,6 +1020,10 @@
 /*** equality ***/
 
 int json_equal(const json_t *json1, const json_t *json2) {
+    return do_equal(json1, json2, 0);
+}
+
+static int do_equal(const json_t *json1, const json_t *json2, int depth) {
     if (!json1 || !json2)
         return 0;
 
@@ -1027,11 +1034,14 @@
     if (json1 == json2)
         return 1;
 
+    if (depth >= JSON_PARSER_MAX_DEPTH)
+        return 0;
+
     switch (json_typeof(json1)) {
         case JSON_OBJECT:
-            return json_object_equal(json1, json2);
+            return json_object_equal(json1, json2, depth);
         case JSON_ARRAY:
-            return json_array_equal(json1, json2);
+            return json_array_equal(json1, json2, depth);
         case JSON_STRING:
             return json_string_equal(json1, json2);
         case JSON_INTEGER:
@@ -1075,21 +1085,24 @@
 
     if (hashtable_init(&parents_set))
         return NULL;
-    res = do_deep_copy(json, &parents_set);
+    res = do_deep_copy(json, &parents_set, 0);
     hashtable_close(&parents_set);
 
     return res;
 }
 
-json_t *do_deep_copy(const json_t *json, hashtable_t *parents) {
+json_t *do_deep_copy(const json_t *json, hashtable_t *parents, int depth) {
     if (!json)
         return NULL;
 
+    if (depth >= JSON_PARSER_MAX_DEPTH)
+        return NULL;
+
     switch (json_typeof(json)) {
         case JSON_OBJECT:
-            return json_object_deep_copy(json, parents);
+            return json_object_deep_copy(json, parents, depth);
         case JSON_ARRAY:
-            return json_array_deep_copy(json, parents);
+            return json_array_deep_copy(json, parents, depth);
             /* for the rest of the types, deep copying doesn't differ from
                shallow copying */
         case JSON_STRING:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/jansson-2.15.0/test/bin/json_process.c 
new/jansson-2.15.1/test/bin/json_process.c
--- old/jansson-2.15.0/test/bin/json_process.c  2024-03-31 21:03:18.000000000 
+0200
+++ new/jansson-2.15.1/test/bin/json_process.c  2026-07-01 20:34:38.000000000 
+0200
@@ -19,6 +19,10 @@
 #include <locale.h>
 #endif
 
+#if defined(_MSC_VER) && (_MSC_VER < 1900) && !defined(snprintf)
+#define snprintf _snprintf
+#endif
+
 #if _WIN32
 #include <fcntl.h> /* for _O_BINARY */
 #include <io.h>    /* for _setmode() */
@@ -119,13 +123,14 @@
     int ret;
     FILE *file;
 
-    sprintf(filename, "%s%c%s", path, dir_sep, fname);
+    snprintf(filename, sizeof(filename), "%s%c%s", path, dir_sep, fname);
     file = fopen(filename, "rb");
     if (!file) {
+        size_t len = strlen(filename);
         if (conf.strip)
-            strcat(filename, ".strip");
+            strncat(filename, ".strip", sizeof(filename) - len - 1);
         else
-            strcat(filename, ".normal");
+            strncat(filename, ".normal", sizeof(filename) - len - 1);
         file = fopen(filename, "rb");
     }
     if (!file) {
@@ -159,13 +164,13 @@
     json_t *json;
     json_error_t error;
 
-    sprintf(filename, "%s%cinput", test_path, dir_sep);
+    snprintf(filename, sizeof(filename), "%s%cinput", test_path, dir_sep);
     if (!(infile = fopen(filename, "rb"))) {
         fprintf(stderr, "Could not open \"%s\"\n", filename);
         return 2;
     }
 
-    sprintf(filename, "%s%cenv", test_path, dir_sep);
+    snprintf(filename, sizeof(filename), "%s%cenv", test_path, dir_sep);
     conffile = fopen(filename, "rb");
     if (conffile) {
         read_conf(conffile);
@@ -215,8 +220,8 @@
     fclose(infile);
 
     if (!json) {
-        sprintf(errstr, "%d %d %d\n%s\n", error.line, error.column, 
error.position,
-                error.text);
+        snprintf(errstr, sizeof(errstr), "%d %d %d\n%s\n", error.line, 
error.column,
+                 error.position, error.text);
 
         ret = cmpfile(errstr, test_path, "error");
         return ret;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/jansson-2.15.0/test/ossfuzz/Makefile.am 
new/jansson-2.15.1/test/ossfuzz/Makefile.am
--- old/jansson-2.15.0/test/ossfuzz/Makefile.am 2022-08-09 20:56:05.000000000 
+0200
+++ new/jansson-2.15.1/test/ossfuzz/Makefile.am 2026-07-01 20:34:38.000000000 
+0200
@@ -18,7 +18,9 @@
 
 if USE_OSSFUZZERS
 noinst_PROGRAMS += \
-       json_load_dump_fuzzer
+       json_load_dump_fuzzer \
+       json_pack_unpack_fuzzer \
+       json_equal_copy_fuzzer
 
 noinst_LIBRARIES += \
        libstandaloneengine.a
@@ -28,5 +30,13 @@
 json_load_dump_fuzzer_CXXFLAGS = $(AM_CXXFLAGS) $(FUZZ_FLAG)
 json_load_dump_fuzzer_LDFLAGS = $(AM_LDFLAGS) -static
 
+json_pack_unpack_fuzzer_SOURCES = json_pack_unpack_fuzzer.cc testinput.h
+json_pack_unpack_fuzzer_CXXFLAGS = $(AM_CXXFLAGS) $(FUZZ_FLAG)
+json_pack_unpack_fuzzer_LDFLAGS = $(AM_LDFLAGS) -static
+
+json_equal_copy_fuzzer_SOURCES = json_equal_copy_fuzzer.cc testinput.h
+json_equal_copy_fuzzer_CXXFLAGS = $(AM_CXXFLAGS) $(FUZZ_FLAG)
+json_equal_copy_fuzzer_LDFLAGS = $(AM_LDFLAGS) -static
+
 libstandaloneengine_a_SOURCES = standaloneengine.cc
 libstandaloneengine_a_CXXFLAGS = $(AM_CXXFLAGS)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/jansson-2.15.0/test/ossfuzz/json_equal_copy_fuzzer.cc 
new/jansson-2.15.1/test/ossfuzz/json_equal_copy_fuzzer.cc
--- old/jansson-2.15.0/test/ossfuzz/json_equal_copy_fuzzer.cc   1970-01-01 
01:00:00.000000000 +0100
+++ new/jansson-2.15.1/test/ossfuzz/json_equal_copy_fuzzer.cc   2026-07-01 
20:34:38.000000000 +0200
@@ -0,0 +1,111 @@
+/*
+ * json_equal_copy_fuzzer.cc
+ *
+ * Fuzz target for jansson equality and copying APIs.
+ * The existing json_load_dump_fuzzer covers json_loads/json_dumps only.
+ * This harness exercises the following uncovered paths:
+ *
+ *   json_loadb()       - length-bounded load (no NUL required)
+ *   json_equal()       - deep equality comparison
+ *   json_copy()        - shallow copy
+ *   json_deep_copy()   - recursive deep copy
+ *   json_object_update()          - merge two objects
+ *   json_object_update_existing() - update only existing keys
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "jansson.h"
+
+static uint8_t u8(const uint8_t **d, size_t *s) {
+    if (*s == 0)
+        return 0;
+    uint8_t v = **d;
+    (*d)++;
+    (*s)--;
+    return v;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+    if (size < 2)
+        return 0;
+
+    uint8_t op = u8(&data, &size);
+    uint8_t flag_byte = u8(&data, &size);
+
+    size_t load_flags = 0;
+    if (flag_byte & 0x01)
+        load_flags |= JSON_REJECT_DUPLICATES;
+    if (flag_byte & 0x02)
+        load_flags |= JSON_DECODE_ANY;
+    if (flag_byte & 0x04)
+        load_flags |= JSON_DISABLE_EOF_CHECK;
+    if (flag_byte & 0x08)
+        load_flags |= JSON_DECODE_INT_AS_REAL;
+    if (flag_byte & 0x10)
+        load_flags |= JSON_ALLOW_NUL;
+
+    /* Parse with json_loadb — does not require NUL termination */
+    json_error_t err;
+    json_t *root = json_loadb((const char *)data, size, load_flags, &err);
+    if (!root)
+        return 0;
+
+    switch (op % 5) {
+        case 0: {
+            /* Deep copy then compare for equality */
+            json_t *copy = json_deep_copy(root);
+            if (copy) {
+                json_equal(root, copy);
+                json_decref(copy);
+            }
+            break;
+        }
+        case 1: {
+            /* Shallow copy */
+            json_t *shallow = json_copy(root);
+            if (shallow) {
+                json_equal(root, shallow);
+                json_decref(shallow);
+            }
+            break;
+        }
+        case 2: {
+            /* Compare root with itself */
+            json_equal(root, root);
+            break;
+        }
+        case 3: {
+            /* json_object_update: merge root into a new empty object */
+            if (json_is_object(root)) {
+                json_t *target = json_object();
+                if (target) {
+                    json_object_update(target, root);
+                    json_decref(target);
+                }
+            }
+            break;
+        }
+        case 4: {
+            /* json_object_update_existing: only update keys present in target 
*/
+            if (json_is_object(root)) {
+                json_t *target = json_deep_copy(root);
+                if (target) {
+                    json_t *patch = json_deep_copy(root);
+                    if (patch) {
+                        json_object_update_existing(target, patch);
+                        json_decref(patch);
+                    }
+                    json_decref(target);
+                }
+            }
+            break;
+        }
+    }
+
+    json_decref(root);
+    return 0;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/jansson-2.15.0/test/ossfuzz/json_pack_unpack_fuzzer.cc 
new/jansson-2.15.1/test/ossfuzz/json_pack_unpack_fuzzer.cc
--- old/jansson-2.15.0/test/ossfuzz/json_pack_unpack_fuzzer.cc  1970-01-01 
01:00:00.000000000 +0100
+++ new/jansson-2.15.1/test/ossfuzz/json_pack_unpack_fuzzer.cc  2026-07-01 
20:34:38.000000000 +0200
@@ -0,0 +1,87 @@
+/*
+ * json_pack_unpack_fuzzer.cc
+ *
+ * Fuzz harness for jansson json_unpack() and json_deep_copy() paths.
+ * json_unpack() processes a format string + JSON value and extracts
+ * typed fields — it involves non-trivial string/type dispatch that
+ * is not exercised by the load/dump fuzzer.
+ *
+ * OSS-Fuzz build: compiled via test/ossfuzz/ossfuzz.sh.
+ */
+#include <stdint.h>
+#include <stddef.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "jansson.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+    if (size < 2)
+        return 0;
+
+    /* Use first byte to select format variant, rest as JSON input */
+    uint8_t variant = data[0] % 8;
+    const char *json_str = (const char *)(data + 1);
+    size_t json_len = size - 1;
+
+    json_error_t error;
+    json_t *root = json_loadb(json_str, json_len,
+                               JSON_DECODE_ANY | JSON_ALLOW_NUL, &error);
+    if (root == NULL)
+        return 0;
+
+    /* Exercise json_deep_copy on whatever we parsed */
+    json_t *copy = json_deep_copy(root);
+    if (copy != NULL)
+        json_decref(copy);
+
+    /* Exercise json_dumps with various flags */
+    const int flag_sets[] = {
+        0,
+        JSON_COMPACT,
+        JSON_ENSURE_ASCII,
+        JSON_SORT_KEYS,
+        JSON_COMPACT | JSON_ENSURE_ASCII,
+    };
+    int flags = flag_sets[variant % 5];
+    char *dumped = json_dumps(root, flags);
+    if (dumped != NULL) {
+        /* Re-load the dumped output for round-trip check */
+        json_t *reparsed = json_loads(dumped, 0, NULL);
+        if (reparsed != NULL)
+            json_decref(reparsed);
+        free(dumped);
+    }
+
+    /* Exercise json_unpack with simple format strings if root is an object */
+    if (json_is_object(root)) {
+        json_t *val = NULL;
+        const char *key = NULL;
+        /* Unpack first key-value pair */
+        void *iter = json_object_iter(root);
+        if (iter != NULL) {
+            key = json_object_iter_key(iter);
+            val  = json_object_iter_value(iter);
+            (void)key;
+            (void)val;
+        }
+
+        /* json_unpack with "o" format — extract object */
+        json_t *out_obj = NULL;
+        json_unpack(root, "o", &out_obj);
+
+        /* json_unpack with "{s?o}" — optional key lookup */
+        json_t *field = NULL;
+        json_unpack(root, "{s?o}", "data", &field);
+    }
+
+    /* Exercise json_unpack on array */
+    if (json_is_array(root) && json_array_size(root) > 0) {
+        json_t *first = NULL;
+        json_unpack(root, "[o!]", &first);
+    }
+
+    json_decref(root);
+    return 0;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/jansson-2.15.0/test/suites/api/test_copy.c 
new/jansson-2.15.1/test/suites/api/test_copy.c
--- old/jansson-2.15.0/test/suites/api/test_copy.c      2022-08-09 
20:56:05.000000000 +0200
+++ new/jansson-2.15.1/test/suites/api/test_copy.c      2026-07-01 
20:34:38.000000000 +0200
@@ -364,6 +364,25 @@
     json_decref(json);
 }
 
+static void test_deep_copy_max_depth(void) {
+    json_t *json;
+    json_t *copy;
+    int i;
+
+    json = json_array();
+    for (i = 1; i < JSON_PARSER_MAX_DEPTH + 100; i++) {
+        json_t *outer = json_array();
+        json_array_append_new(outer, json);
+        json = outer;
+    }
+
+    copy = json_deep_copy(json);
+    if (copy)
+        fail("json_deep_copy didn't fail for a too deeply nested structure!");
+
+    json_decref(json);
+}
+
 static void run_tests() {
     test_copy_simple();
     test_deep_copy_simple();
@@ -372,4 +391,5 @@
     test_copy_object();
     test_deep_copy_object();
     test_deep_copy_circular_references();
+    test_deep_copy_max_depth();
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/jansson-2.15.0/test/suites/api/test_dump.c 
new/jansson-2.15.1/test/suites/api/test_dump.c
--- old/jansson-2.15.0/test/suites/api/test_dump.c      2022-08-09 
20:56:05.000000000 +0200
+++ new/jansson-2.15.1/test/suites/api/test_dump.c      2026-07-01 
20:34:38.000000000 +0200
@@ -297,6 +297,39 @@
     }
 }
 
+static json_t *build_nested_array(int depth) {
+    json_t *json = json_array();
+    int i;
+
+    for (i = 1; i < depth; i++) {
+        json_t *outer = json_array();
+        json_array_append_new(outer, json);
+        json = outer;
+    }
+
+    return json;
+}
+
+static void max_depth() {
+    json_t *json;
+    char *result;
+
+    /* A structure nested exactly to the limit must still serialize. */
+    json = build_nested_array(JSON_PARSER_MAX_DEPTH);
+    result = json_dumps(json, 0);
+    if (!result)
+        fail("json_dumps failed for a structure within the depth limit");
+    free(result);
+    json_decref(json);
+
+    /* A structure nested deeper than the limit must fail cleanly rather
+       than overflow the stack. */
+    json = build_nested_array(JSON_PARSER_MAX_DEPTH + 100);
+    if (json_dumps(json, 0) != NULL)
+        fail("json_dumps didn't fail for a too deeply nested structure");
+    json_decref(json);
+}
+
 static void run_tests() {
     encode_null();
     encode_twice();
@@ -308,4 +341,5 @@
     dumpb();
     dumpfd();
     embed();
+    max_depth();
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/jansson-2.15.0/test/suites/api/test_equal.c 
new/jansson-2.15.1/test/suites/api/test_equal.c
--- old/jansson-2.15.0/test/suites/api/test_equal.c     2022-08-09 
20:56:05.000000000 +0200
+++ new/jansson-2.15.1/test/suites/api/test_equal.c     2026-07-01 
20:34:38.000000000 +0200
@@ -194,9 +194,34 @@
     json_decref(value3);
 }
 
+static void test_equal_max_depth() {
+    json_t *value1, *value2;
+    int i;
+
+    value1 = json_array();
+    value2 = json_array();
+    for (i = 1; i < JSON_PARSER_MAX_DEPTH + 100; i++) {
+        json_t *outer1 = json_array();
+        json_t *outer2 = json_array();
+        json_array_append_new(outer1, value1);
+        json_array_append_new(outer2, value2);
+        value1 = outer1;
+        value2 = outer2;
+    }
+
+    /* The structures are structurally equal, but exceed the depth limit;
+       json_equal must bail out rather than overflow the stack. */
+    if (json_equal(value1, value2))
+        fail("json_equal didn't bail out for a too deeply nested structure");
+
+    json_decref(value1);
+    json_decref(value2);
+}
+
 static void run_tests() {
     test_equal_simple();
     test_equal_array();
     test_equal_object();
     test_equal_complex();
+    test_equal_max_depth();
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/jansson-2.15.0/test/suites/api/test_pack.c 
new/jansson-2.15.1/test/suites/api/test_pack.c
--- old/jansson-2.15.0/test/suites/api/test_pack.c      2022-08-09 
20:56:05.000000000 +0200
+++ new/jansson-2.15.1/test/suites/api/test_pack.c      2026-07-01 
20:34:38.000000000 +0200
@@ -167,6 +167,12 @@
         fail("json_pack string and length (int) refcount failed");
     json_decref(value);
 
+    /* negative length (int) is rejected */
+    if (json_pack_ex(&error, 0, "s#", "test", -2))
+        fail("json_pack failed to catch negative length");
+    check_error(json_error_invalid_argument, "Invalid length for string: -2", 
"<args>", 1,
+                2, 2);
+
     /* string and length (size_t), non-NUL terminated string */
     value = json_pack("s%", buffer, (size_t)4);
     if (!json_is_string(value) || strcmp("test", json_string_value(value)))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/jansson-2.15.0/test/suites/api/test_unpack.c 
new/jansson-2.15.1/test/suites/api/test_unpack.c
--- old/jansson-2.15.0/test/suites/api/test_unpack.c    2022-08-09 
20:56:05.000000000 +0200
+++ new/jansson-2.15.1/test/suites/api/test_unpack.c    2026-07-01 
20:34:38.000000000 +0200
@@ -263,6 +263,57 @@
     json_decref(j);
     json_decref(j2);
 
+    /* invalid types in objects */
+    j = json_pack("{si}", "bar", 42);
+    j2 = json_pack("{ss}", "bar", "foo");
+    if (!json_unpack_ex(j, &error, 0, "{ss}", "bar"))
+        fail("json_unpack failed to catch invalid type in object");
+    check_error(json_error_wrong_type, "Expected string, got integer for key 
bar",
+                "<validation>", 1, 3, 3);
+
+    if (!json_unpack_ex(j, &error, 0, "{sn}", "bar"))
+        fail("json_unpack failed to catch invalid type in object");
+    check_error(json_error_wrong_type, "Expected null, got integer for key 
bar",
+                "<validation>", 1, 3, 3);
+
+    if (!json_unpack_ex(j, &error, 0, "{sb}", "bar"))
+        fail("json_unpack failed to catch invalid type in object");
+    check_error(json_error_wrong_type, "Expected true or false, got integer 
for key bar",
+                "<validation>", 1, 3, 3);
+
+    if (!json_unpack_ex(j2, &error, 0, "{si}", "bar"))
+        fail("json_unpack failed to catch invalid type in object");
+    check_error(json_error_wrong_type, "Expected integer, got string for key 
bar",
+                "<validation>", 1, 3, 3);
+
+    if (!json_unpack_ex(j2, &error, 0, "{sI}", "bar"))
+        fail("json_unpack failed to catch invalid type in object");
+    check_error(json_error_wrong_type, "Expected integer, got string for key 
bar",
+                "<validation>", 1, 3, 3);
+
+    if (!json_unpack_ex(j, &error, 0, "{sf}", "bar"))
+        fail("json_unpack failed to catch invalid type in object");
+    check_error(json_error_wrong_type, "Expected real, got integer for key 
bar",
+                "<validation>", 1, 3, 3);
+
+    if (!json_unpack_ex(j2, &error, 0, "{sF}", "bar"))
+        fail("json_unpack failed to catch invalid type in object");
+    check_error(json_error_wrong_type, "Expected real or integer, got string 
for key bar",
+                "<validation>", 1, 3, 3);
+
+    if (!json_unpack_ex(j, &error, 0, "{s[i]}", "bar"))
+        fail("json_unpack failed to catch invalid type in object");
+    check_error(json_error_wrong_type, "Expected array, got integer for key 
bar",
+                "<validation>", 1, 3, 3);
+
+    if (!json_unpack_ex(j, &error, 0, "{s{si}}", "bar", "foo"))
+        fail("json_unpack failed to catch invalid type in object");
+    check_error(json_error_wrong_type, "Expected object, got integer for key 
bar",
+                "<validation>", 1, 3, 3);
+
+    json_decref(j);
+    json_decref(j2);
+
     /* Array index out of range */
     j = json_pack("[i]", 1);
     if (!json_unpack_ex(j, &error, 0, "[ii]", &i1, &i2))

Reply via email to