Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package msgpack-cxx for openSUSE:Factory 
checked in at 2026-08-27 18:52:09
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/msgpack-cxx (Old)
 and      /work/SRC/openSUSE:Factory/.msgpack-cxx.new.1265 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "msgpack-cxx"

Thu Aug 27 18:52:09 2026 rev:8 rq:1373897 version:9.0.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/msgpack-cxx/msgpack-cxx.changes  2026-05-31 
18:31:16.043431531 +0200
+++ /work/SRC/openSUSE:Factory/.msgpack-cxx.new.1265/msgpack-cxx.changes        
2026-08-27 18:55:30.987252673 +0200
@@ -1,0 +2,14 @@
+Wed Aug 26 19:58:02 UTC 2026 - Jan Engelhardt <[email protected]>
+
+- Update to release 9.0.0
+  * Fix out-of-bounds reads and writes, heap buffer overflows,
+    double frees, use-after-frees, nullptr dereferencing and
+    integer overflows.
+  * Breaking change: Fix ext32 max size truncation on 64-bit by
+    widening visit_ext size to size_t.
+    If you have a custom visitor that implements visit_ext(),
+    widen its size parameter from uint32_t to std::size_t:
+    Before: bool visit_ext(const char *v, uint32_t size)
+    After:  bool visit_ext(const char *v, std::size_t size)
+
+-------------------------------------------------------------------

Old:
----
  msgpack-cxx-8.0.0.tar.gz

New:
----
  msgpack-cxx-9.0.0.tar.gz

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

Other differences:
------------------
++++++ msgpack-cxx.spec ++++++
--- /var/tmp/diff_new_pack.xYxjDp/_old  2026-08-27 18:55:31.664276309 +0200
+++ /var/tmp/diff_new_pack.xYxjDp/_new  2026-08-27 18:55:31.665276344 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           msgpack-cxx
-Version:        8.0.0
+Version:        9.0.0
 Release:        0
 Summary:        Object serialization library for cross-language communication 
(C++ interface)
 License:        BSL-1.0

++++++ _scmsync.obsinfo ++++++
--- /var/tmp/diff_new_pack.xYxjDp/_old  2026-08-27 18:55:31.721278299 +0200
+++ /var/tmp/diff_new_pack.xYxjDp/_new  2026-08-27 18:55:31.724278404 +0200
@@ -1,5 +1,5 @@
-mtime: 1780241979
-commit: 7933327211a3ca1fe99b8f6afe791e1acaa946287734c9f268304472e63a65cd
+mtime: 1787775230
+commit: 815d2a72cd42c686d2e46effa413858e67a92b858b9a9bd92ed4d4958504933d
 url: https://src.opensuse.org/clibs/msgpack-cxx
 revision: master
 

++++++ build.specials.obscpio ++++++

++++++ build.specials.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/.gitignore new/.gitignore
--- old/.gitignore      1970-01-01 01:00:00.000000000 +0100
+++ new/.gitignore      2026-08-26 22:13:50.000000000 +0200
@@ -0,0 +1 @@
+.osc

++++++ msgpack-cxx-8.0.0.tar.gz -> msgpack-cxx-9.0.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msgpack-cxx-8.0.0/README.md 
new/msgpack-cxx-9.0.0/README.md
--- old/msgpack-cxx-8.0.0/README.md     2026-05-30 12:31:43.000000000 +0200
+++ new/msgpack-cxx-9.0.0/README.md     2026-08-25 10:56:00.000000000 +0200
@@ -1,7 +1,7 @@
 `msgpack` for C++
 ===================
 
-Version 8.0.0 [![Build 
Status](https://github.com/msgpack/msgpack-c/workflows/CI/badge.svg?branch=cpp_master)](https://github.com/msgpack/msgpack-c/actions)
 [![Build 
status](https://ci.appveyor.com/api/projects/status/8kstcgt79qj123mw/branch/cpp_master?svg=true)](https://ci.appveyor.com/project/redboltz/msgpack-c/branch/cpp_master)
+Version 9.0.0 [![Build 
Status](https://github.com/msgpack/msgpack-c/workflows/CI/badge.svg?branch=cpp_master)](https://github.com/msgpack/msgpack-c/actions)
 [![Build 
status](https://ci.appveyor.com/api/projects/status/8kstcgt79qj123mw/branch/cpp_master?svg=true)](https://ci.appveyor.com/project/redboltz/msgpack-c/branch/cpp_master)
 
[![codecov](https://codecov.io/gh/msgpack/msgpack-c/branch/cpp_master/graph/badge.svg)](https://app.codecov.io/gh/msgpack/msgpack-c/tree/cpp_master)
 
 It's like JSON but smaller and faster.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msgpack-cxx-8.0.0/erb/v1/cpp03_zone.hpp.erb 
new/msgpack-cxx-9.0.0/erb/v1/cpp03_zone.hpp.erb
--- old/msgpack-cxx-8.0.0/erb/v1/cpp03_zone.hpp.erb     2023-11-23 
05:04:23.000000000 +0100
+++ new/msgpack-cxx-9.0.0/erb/v1/cpp03_zone.hpp.erb     2026-08-25 
10:56:00.000000000 +0200
@@ -249,6 +249,10 @@
         sz = tmp_sz;
     }
 
+    if((sizeof(chunk) + sz) < sz) {
+        throw std::bad_alloc();
+    }
+
     chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + sz));
     if (!c) throw std::bad_alloc();
 
@@ -283,8 +287,16 @@
 {
     using std::swap;
     swap(m_chunk_size, o.m_chunk_size);
-    swap(m_chunk_list, o.m_chunk_list);
-    swap(m_finalizer_array, o.m_finalizer_array);
+    // Swap the internal pointers directly. std::swap on chunk_list /
+    // finalizer_array would construct a temporary and run its owning
+    // destructor (freeing chunks and executing finalizers) on memory that
+    // has just been transferred to the other zone -> double free / UAF.
+    swap(m_chunk_list.m_free, o.m_chunk_list.m_free);
+    swap(m_chunk_list.m_ptr,  o.m_chunk_list.m_ptr);
+    swap(m_chunk_list.m_head, o.m_chunk_list.m_head);
+    swap(m_finalizer_array.m_tail,  o.m_finalizer_array.m_tail);
+    swap(m_finalizer_array.m_end,   o.m_finalizer_array.m_end);
+    swap(m_finalizer_array.m_array, o.m_finalizer_array.m_array);
 }
 
 template <typename T>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/msgpack-cxx-8.0.0/include/msgpack/v1/adaptor/array_ref.hpp 
new/msgpack-cxx-9.0.0/include/msgpack/v1/adaptor/array_ref.hpp
--- old/msgpack-cxx-8.0.0/include/msgpack/v1/adaptor/array_ref.hpp      
2023-07-08 05:21:22.000000000 +0200
+++ new/msgpack-cxx-9.0.0/include/msgpack/v1/adaptor/array_ref.hpp      
2026-08-25 10:56:00.000000000 +0200
@@ -78,10 +78,8 @@
     template <typename U>
     bool operator==(array_ref<U> const& t) const {
         if (N != t.size()) return false;
-        T const* pself = data;
-        U const* pother = t.data;
-        for (; pself != &data[N]; ++pself, ++pother) {
-            if (*pself != *pother) return false;
+        for (std::size_t i = 0; i < N; ++i) {
+            if (!(data[i] == t.data[i])) return false;
         }
         return true;
     }
@@ -92,28 +90,32 @@
     template <typename U>
     bool operator< (array_ref<U> const& t) const
     {
-        T const* pself = data;
-        U const* pother = t.data;
-        for (; pself != &data[N] && pother != t.data[t.size()]; ++pself, 
++pother) {
-            if (*pself < *pother) return true;
+        std::size_t n = (N < t.size()) ? N : t.size();
+        for (std::size_t i = 0; i < n; ++i) {
+            if (data[i] < t.data[i]) return true;
+            if (t.data[i] < data[i]) return false;
         }
-        if (N < t.size()) return true;
-        return false;
+        return N < t.size();
     }
     template <typename U>
     bool operator> (array_ref<U> const& t) const
     {
-        return t.data < data;
+        std::size_t n = (N < t.size()) ? N : t.size();
+        for (std::size_t i = 0; i < n; ++i) {
+            if (t.data[i] < data[i]) return true;
+            if (data[i] < t.data[i]) return false;
+        }
+        return t.size() < N;
     }
     template <typename U>
     bool operator<= (array_ref<U> const& t) const
     {
-        return !(t.data < data);
+        return !(*this > t);
     }
     template <typename U>
     bool operator>= (array_ref<U> const& t) const
     {
-        return !(data < t.data);
+        return !(*this < t);
     }
 };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/msgpack-cxx-8.0.0/include/msgpack/v1/adaptor/carray.hpp 
new/msgpack-cxx-9.0.0/include/msgpack/v1/adaptor/carray.hpp
--- old/msgpack-cxx-8.0.0/include/msgpack/v1/adaptor/carray.hpp 2023-07-08 
05:21:22.000000000 +0200
+++ new/msgpack-cxx-9.0.0/include/msgpack/v1/adaptor/carray.hpp 2026-08-25 
10:56:00.000000000 +0200
@@ -30,11 +30,9 @@
         if (o.via.array.size > N) { throw msgpack::type_error(); }
         msgpack::object* p = o.via.array.ptr;
         msgpack::object* const pend = o.via.array.ptr + o.via.array.size;
-        do {
+        for (; p < pend; ++p, ++v) {
             p->convert(*v);
-            ++p;
-            ++v;
-        } while(p < pend);
+        }
         return o;
     }
 };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/msgpack-cxx-8.0.0/include/msgpack/v1/adaptor/cpp11/array_char.hpp 
new/msgpack-cxx-9.0.0/include/msgpack/v1/adaptor/cpp11/array_char.hpp
--- old/msgpack-cxx-8.0.0/include/msgpack/v1/adaptor/cpp11/array_char.hpp       
2023-07-08 05:21:22.000000000 +0200
+++ new/msgpack-cxx-9.0.0/include/msgpack/v1/adaptor/cpp11/array_char.hpp       
2026-08-25 10:56:00.000000000 +0200
@@ -36,7 +36,7 @@
             break;
         case msgpack::type::STR:
             if(o.via.str.size > N) { throw msgpack::type_error(); }
-            std::memcpy(v.data(), o.via.str.ptr, N);
+            std::memcpy(v.data(), o.via.str.ptr, o.via.str.size);
             break;
         default:
             throw msgpack::type_error();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/msgpack-cxx-8.0.0/include/msgpack/v1/adaptor/cpp11/array_unsigned_char.hpp 
new/msgpack-cxx-9.0.0/include/msgpack/v1/adaptor/cpp11/array_unsigned_char.hpp
--- 
old/msgpack-cxx-8.0.0/include/msgpack/v1/adaptor/cpp11/array_unsigned_char.hpp  
    2023-07-08 05:21:22.000000000 +0200
+++ 
new/msgpack-cxx-9.0.0/include/msgpack/v1/adaptor/cpp11/array_unsigned_char.hpp  
    2026-08-25 10:56:00.000000000 +0200
@@ -36,7 +36,7 @@
             break;
         case msgpack::type::STR:
             if(o.via.str.size > N) { throw msgpack::type_error(); }
-            std::memcpy(v.data(), o.via.str.ptr, N);
+            std::memcpy(v.data(), o.via.str.ptr, o.via.str.size);
             break;
         default:
             throw msgpack::type_error();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/msgpack-cxx-8.0.0/include/msgpack/v1/adaptor/cpp11/tuple.hpp 
new/msgpack-cxx-9.0.0/include/msgpack/v1/adaptor/cpp11/tuple.hpp
--- old/msgpack-cxx-8.0.0/include/msgpack/v1/adaptor/cpp11/tuple.hpp    
2023-07-08 05:21:22.000000000 +0200
+++ new/msgpack-cxx-9.0.0/include/msgpack/v1/adaptor/cpp11/tuple.hpp    
2026-08-25 10:56:00.000000000 +0200
@@ -114,6 +114,7 @@
     std::tuple<Args...> operator()(
         msgpack::object const& o) const {
         if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
+        if (o.via.array.size < sizeof...(Args)) { throw msgpack::type_error(); 
}
         return StdTupleAs<Args...>::as(o);
     }
 };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/msgpack-cxx-8.0.0/include/msgpack/v1/adaptor/detail/cpp11_msgpack_tuple.hpp 
new/msgpack-cxx-9.0.0/include/msgpack/v1/adaptor/detail/cpp11_msgpack_tuple.hpp
--- 
old/msgpack-cxx-8.0.0/include/msgpack/v1/adaptor/detail/cpp11_msgpack_tuple.hpp 
    2023-07-08 05:21:22.000000000 +0200
+++ 
new/msgpack-cxx-9.0.0/include/msgpack/v1/adaptor/detail/cpp11_msgpack_tuple.hpp 
    2026-08-25 10:56:00.000000000 +0200
@@ -131,7 +131,8 @@
     static void convert (
         msgpack::object const& o,
         Tuple& v) {
-        o.via.array.ptr[0].convert<typename 
std::remove_reference<decltype(v.template get<0>())>::type>(v.template 
get<0>());
+        if (o.via.array.size >= 1)
+            o.via.array.ptr[0].convert<typename 
std::remove_reference<decltype(v.template get<0>())>::type>(v.template 
get<0>());
     }
 };
 
@@ -150,6 +151,7 @@
     msgpack::type::tuple<Args...> operator()(
         msgpack::object const& o) const {
         if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
+        if (o.via.array.size < sizeof...(Args)) { throw msgpack::type_error(); 
}
         return MsgpackTupleAs<Args...>::as(o);
     }
 };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msgpack-cxx-8.0.0/include/msgpack/v1/adaptor/ext.hpp 
new/msgpack-cxx-9.0.0/include/msgpack/v1/adaptor/ext.hpp
--- old/msgpack-cxx-8.0.0/include/msgpack/v1/adaptor/ext.hpp    2023-07-08 
05:21:22.000000000 +0200
+++ new/msgpack-cxx-9.0.0/include/msgpack/v1/adaptor/ext.hpp    2026-08-25 
10:56:00.000000000 +0200
@@ -149,7 +149,7 @@
     }
 
     bool operator== (const ext_ref& x) const {
-        return m_size == x.m_size && std::memcmp(m_ptr, x.m_ptr, m_size) == 0;
+        return m_size == x.m_size && std::memcmp(m_ptr, x.m_ptr, m_size + 1) 
== 0;
     }
 
     bool operator!= (const ext_ref& x) const {
@@ -159,13 +159,13 @@
     bool operator< (const ext_ref& x) const {
         if (m_size < x.m_size) return true;
         if (m_size > x.m_size) return false;
-        return std::memcmp(m_ptr, x.m_ptr, m_size) < 0;
+        return std::memcmp(m_ptr, x.m_ptr, m_size + 1) < 0;
     }
 
     bool operator> (const ext_ref& x) const {
         if (m_size > x.m_size) return true;
         if (m_size < x.m_size) return false;
-        return std::memcmp(m_ptr, x.m_ptr, m_size) > 0;
+        return std::memcmp(m_ptr, x.m_ptr, m_size + 1) > 0;
     }
 
 private:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/msgpack-cxx-8.0.0/include/msgpack/v1/detail/cpp03_zone.hpp 
new/msgpack-cxx-9.0.0/include/msgpack/v1/detail/cpp03_zone.hpp
--- old/msgpack-cxx-8.0.0/include/msgpack/v1/detail/cpp03_zone.hpp      
2024-11-02 02:56:19.000000000 +0100
+++ new/msgpack-cxx-9.0.0/include/msgpack/v1/detail/cpp03_zone.hpp      
2026-08-25 10:56:00.000000000 +0200
@@ -294,6 +294,10 @@
         sz = tmp_sz;
     }
 
+    if((sizeof(chunk) + sz) < sz) {
+        throw std::bad_alloc();
+    }
+
     chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + sz));
     if (!c) throw std::bad_alloc();
 
@@ -328,8 +332,16 @@
 {
     using std::swap;
     swap(m_chunk_size, o.m_chunk_size);
-    swap(m_chunk_list, o.m_chunk_list);
-    swap(m_finalizer_array, o.m_finalizer_array);
+    // Swap the internal pointers directly. std::swap on chunk_list /
+    // finalizer_array would construct a temporary and run its owning
+    // destructor (freeing chunks and executing finalizers) on memory that
+    // has just been transferred to the other zone -> double free / UAF.
+    swap(m_chunk_list.m_free, o.m_chunk_list.m_free);
+    swap(m_chunk_list.m_ptr,  o.m_chunk_list.m_ptr);
+    swap(m_chunk_list.m_head, o.m_chunk_list.m_head);
+    swap(m_finalizer_array.m_tail,  o.m_finalizer_array.m_tail);
+    swap(m_finalizer_array.m_end,   o.m_finalizer_array.m_end);
+    swap(m_finalizer_array.m_array, o.m_finalizer_array.m_array);
 }
 
 template <typename T>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/msgpack-cxx-8.0.0/include/msgpack/v1/detail/cpp11_zone.hpp 
new/msgpack-cxx-9.0.0/include/msgpack/v1/detail/cpp11_zone.hpp
--- old/msgpack-cxx-8.0.0/include/msgpack/v1/detail/cpp11_zone.hpp      
2023-11-23 05:04:23.000000000 +0100
+++ new/msgpack-cxx-9.0.0/include/msgpack/v1/detail/cpp11_zone.hpp      
2026-08-25 10:56:00.000000000 +0200
@@ -150,6 +150,8 @@
         chunk_list(chunk_list&& other) noexcept
             :m_free(other.m_free), m_ptr(other.m_ptr), m_head(other.m_head)
         {
+            other.m_free = 0;
+            other.m_ptr  = MSGPACK_NULLPTR;
             other.m_head = MSGPACK_NULLPTR;
         }
         chunk_list& operator=(chunk_list&& other) noexcept
@@ -208,7 +210,18 @@
     T* allocate(Args... args);
 
     zone(zone&&) = default;
-    zone& operator=(zone&&) = default;
+    zone& operator=(zone&& other) {
+        if (this != &other) {
+            // Destroy in the correct order: run finalizers first (while our
+            // chunks are still alive), then release our chunks. A defaulted
+            // move-assignment would free the chunks before the finalizers run,
+            // causing use-after-free of zone-allocated objects.
+            m_finalizer_array = std::move(other.m_finalizer_array);
+            m_chunk_list = std::move(other.m_chunk_list);
+            m_chunk_size = other.m_chunk_size;
+        }
+        return *this;
+    }
     zone(const zone&) = delete;
     zone& operator=(const zone&) = delete;
 
@@ -281,6 +294,10 @@
         sz = tmp_sz;
     }
 
+    if((sizeof(chunk) + sz) < sz) {
+        throw std::bad_alloc();
+    }
+
     chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + sz));
     if (!c) throw std::bad_alloc();
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msgpack-cxx-8.0.0/include/msgpack/v1/object.hpp 
new/msgpack-cxx-9.0.0/include/msgpack/v1/object.hpp
--- old/msgpack-cxx-8.0.0/include/msgpack/v1/object.hpp 2026-05-29 
12:20:58.000000000 +0200
+++ new/msgpack-cxx-9.0.0/include/msgpack/v1/object.hpp 2026-08-25 
10:56:00.000000000 +0200
@@ -265,7 +265,7 @@
                 break;
             case msgpack::type::EXT:
                 
msgpack::detail::check_container_size<sizeof(std::size_t)>(m_current->via.ext.size);
-                if (!v.visit_ext(m_current->via.ext.ptr, 
m_current->via.ext.size + 1)) return;
+                if (!v.visit_ext(m_current->via.ext.ptr, 
static_cast<std::size_t>(m_current->via.ext.size) + 1)) return;
                 break;
             case msgpack::type::ARRAY:
                 if (!v.start_array(m_current->via.array.size)) return;
@@ -351,9 +351,9 @@
         m_packer.pack_bin_body(v, size);
         return true;
     }
-    bool visit_ext(const char* v, uint32_t size) {
+    bool visit_ext(const char* v, std::size_t size) {
         m_packer.pack_ext(size - 1, static_cast<int8_t>(*v));
-        m_packer.pack_ext_body(v + 1, size - 1);
+        m_packer.pack_ext_body(v + 1, static_cast<uint32_t>(size - 1));
         return true;
     }
     bool start_array(uint32_t num_elements) {
@@ -470,7 +470,7 @@
         m_os << "\"BIN(size:" << size << ")\"";
         return true;
     }
-    bool visit_ext(const char* v, uint32_t size) {
+    bool visit_ext(const char* v, std::size_t size) {
         if (size == 0) {
             m_os << "\"EXT(size:0)\"";
         }
@@ -560,7 +560,7 @@
         m_size += msgpack::aligned_size(size, MSGPACK_ZONE_ALIGNOF(char));
         return true;
     }
-    bool visit_ext(const char*, uint32_t size) {
+    bool visit_ext(const char*, std::size_t size) {
         m_size += msgpack::aligned_size(size, MSGPACK_ZONE_ALIGNOF(char));
         return true;
     }
@@ -741,12 +741,12 @@
             std::memcpy(ptr, v, size);
             return true;
         }
-        bool visit_ext(const char* v, uint32_t size) {
+        bool visit_ext(const char* v, std::size_t size) {
             m_ptr->type = msgpack::type::EXT;
 
             // v contains type but length(size) doesn't count the type byte.
             // See 
https://github.com/msgpack/msgpack/blob/master/spec.md#ext-format-family
-            m_ptr->via.ext.size = size - 1;
+            m_ptr->via.ext.size = static_cast<uint32_t>(size - 1);
 
             char* ptr = static_cast<char*>(m_zone.allocate_align(size, 
MSGPACK_ZONE_ALIGNOF(char)));
             m_ptr->via.ext.ptr = ptr;
@@ -941,7 +941,7 @@
         }
         return true;
     }
-    bool visit_ext(const char* v, uint32_t size) {
+    bool visit_ext(const char* v, std::size_t size) {
         if (m_ptr->type != msgpack::type::EXT ||
             m_ptr->via.ext.size != size - 1 ||
             std::memcmp(m_ptr->via.ext.ptr, v, size) != 0) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msgpack-cxx-8.0.0/include/msgpack/v1/unpack.hpp 
new/msgpack-cxx-9.0.0/include/msgpack/v1/unpack.hpp
--- old/msgpack-cxx-8.0.0/include/msgpack/v1/unpack.hpp 2023-08-29 
16:27:11.000000000 +0200
+++ new/msgpack-cxx-9.0.0/include/msgpack/v1/unpack.hpp 2026-08-25 
10:56:00.000000000 +0200
@@ -21,6 +21,7 @@
 #include "msgpack/assert.hpp"
 
 #include <memory>
+#include <limits>
 
 
 #if !defined(MSGPACK_USE_CPP03)
@@ -166,12 +167,12 @@
 inline void unpack_str(unpack_user& u, const char* p, uint32_t l, 
msgpack::object& o)
 {
     o.type = msgpack::type::STR;
+    if (l > u.limit().str()) throw msgpack::str_size_overflow("str size 
overflow");
     if (u.reference_func() && u.reference_func()(o.type, l, u.user_data())) {
         o.via.str.ptr = p;
         u.set_referenced(true);
     }
     else if (l > 0) {
-        if (l > u.limit().str()) throw msgpack::str_size_overflow("str size 
overflow");
         char* tmp = static_cast<char*>(u.zone().allocate_align(l, 
MSGPACK_ZONE_ALIGNOF(char)));
         std::memcpy(tmp, p, l);
         o.via.str.ptr = tmp;
@@ -185,12 +186,12 @@
 inline void unpack_bin(unpack_user& u, const char* p, uint32_t l, 
msgpack::object& o)
 {
     o.type = msgpack::type::BIN;
+    if (l > u.limit().bin()) throw msgpack::bin_size_overflow("bin size 
overflow");
     if (u.reference_func() && u.reference_func()(o.type, l, u.user_data())) {
         o.via.bin.ptr = p;
         u.set_referenced(true);
     }
     else if (l > 0) {
-        if (l > u.limit().bin()) throw msgpack::bin_size_overflow("bin size 
overflow");
         char* tmp = static_cast<char*>(u.zone().allocate_align(l, 
MSGPACK_ZONE_ALIGNOF(char)));
         std::memcpy(tmp, p, l);
         o.via.bin.ptr = tmp;
@@ -204,12 +205,12 @@
 inline void unpack_ext(unpack_user& u, const char* p, std::size_t l, 
msgpack::object& o)
 {
     o.type = msgpack::type::EXT;
+    if (l > u.limit().ext()) throw msgpack::ext_size_overflow("ext size 
overflow");
     if (u.reference_func() && u.reference_func()(o.type, l, u.user_data())) {
         o.via.ext.ptr = p;
         u.set_referenced(true);
     }
     else {
-        if (l > u.limit().ext()) throw msgpack::ext_size_overflow("ext size 
overflow");
         char* tmp = static_cast<char*>(u.zone().allocate_align(l, 
MSGPACK_ZONE_ALIGNOF(char)));
         std::memcpy(tmp, p, l);
         o.via.ext.ptr = tmp;
@@ -1104,8 +1105,10 @@
 }
 
 inline unpacker& unpacker::operator=(unpacker&& other) {
-    this->~unpacker();
-    new (this) unpacker(std::move(other));
+    if (this != &other) {
+        this->~unpacker();
+        new (this) unpacker(std::move(other));
+    }
     return *this;
 }
 
@@ -1138,6 +1141,9 @@
     }
 
     if(m_off == COUNTER_SIZE) {
+        if(size > std::numeric_limits<std::size_t>::max() - m_used) {
+            throw std::bad_alloc();
+        }
         std::size_t next_size = (m_used + m_free) * 2;    // include 
COUNTER_SIZE
         while(next_size < size + m_used) {
             std::size_t tmp_next_size = next_size * 2;
@@ -1159,6 +1165,9 @@
     } else {
         std::size_t next_size = m_initial_buffer_size;  // include COUNTER_SIZE
         std::size_t not_parsed = m_used - m_off;
+        if(size > std::numeric_limits<std::size_t>::max() - not_parsed - 
COUNTER_SIZE) {
+            throw std::bad_alloc();
+        }
         while(next_size < size + not_parsed + COUNTER_SIZE) {
             std::size_t tmp_next_size = next_size * 2;
             if (tmp_next_size <= next_size) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msgpack-cxx-8.0.0/include/msgpack/v1/vrefbuffer.hpp 
new/msgpack-cxx-9.0.0/include/msgpack/v1/vrefbuffer.hpp
--- old/msgpack-cxx-8.0.0/include/msgpack/v1/vrefbuffer.hpp     2023-07-08 
05:21:22.000000000 +0200
+++ new/msgpack-cxx-9.0.0/include/msgpack/v1/vrefbuffer.hpp     2026-08-25 
10:56:00.000000000 +0200
@@ -213,7 +213,7 @@
         empty->next = MSGPACK_NULLPTR;
 
         const size_t nused = static_cast<size_t>(m_tail - m_array);
-        if(to->m_tail + nused < m_end) {
+        if(to->m_tail + nused > to->m_end) {
             const size_t tosize = static_cast<size_t>(to->m_tail - 
to->m_array);
             const size_t reqsize = nused + tosize;
             size_t nnext = static_cast<size_t>(to->m_end - to->m_array) * 2;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/msgpack-cxx-8.0.0/include/msgpack/v2/create_object_visitor.hpp 
new/msgpack-cxx-9.0.0/include/msgpack/v2/create_object_visitor.hpp
--- old/msgpack-cxx-8.0.0/include/msgpack/v2/create_object_visitor.hpp  
2023-08-29 16:27:11.000000000 +0200
+++ new/msgpack-cxx-9.0.0/include/msgpack/v2/create_object_visitor.hpp  
2026-08-25 10:56:00.000000000 +0200
@@ -44,8 +44,10 @@
         m_stack[0] = &m_obj;
     }
     create_object_visitor& operator=(create_object_visitor&& other) {
-        this->~create_object_visitor();
-        new (this) create_object_visitor(std::move(other));
+        if (this != &other) {
+            this->~create_object_visitor();
+            new (this) create_object_visitor(std::move(other));
+        }
         return *this;
     }
 #endif // !defined(MSGPACK_USE_CPP03)
@@ -154,7 +156,7 @@
         }
         return true;
     }
-    bool visit_ext(const char* v, uint32_t size) {
+    bool visit_ext(const char* v, std::size_t size) {
         MSGPACK_ASSERT(v || size == 0);
         if (size > m_limit.ext()) throw msgpack::ext_size_overflow("ext size 
overflow");
         msgpack::object* obj = m_stack.back();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/msgpack-cxx-8.0.0/include/msgpack/v2/null_visitor.hpp 
new/msgpack-cxx-9.0.0/include/msgpack/v2/null_visitor.hpp
--- old/msgpack-cxx-8.0.0/include/msgpack/v2/null_visitor.hpp   2023-07-08 
05:21:22.000000000 +0200
+++ new/msgpack-cxx-9.0.0/include/msgpack/v2/null_visitor.hpp   2026-08-25 
10:56:00.000000000 +0200
@@ -43,7 +43,7 @@
     bool visit_bin(const char* /*v*/, uint32_t /*size*/) {
         return true;
     }
-    bool visit_ext(const char* /*v*/, uint32_t /*size*/) {
+    bool visit_ext(const char* /*v*/, std::size_t /*size*/) {
         return true;
     }
     bool start_array(uint32_t /*num_elements*/) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msgpack-cxx-8.0.0/include/msgpack/v2/parse.hpp 
new/msgpack-cxx-9.0.0/include/msgpack/v2/parse.hpp
--- old/msgpack-cxx-8.0.0/include/msgpack/v2/parse.hpp  2023-07-08 
05:21:22.000000000 +0200
+++ new/msgpack-cxx-9.0.0/include/msgpack/v2/parse.hpp  2026-08-25 
10:56:00.000000000 +0200
@@ -13,6 +13,8 @@
 #if MSGPACK_DEFAULT_API_VERSION >= 2
 
 #include <cstddef>
+#include <limits>
+#include <new>
 
 #include "msgpack/unpack_define.hpp"
 #include "msgpack/parse_return.hpp"
@@ -479,7 +481,7 @@
                 load<uint8_t>(tmp, n);
                 m_trail = tmp + 1;
                 if(m_trail == 0) {
-                    bool visret = holder().visitor().visit_ext(n, 
static_cast<uint32_t>(m_trail));
+                    bool visret = holder().visitor().visit_ext(n, m_trail);
                     parse_return upr = after_visit_proc(visret, off);
                     if (upr != PARSE_CONTINUE) return upr;
                 }
@@ -521,7 +523,7 @@
                 load<uint16_t>(tmp, n);
                 m_trail = tmp + 1;
                 if(m_trail == 0) {
-                    bool visret = holder().visitor().visit_ext(n, 
static_cast<uint32_t>(m_trail));
+                    bool visret = holder().visitor().visit_ext(n, m_trail);
                     parse_return upr = after_visit_proc(visret, off);
                     if (upr != PARSE_CONTINUE) return upr;
                 }
@@ -565,7 +567,7 @@
                 m_trail = tmp;
                 ++m_trail;
                 if(m_trail == 0) {
-                    bool visret = holder().visitor().visit_ext(n, 
static_cast<uint32_t>(m_trail));
+                    bool visret = holder().visitor().visit_ext(n, m_trail);
                     parse_return upr = after_visit_proc(visret, off);
                     if (upr != PARSE_CONTINUE) return upr;
                 }
@@ -585,7 +587,7 @@
                 if (upr != PARSE_CONTINUE) return upr;
             } break;
             case MSGPACK_ACS_EXT_VALUE: {
-                bool visret = holder().visitor().visit_ext(n, 
static_cast<uint32_t>(m_trail));
+                bool visret = holder().visitor().visit_ext(n, m_trail);
                 parse_return upr = after_visit_proc(visret, off);
                 if (upr != PARSE_CONTINUE) return upr;
             } break;
@@ -761,6 +763,14 @@
     void expand_buffer(std::size_t size);
     parse_return execute_imp();
 
+protected:
+    // Re-point the buffer-hook, e.g. after a move of the owning object so that
+    // the hook refers to the moved-to object's member rather than the
+    // moved-from (soon to be destroyed) object's member.
+    void set_referenced_buffer_hook(ReferencedBufferHook& hook) {
+        m_referenced_buffer_hook = &hook;
+    }
+
 private:
     char* m_buffer;
     std::size_t m_used;
@@ -768,7 +778,7 @@
     std::size_t m_off;
     std::size_t m_parsed;
     std::size_t m_initial_buffer_size;
-    ReferencedBufferHook& m_referenced_buffer_hook;
+    ReferencedBufferHook* m_referenced_buffer_hook;
 
 #if defined(MSGPACK_USE_CPP03)
 private:
@@ -785,7 +795,7 @@
 inline parser<VisitorHolder, ReferencedBufferHook>::parser(
     ReferencedBufferHook& hook,
     std::size_t initial_buffer_size)
-    :m_referenced_buffer_hook(hook)
+    :m_referenced_buffer_hook(&hook)
 {
     if(initial_buffer_size < COUNTER_SIZE) {
         initial_buffer_size = COUNTER_SIZE;
@@ -828,8 +838,10 @@
 
 template <typename VisitorHolder, typename ReferencedBufferHook>
 inline parser<VisitorHolder, ReferencedBufferHook>& parser<VisitorHolder, 
ReferencedBufferHook>::operator=(this_type&& other) {
-    this->~parser();
-    new (this) this_type(std::move(other));
+    if (this != &other) {
+        this->~parser();
+        new (this) this_type(std::move(other));
+    }
     return *this;
 }
 
@@ -865,6 +877,9 @@
     }
 
     if(m_off == COUNTER_SIZE) {
+        if(size > std::numeric_limits<std::size_t>::max() - m_used) {
+            throw std::bad_alloc();
+        }
         std::size_t next_size = (m_used + m_free) * 2;    // include 
COUNTER_SIZE
         while(next_size < size + m_used) {
             std::size_t tmp_next_size = next_size * 2;
@@ -886,6 +901,9 @@
     } else {
         std::size_t next_size = m_initial_buffer_size;  // include COUNTER_SIZE
         std::size_t not_parsed = m_used - m_off;
+        if(size > std::numeric_limits<std::size_t>::max() - not_parsed - 
COUNTER_SIZE) {
+            throw std::bad_alloc();
+        }
         while(next_size < size + not_parsed + COUNTER_SIZE) {
             std::size_t tmp_next_size = next_size * 2;
             if (tmp_next_size <= next_size) {
@@ -906,7 +924,7 @@
 
         if(static_cast<VisitorHolder&>(*this).referenced()) {
             try {
-                m_referenced_buffer_hook(m_buffer);
+                (*m_referenced_buffer_hook)(m_buffer);
             }
             catch (...) {
                 ::free(tmp);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msgpack-cxx-8.0.0/include/msgpack/v2/unpack.hpp 
new/msgpack-cxx-9.0.0/include/msgpack/v2/unpack.hpp
--- old/msgpack-cxx-8.0.0/include/msgpack/v2/unpack.hpp 2023-07-08 
05:21:22.000000000 +0200
+++ new/msgpack-cxx-9.0.0/include/msgpack/v2/unpack.hpp 2026-08-25 
10:56:00.000000000 +0200
@@ -48,6 +48,27 @@
         set_referenced(false);
     }
 
+#if !defined(MSGPACK_USE_CPP03)
+    unpacker(unpacker&& other)
+        :parser_t(std::move(other)),
+         detail::create_object_visitor(std::move(other)),
+         m_z(std::move(other.m_z)),
+         m_finalizer(std::move(other.m_finalizer)) {
+        // The parser base copied a hook pointer that still refers to the
+        // moved-from object's m_finalizer; re-point it to our own. The zone
+        // itself is heap-allocated and only ownership moved, so the zone
+        // pointers held by the visitor and by m_finalizer stay valid.
+        parser_t::set_referenced_buffer_hook(m_finalizer);
+    }
+    unpacker& operator=(unpacker&& other) {
+        if (this != &other) {
+            this->~unpacker();
+            new (this) unpacker(std::move(other));
+        }
+        return *this;
+    }
+#endif // !defined(MSGPACK_USE_CPP03)
+
     detail::create_object_visitor& visitor() { return *this; }
     /// Unpack one msgpack::object.
     /**
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msgpack-cxx-8.0.0/include/msgpack/v2/x3_parse.hpp 
new/msgpack-cxx-9.0.0/include/msgpack/v2/x3_parse.hpp
--- old/msgpack-cxx-8.0.0/include/msgpack/v2/x3_parse.hpp       2023-07-08 
05:21:22.000000000 +0200
+++ new/msgpack-cxx-9.0.0/include/msgpack/v2/x3_parse.hpp       2026-08-25 
10:56:00.000000000 +0200
@@ -214,7 +214,7 @@
         (
             [](auto& ctx){
                 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
-                app_specific.vis.visit_negative_integer(_attr(ctx));
+                app_specific.vis.visit_positive_integer(_attr(ctx));
             }
         )
     ]
@@ -592,7 +592,7 @@
             [](auto& ctx){
                 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
                 auto const& ext = _attr(ctx);
-                auto size = static_cast<uint32_t>(std::distance(ext.begin(), 
ext.end()));
+                auto size = 
static_cast<std::size_t>(std::distance(ext.begin(), ext.end()));
                 app_specific.vis.visit_ext(size ? &ext.front() : nullptr, 
size);
             }
         )
@@ -616,7 +616,7 @@
             [](auto& ctx){
                 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
                 auto const& ext = _attr(ctx);
-                auto size = static_cast<uint32_t>(std::distance(ext.begin(), 
ext.end()));
+                auto size = 
static_cast<std::size_t>(std::distance(ext.begin(), ext.end()));
                 app_specific.vis.visit_ext(size ? &ext.front() : nullptr, 
size);
             }
         )
@@ -640,7 +640,7 @@
             [](auto& ctx){
                 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
                 auto const& ext = _attr(ctx);
-                auto size = static_cast<uint32_t>(std::distance(ext.begin(), 
ext.end()));
+                auto size = 
static_cast<std::size_t>(std::distance(ext.begin(), ext.end()));
                 app_specific.vis.visit_ext(size ? &ext.front() : nullptr, 
size);
             }
         )
@@ -664,7 +664,7 @@
             [](auto& ctx){
                 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
                 auto const& ext = _attr(ctx);
-                auto size = static_cast<uint32_t>(std::distance(ext.begin(), 
ext.end()));
+                auto size = 
static_cast<std::size_t>(std::distance(ext.begin(), ext.end()));
                 app_specific.vis.visit_ext(size ? &ext.front() : nullptr, 
size);
             }
         )
@@ -688,7 +688,7 @@
             [](auto& ctx){
                 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
                 auto const& ext = _attr(ctx);
-                auto size = static_cast<uint32_t>(std::distance(ext.begin(), 
ext.end()));
+                auto size = 
static_cast<std::size_t>(std::distance(ext.begin(), ext.end()));
                 app_specific.vis.visit_ext(size ? &ext.front() : nullptr, 
size);
             }
         )
@@ -712,7 +712,7 @@
             [](auto& ctx){
                 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
                 auto const& ext = _attr(ctx);
-                auto size = static_cast<uint32_t>(std::distance(ext.begin(), 
ext.end()));
+                auto size = 
static_cast<std::size_t>(std::distance(ext.begin(), ext.end()));
                 app_specific.vis.visit_ext(size ? &ext.front() : nullptr, 
size);
             }
         )
@@ -736,7 +736,7 @@
             [](auto& ctx){
                 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
                 auto const& ext = _attr(ctx);
-                auto size = static_cast<uint32_t>(std::distance(ext.begin(), 
ext.end()));
+                auto size = 
static_cast<std::size_t>(std::distance(ext.begin(), ext.end()));
                 app_specific.vis.visit_ext(size ? &ext.front() : nullptr, 
size);
             }
         )
@@ -760,7 +760,7 @@
             [](auto& ctx){
                 auto& app_specific = x3::get<tag_app_specific>(ctx).get();
                 auto const& ext = _attr(ctx);
-                auto size = static_cast<uint32_t>(std::distance(ext.begin(), 
ext.end()));
+                auto size = 
static_cast<std::size_t>(std::distance(ext.begin(), ext.end()));
                 app_specific.vis.visit_ext(size ? &ext.front() : nullptr, 
size);
             }
         )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msgpack-cxx-8.0.0/include/msgpack/v3/parse.hpp 
new/msgpack-cxx-9.0.0/include/msgpack/v3/parse.hpp
--- old/msgpack-cxx-8.0.0/include/msgpack/v3/parse.hpp  2023-07-08 
05:21:22.000000000 +0200
+++ new/msgpack-cxx-9.0.0/include/msgpack/v3/parse.hpp  2026-08-25 
10:56:00.000000000 +0200
@@ -488,7 +488,7 @@
                 load<uint8_t>(tmp, n);
                 m_trail = tmp + 1;
                 if(m_trail == 0) {
-                    bool visret = holder().visitor().visit_ext(n, 
static_cast<uint32_t>(m_trail));
+                    bool visret = holder().visitor().visit_ext(n, m_trail);
                     parse_return upr = after_visit_proc(visret, off);
                     if (upr != PARSE_CONTINUE) return upr;
                 }
@@ -530,7 +530,7 @@
                 load<uint16_t>(tmp, n);
                 m_trail = tmp + 1;
                 if(m_trail == 0) {
-                    bool visret = holder().visitor().visit_ext(n, 
static_cast<uint32_t>(m_trail));
+                    bool visret = holder().visitor().visit_ext(n, m_trail);
                     parse_return upr = after_visit_proc(visret, off);
                     if (upr != PARSE_CONTINUE) return upr;
                 }
@@ -574,7 +574,7 @@
                 m_trail = tmp;
                 ++m_trail;
                 if(m_trail == 0) {
-                    bool visret = holder().visitor().visit_ext(n, 
static_cast<uint32_t>(m_trail));
+                    bool visret = holder().visitor().visit_ext(n, m_trail);
                     parse_return upr = after_visit_proc(visret, off);
                     if (upr != PARSE_CONTINUE) return upr;
                 }
@@ -594,7 +594,7 @@
                 if (upr != PARSE_CONTINUE) return upr;
             } break;
             case MSGPACK_ACS_EXT_VALUE: {
-                bool visret = holder().visitor().visit_ext(n, 
static_cast<uint32_t>(m_trail));
+                bool visret = holder().visitor().visit_ext(n, m_trail);
                 parse_return upr = after_visit_proc(visret, off);
                 if (upr != PARSE_CONTINUE) return upr;
             } break;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msgpack-cxx-8.0.0/include/msgpack/version_master.hpp 
new/msgpack-cxx-9.0.0/include/msgpack/version_master.hpp
--- old/msgpack-cxx-8.0.0/include/msgpack/version_master.hpp    2026-05-30 
12:31:43.000000000 +0200
+++ new/msgpack-cxx-9.0.0/include/msgpack/version_master.hpp    2026-08-25 
10:56:00.000000000 +0200
@@ -1,3 +1,3 @@
-#define MSGPACK_VERSION_MAJOR    8
+#define MSGPACK_VERSION_MAJOR    9
 #define MSGPACK_VERSION_MINOR    0
 #define MSGPACK_VERSION_REVISION 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msgpack-cxx-8.0.0/test/CMakeLists.txt 
new/msgpack-cxx-9.0.0/test/CMakeLists.txt
--- old/msgpack-cxx-8.0.0/test/CMakeLists.txt   2024-08-09 04:56:55.000000000 
+0200
+++ new/msgpack-cxx-9.0.0/test/CMakeLists.txt   2026-08-25 10:56:00.000000000 
+0200
@@ -47,6 +47,7 @@
         msgpack_cpp11.cpp
         reference_cpp11.cpp
         reference_wrapper_cpp11.cpp
+        security_fixes_cpp11.cpp
         shared_ptr_cpp11.cpp
         unique_ptr_cpp11.cpp
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msgpack-cxx-8.0.0/test/security_fixes_cpp11.cpp 
new/msgpack-cxx-9.0.0/test/security_fixes_cpp11.cpp
--- old/msgpack-cxx-8.0.0/test/security_fixes_cpp11.cpp 1970-01-01 
01:00:00.000000000 +0100
+++ new/msgpack-cxx-9.0.0/test/security_fixes_cpp11.cpp 2026-08-25 
10:56:00.000000000 +0200
@@ -0,0 +1,175 @@
+#include <msgpack.hpp>
+
+#define BOOST_TEST_MODULE security_fixes
+#include <boost/test/unit_test.hpp>
+
+#include <array>
+#include <chrono>
+#include <cstring>
+#include <limits>
+#include <string>
+#include <tuple>
+#include <vector>
+
+// Regression tests for memory-safety / correctness fixes.
+// See the audit that accompanied the msgpack_unpacker_expand_buffer overflow 
fix.
+
+// A1: convert of an empty msgpack array into a C array must not dereference a
+// null/oversized pointer. size < N leaves the remaining elements untouched;
+// size > N throws.
+BOOST_AUTO_TEST_CASE(carray_empty_array_no_crash)
+{
+    msgpack::object_handle oh = msgpack::unpack("\x90", 1); // empty fixarray
+    int v[3] = {7, 8, 9};
+    oh.get().convert(v); // must not crash
+    BOOST_CHECK_EQUAL(v[0], 7);
+
+    msgpack::object_handle oh2 = msgpack::unpack("\x94\x01\x02\x03\x04", 5); 
// 4 elems
+    int v2[3];
+    BOOST_CHECK_THROW(oh2.get().convert(v2), msgpack::type_error);
+}
+
+// A2: convert of an empty array into msgpack::type::tuple must not dereference
+// a null pointer (the N==1 base specialization was missing the size guard).
+BOOST_AUTO_TEST_CASE(msgpack_tuple_convert_empty_array)
+{
+    msgpack::object_handle oh = msgpack::unpack("\x90", 1);
+    msgpack::type::tuple<int> t;
+    oh.get().convert(t); // must not crash
+    BOOST_CHECK(true);
+}
+
+// A3: as<tuple> on an array shorter than the tuple must throw, not read OOB
+// (index computation size - sizeof...(Args) - 1 used to underflow).
+BOOST_AUTO_TEST_CASE(tuple_as_short_array_throws)
+{
+    using tp = std::chrono::system_clock::time_point;
+    const char b[] = "\x91\x01"; // [1]
+    msgpack::object_handle oh = msgpack::unpack(b, 2);
+    BOOST_CHECK_THROW((oh.get().as<std::tuple<tp, tp, tp> >()), 
msgpack::type_error);
+    BOOST_CHECK_THROW((oh.get().as<msgpack::type::tuple<tp, tp, tp> >()), 
msgpack::type_error);
+}
+
+// A4: converting a short STR into std::array<char, N> must copy only str.size
+// bytes, not N (which over-read the source).
+BOOST_AUTO_TEST_CASE(array_char_str_no_overread)
+{
+    msgpack::sbuffer sb;
+    msgpack::pack(sb, std::string("ab"));
+    msgpack::object_handle oh = msgpack::unpack(sb.data(), sb.size());
+    std::array<char, 8> a;
+    a.fill('Z');
+    oh.get().convert(a);
+    BOOST_CHECK_EQUAL(a[0], 'a');
+    BOOST_CHECK_EQUAL(a[1], 'b');
+    BOOST_CHECK_EQUAL(a[2], 'Z'); // untouched
+}
+
+// B1: moving a (v2) unpacker must not leave the parser referencing the
+// moved-from object's buffer hook.
+BOOST_AUTO_TEST_CASE(unpacker_move_buffer_hook)
+{
+    msgpack::unpacker u1(MSGPACK_NULLPTR, MSGPACK_NULLPTR, 64);
+    msgpack::unpacker u2(std::move(u1));
+    const char m[] = "\x92\xa3" "abc"; // array(2) + referencing str, 2nd elem 
missing
+    u2.reserve_buffer(5);
+    std::memcpy(u2.buffer(), m, 5);
+    u2.buffer_consumed(5);
+    msgpack::object_handle oh;
+    u2.next(oh);
+    u2.reserve_buffer(1 << 20); // exercises the referenced-buffer hook
+    BOOST_CHECK(true);
+
+    // move-assignment and self-move-assignment
+    msgpack::unpacker u3(MSGPACK_NULLPTR, MSGPACK_NULLPTR, 64);
+    u3 = std::move(u2);
+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wself-move"
+#endif
+    u3 = std::move(u3); // self-move must not crash
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
+    BOOST_CHECK(true);
+}
+
+// B2: zone move-assignment must run finalizers before freeing chunks.
+BOOST_AUTO_TEST_CASE(zone_move_assignment)
+{
+    msgpack::zone z1;
+    z1.allocate<std::string>("a fairly long string that lives in the chunk");
+    msgpack::zone z2;
+    z1 = std::move(z2); // must not use-after-free
+    BOOST_CHECK(true);
+}
+
+// B4: vrefbuffer::migrate must grow the destination iovec array when needed.
+BOOST_AUTO_TEST_CASE(vrefbuffer_migrate)
+{
+    // Use distinct 256-byte buffers so each write becomes its own iovec and
+    // fills the initial iovec array of both buffers, forcing migrate() to grow
+    // the destination array.
+    std::vector<std::string> bufs;
+    for (std::size_t i = 0; i < 8; ++i) bufs.push_back(std::string(256, 
static_cast<char>('a' + i)));
+    msgpack::vrefbuffer from;
+    msgpack::vrefbuffer to;
+    for (std::size_t i = 0; i < 4; ++i) from.write(bufs[i].data(), 
bufs[i].size());
+    for (std::size_t i = 4; i < 8; ++i) to.write(bufs[i].data(), 
bufs[i].size());
+    const size_t from_n = from.vector_size();
+    const size_t to_n = to.vector_size();
+    from.migrate(&to); // must not overflow to's iovec array
+    BOOST_CHECK_EQUAL(to.vector_size(), from_n + to_n);
+}
+
+// B5: an impossibly large zone allocation must throw, not wrap the malloc 
size.
+BOOST_AUTO_TEST_CASE(zone_allocate_overflow)
+{
+    msgpack::zone z;
+    BOOST_CHECK_THROW(
+        z.allocate_no_align(std::numeric_limits<std::size_t>::max() - 4),
+        std::bad_alloc);
+}
+
+// C1: ext_ref comparison must include the whole payload (used to drop the last
+// byte via memcmp(..., m_size)).
+BOOST_AUTO_TEST_CASE(ext_ref_full_payload_compare)
+{
+    char ba[] = {7, 'x', 'y', 'A'};
+    char bb[] = {7, 'x', 'y', 'B'};
+    msgpack::type::ext_ref ra(ba, sizeof(ba));
+    msgpack::type::ext_ref rb(bb, sizeof(bb));
+    BOOST_CHECK(!(ra == rb));
+    BOOST_CHECK(ra != rb);
+    BOOST_CHECK((ra < rb) || (rb < ra));
+}
+
+// C2: array_ref<T[N]> relational operators must compare element-wise.
+BOOST_AUTO_TEST_CASE(array_ref_carray_compare)
+{
+    int x[3] = {1, 2, 3};
+    int y[3] = {1, 2, 4};
+    msgpack::type::array_ref<int[3]> rx = msgpack::type::make_array_ref(x);
+    msgpack::type::array_ref<int[3]> ry = msgpack::type::make_array_ref(y);
+    BOOST_CHECK(rx == rx);
+    BOOST_CHECK(rx != ry);
+    BOOST_CHECK(rx < ry);
+    BOOST_CHECK(ry > rx);
+    BOOST_CHECK(rx <= rx);
+    BOOST_CHECK(ry >= rx);
+}
+
+// C3: v1 unpacker must enforce the str limit even on the reference path.
+BOOST_AUTO_TEST_CASE(v1_unpacker_reference_path_limit)
+{
+    msgpack::sbuffer sb;
+    msgpack::pack(sb, std::string("0123456789"));
+    // array, map, str=2, ...
+    msgpack::v1::unpacker u(MSGPACK_NULLPTR, MSGPACK_NULLPTR, 64,
+                            msgpack::unpack_limit(0xffffffff, 0xffffffff, 2));
+    u.reserve_buffer(sb.size());
+    std::memcpy(u.buffer(), sb.data(), sb.size());
+    u.buffer_consumed(sb.size());
+    msgpack::object_handle oh;
+    BOOST_CHECK_THROW(u.next(oh), msgpack::str_size_overflow);
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msgpack-cxx-8.0.0/test/streaming.cpp 
new/msgpack-cxx-9.0.0/test/streaming.cpp
--- old/msgpack-cxx-8.0.0/test/streaming.cpp    2023-07-08 05:21:22.000000000 
+0200
+++ new/msgpack-cxx-9.0.0/test/streaming.cpp    2026-08-25 10:56:00.000000000 
+0200
@@ -333,3 +333,65 @@
 }
 
 #endif // !defined(MSGPACK_USE_CPP03)
+
+// https://github.com/msgpack/msgpack-c/issues/1181
+template <typename Unpacker>
+void reserve_buffer_overflow_rewound_impl()
+{
+    Unpacker pac(MSGPACK_NULLPTR, MSGPACK_NULLPTR, 8);
+
+    // off == COUNTER_SIZE path: size + used would wrap
+    std::size_t request = std::numeric_limits<std::size_t>::max() - 2;
+    BOOST_CHECK_THROW(pac.reserve_buffer(request), std::bad_alloc);
+
+    // a sane request still works
+    pac.reserve_buffer(64);
+    BOOST_CHECK_GE(pac.buffer_capacity(), static_cast<std::size_t>(64));
+}
+
+template <typename Unpacker>
+void reserve_buffer_overflow_not_rewound_impl()
+{
+    Unpacker pac(MSGPACK_NULLPTR, MSGPACK_NULLPTR, 8);
+
+    // consume part of the buffer so off != COUNTER_SIZE
+    msgpack::sbuffer sbuf;
+    msgpack::packer<msgpack::sbuffer> pk(&sbuf);
+    pk.pack(1);
+    pk.pack(2);
+
+    pac.reserve_buffer(sbuf.size());
+    std::memcpy(pac.buffer(), sbuf.data(), sbuf.size());
+    pac.buffer_consumed(sbuf.size());
+
+    msgpack::object_handle oh;
+    BOOST_CHECK(pac.next(oh));
+    BOOST_CHECK_EQUAL(oh.get().as<int>(), 1);
+
+    std::size_t request = std::numeric_limits<std::size_t>::max() - 2;
+    BOOST_CHECK_THROW(pac.reserve_buffer(request), std::bad_alloc);
+
+    // remaining data must still be parsable
+    BOOST_CHECK(pac.next(oh));
+    BOOST_CHECK_EQUAL(oh.get().as<int>(), 2);
+}
+
+BOOST_AUTO_TEST_CASE(reserve_buffer_overflow_rewound)
+{
+    reserve_buffer_overflow_rewound_impl<msgpack::unpacker>();
+}
+
+BOOST_AUTO_TEST_CASE(reserve_buffer_overflow_rewound_v1)
+{
+    reserve_buffer_overflow_rewound_impl<msgpack::v1::unpacker>();
+}
+
+BOOST_AUTO_TEST_CASE(reserve_buffer_overflow_not_rewound)
+{
+    reserve_buffer_overflow_not_rewound_impl<msgpack::unpacker>();
+}
+
+BOOST_AUTO_TEST_CASE(reserve_buffer_overflow_not_rewound_v1)
+{
+    reserve_buffer_overflow_not_rewound_impl<msgpack::v1::unpacker>();
+}

Reply via email to