Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package libaec for openSUSE:Factory checked 
in at 2026-05-23 23:25:22
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libaec (Old)
 and      /work/SRC/openSUSE:Factory/.libaec.new.2084 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libaec"

Sat May 23 23:25:22 2026 rev:12 rq:1354728 version:1.1.7

Changes:
--------
--- /work/SRC/openSUSE:Factory/libaec/libaec.changes    2026-02-25 
21:23:34.210269814 +0100
+++ /work/SRC/openSUSE:Factory/.libaec.new.2084/libaec.changes  2026-05-23 
23:27:26.532870968 +0200
@@ -1,0 +2,6 @@
+Tue May 19 12:57:53 UTC 2026 - Manfred Schwarb <[email protected]>
+
+- Update to version 1.1.7:
+  * Fixed several security vulnerabilities discovered by libFuzzer and AI 
assistant 
+
+-------------------------------------------------------------------

Old:
----
  libaec-v1.1.6.tar.gz

New:
----
  libaec-v1.1.7.tar.gz

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

Other differences:
------------------
++++++ libaec.spec ++++++
--- /var/tmp/diff_new_pack.7Zhx6r/_old  2026-05-23 23:27:27.128895299 +0200
+++ /var/tmp/diff_new_pack.7Zhx6r/_new  2026-05-23 23:27:27.132895462 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           libaec
-Version:        1.1.6
+Version:        1.1.7
 Release:        0
 Summary:        Adaptive Entropy Coding library
 License:        BSD-2-Clause

++++++ libaec-v1.1.6.tar.gz -> libaec-v1.1.7.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libaec-v1.1.6/CHANGELOG.md 
new/libaec-v1.1.7/CHANGELOG.md
--- old/libaec-v1.1.6/CHANGELOG.md      2026-02-24 10:19:36.000000000 +0100
+++ new/libaec-v1.1.7/CHANGELOG.md      2026-05-19 12:20:48.000000000 +0200
@@ -1,7 +1,13 @@
 # libaec Changelog
 All notable changes to libaec will be documented in this file.
 
-## [1.1.6] - 2026-06-16
+## [1.1.7] - 2026-05-19
+
+### Fixed
+- Fixed several security vulnerabilities discovered by libFuzzer and AI
+  assistant
+
+## [1.1.6] - 2026-02-16
 
 ### Fixed
 - CMake fixes by Adrien Wu
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libaec-v1.1.6/CMakeLists.txt 
new/libaec-v1.1.7/CMakeLists.txt
--- old/libaec-v1.1.6/CMakeLists.txt    2026-02-24 10:19:36.000000000 +0100
+++ new/libaec-v1.1.7/CMakeLists.txt    2026-05-19 12:20:48.000000000 +0200
@@ -1,5 +1,5 @@
 cmake_minimum_required(VERSION 3.26...3.31)
-project(libaec LANGUAGES C VERSION 1.1.6)
+project(libaec LANGUAGES C VERSION 1.1.7)
 
 option(BUILD_SHARED_LIBS "OFF: do not build shared libraries.  ON (default): 
build shared libraries" ON)
 option(BUILD_STATIC_LIBS "OFF: do not build static libraries.  ON (default): 
build static libraries" ON)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libaec-v1.1.6/configure.ac 
new/libaec-v1.1.7/configure.ac
--- old/libaec-v1.1.6/configure.ac      2026-02-24 10:19:36.000000000 +0100
+++ new/libaec-v1.1.7/configure.ac      2026-05-19 12:20:48.000000000 +0200
@@ -2,7 +2,7 @@
 
 m4_define([VERSION_MAJOR], [1])
 m4_define([VERSION_MINOR], [1])
-m4_define([VERSION_PATCH], [6])
+m4_define([VERSION_PATCH], [7])
 
 
AC_INIT([libaec],[VERSION_MAJOR.VERSION_MINOR.VERSION_PATCH],[[email protected]])
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libaec-v1.1.6/fuzzing/CMakeLists.txt 
new/libaec-v1.1.7/fuzzing/CMakeLists.txt
--- old/libaec-v1.1.6/fuzzing/CMakeLists.txt    2026-02-24 10:19:36.000000000 
+0100
+++ new/libaec-v1.1.7/fuzzing/CMakeLists.txt    2026-05-19 12:20:48.000000000 
+0200
@@ -1,11 +1,13 @@
 add_executable(fuzz_target fuzz_target.cc)
 target_link_libraries(fuzz_target PUBLIC libaec::aec)
-
-# Actually link libFuzzer
 target_link_options(fuzz_target PRIVATE -fsanitize=fuzzer)
 
 add_executable(fuzz_target_sz fuzz_target_sz.cc)
 target_link_libraries(fuzz_target_sz PUBLIC libaec::sz)
-
-# Actually link libFuzzer
 target_link_options(fuzz_target_sz PRIVATE -fsanitize=fuzzer)
+
+# Covers the streaming encode/decode APIs, RSI offset capture,
+# aec_buffer_seek, and aec_decode_range.
+add_executable(fuzz_target_streaming fuzz_target_streaming.cc)
+target_link_libraries(fuzz_target_streaming PUBLIC libaec::aec)
+target_link_options(fuzz_target_streaming PRIVATE -fsanitize=fuzzer)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libaec-v1.1.6/fuzzing/fuzz_target_streaming.cc 
new/libaec-v1.1.7/fuzzing/fuzz_target_streaming.cc
--- old/libaec-v1.1.6/fuzzing/fuzz_target_streaming.cc  1970-01-01 
01:00:00.000000000 +0100
+++ new/libaec-v1.1.7/fuzzing/fuzz_target_streaming.cc  2026-05-19 
12:20:48.000000000 +0200
@@ -0,0 +1,241 @@
+/**
+ * @file fuzz_target_streaming.cc
+ *
+ * Exercises the streaming encode/decode APIs, RSI offset capture,
+ * aec_buffer_seek, and aec_decode_range — the public API functions not
+ * covered by fuzz_target.cc.
+ *
+ * Four phases per input:
+ *
+ *   1. Streaming decode of raw fuzz bytes on to a small output buffer.
+ *      Forces the resumable decoder states (m_split_output, m_zero_output,
+ *      m_se_decode, m_uncomp_copy, …).  Captured RSI offsets are then used
+ *      to exercise aec_buffer_seek.
+ *
+ *   2. Streaming encode of the fuzz payload.  Captures RSI offsets via the
+ *      encode offset API.
+ *
+ *   3. Streaming decode of the encoded output.  Validates the round-trip and
+ *      collects decode-side RSI offsets needed for phase 4.
+ *
+ *   4. aec_decode_range called with two different (pos, size) pairs using the
+ *      offsets captured in phase 3.
+ *
+ * APIs exercised
+ *   aec_encode_init, aec_encode_enable_offsets, aec_encode,
+ *   aec_encode_count_offsets, aec_encode_get_offsets, aec_encode_end,
+ *   aec_decode_init, aec_decode_enable_offsets, aec_decode,
+ *   aec_decode_count_offsets, aec_decode_get_offsets, aec_decode_end,
+ *   aec_decode_range, aec_buffer_seek
+ */
+
+#include <cstddef>
+#include <cstdint>
+#include <cstring>
+#include <vector>
+#include "libaec.h"
+#include <fuzzer/FuzzedDataProvider.h>
+
+static void fill_stream(struct aec_stream *strm,
+                        unsigned int bits_per_sample,
+                        unsigned int block_size,
+                        unsigned int rsi,
+                        unsigned int flags)
+{
+    memset(strm, 0, sizeof(*strm));
+    strm->bits_per_sample = bits_per_sample;
+    strm->block_size      = block_size;
+    strm->rsi             = rsi;
+    strm->flags           = flags;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
+{
+    FuzzedDataProvider fdp(Data, Size);
+
+    const unsigned int bits_per_sample =
+        fdp.ConsumeIntegralInRange<unsigned int>(1, 32);
+    const unsigned int block_size =
+        fdp.PickValueInArray<unsigned int>({8, 16, 32, 64});
+    const unsigned int rsi =
+        fdp.ConsumeIntegralInRange<unsigned int>(1, 4096);
+    /* Only the flags that aec_decode_init/aec_encode_init actually honour. */
+    const unsigned int flags =
+        fdp.ConsumeIntegral<uint8_t>() &
+        (AEC_DATA_SIGNED | AEC_DATA_MSB | AEC_DATA_PREPROCESS | AEC_PAD_RSI);
+
+    /* Output chunk size used in phase 1 to exercise resumable states. */
+    const size_t chunk_out =
+        fdp.ConsumeIntegralInRange<size_t>(1, 128);
+
+    std::vector<uint8_t> payload = fdp.ConsumeRemainingBytes<uint8_t>();
+    if (payload.empty())
+        return 0;
+
+    /* ── Phase 1: streaming decode of raw fuzz bytes ────────────────────────
+     *
+     * Intent: exercise the decoder on arbitrary, likely-invalid compressed
+     * data and verify it handles errors cleanly.  The small per-call avail_out
+     * forces the resumable partial-output states.
+     * After decoding, use any captured RSI offsets with aec_buffer_seek.      
 */
+    {
+        struct aec_stream dec;
+        fill_stream(&dec, bits_per_sample, block_size, rsi, flags);
+        dec.next_in  = payload.data();
+        dec.avail_in = payload.size();
+
+        /* Generous output buffer; we expose it in small slices below. */
+        std::vector<uint8_t> out(payload.size() * 4 + 1024);
+        size_t out_written = 0;
+
+        if (aec_decode_init(&dec) == AEC_OK) {
+            aec_decode_enable_offsets(&dec);
+
+            /* Feed output in chunk_out-sized pieces to hit resumable paths. */
+            bool decode_error = false;
+            while (out_written + chunk_out <= out.size() && dec.avail_in > 0) {
+                dec.next_out  = out.data() + out_written;
+                dec.avail_out = chunk_out;
+                int st = aec_decode(&dec, AEC_NO_FLUSH);
+                out_written += chunk_out - dec.avail_out;
+                if (st == AEC_DATA_ERROR) { decode_error = true; break; }
+                if (st != AEC_OK) break;
+            }
+            /* Drain whatever remains (only if no hard error above). */
+            if (!decode_error && out_written < out.size()) {
+                dec.next_out  = out.data() + out_written;
+                dec.avail_out = out.size() - out_written;
+                aec_decode(&dec, AEC_FLUSH);
+            }
+
+            size_t count = 0;
+            if (aec_decode_count_offsets(&dec, &count) == AEC_OK && count > 0) 
{
+                std::vector<size_t> offsets(count);
+                if (aec_decode_get_offsets(&dec, offsets.data(), count) == 
AEC_OK) {
+                    /* Exercise aec_buffer_seek at up to 4 captured offsets. */
+                    for (size_t i = 0; i < count && i < 4; i++) {
+                        struct aec_stream sk;
+                        fill_stream(&sk, bits_per_sample, block_size, rsi, 
flags);
+                        sk.next_in  = payload.data();
+                        sk.avail_in = payload.size();
+                        if (aec_decode_init(&sk) == AEC_OK) {
+                            std::vector<uint8_t> sk_out(256);
+                            sk.next_out  = sk_out.data();
+                            sk.avail_out = sk_out.size();
+                            if (aec_buffer_seek(&sk, offsets[i]) == AEC_OK)
+                                aec_decode(&sk, AEC_FLUSH);
+                            aec_decode_end(&sk);
+                        }
+                    }
+                }
+            }
+            aec_decode_end(&dec);
+        }
+    }
+
+    /* ── Phase 2: streaming encode of fuzz payload ──────────────────────────
+     *
+     * Intent: exercise the encoder streaming API and RSI offset capture.      
*/
+    std::vector<uint8_t> encoded(payload.size() * 2 + 1024);
+    size_t encoded_bytes = 0;
+
+    {
+        struct aec_stream enc;
+        fill_stream(&enc, bits_per_sample, block_size, rsi, flags);
+        enc.next_in   = payload.data();
+        enc.avail_in  = payload.size();
+        enc.next_out  = encoded.data();
+        enc.avail_out = encoded.size();
+
+        if (aec_encode_init(&enc) != AEC_OK)
+            return 0;
+        aec_encode_enable_offsets(&enc);
+        aec_encode(&enc, AEC_FLUSH);
+        encoded_bytes = enc.total_out;
+
+        size_t count = 0;
+        if (aec_encode_count_offsets(&enc, &count) == AEC_OK && count > 0) {
+            std::vector<size_t> enc_offsets(count);
+            aec_encode_get_offsets(&enc, enc_offsets.data(), count);
+        }
+        aec_encode_end(&enc);
+    }
+
+    if (encoded_bytes == 0)
+        return 0;
+
+    /* ── Phase 3: streaming decode of encoded output ────────────────────────
+     *
+     * Intent: validate the encode→decode round-trip and collect RSI offsets
+     * in the decoded domain for phase 4.                                      
 */
+    std::vector<uint8_t> decoded(payload.size() + 1024);
+    size_t decoded_bytes = 0;
+    std::vector<size_t> dec_offsets;
+
+    {
+        struct aec_stream dec;
+        fill_stream(&dec, bits_per_sample, block_size, rsi, flags);
+        dec.next_in   = encoded.data();
+        dec.avail_in  = encoded_bytes;
+        dec.next_out  = decoded.data();
+        dec.avail_out = decoded.size();
+
+        if (aec_decode_init(&dec) != AEC_OK)
+            return 0;
+        aec_decode_enable_offsets(&dec);
+        aec_decode(&dec, AEC_FLUSH);
+        decoded_bytes = dec.total_out;
+
+        size_t count = 0;
+        if (aec_decode_count_offsets(&dec, &count) == AEC_OK && count > 0) {
+            dec_offsets.resize(count);
+            aec_decode_get_offsets(&dec, dec_offsets.data(), count);
+        }
+        aec_decode_end(&dec);
+    }
+
+    /* ── Phase 4: aec_decode_range ──────────────────────────────────────────
+     *
+     * Intent: exercise random-access decode with valid compressed data and
+     * captured RSI offsets.  Calls the function twice:
+     *   (a) full range from position 0
+     *   (b) from the start of the second RSI (if one exists)               */
+    if (dec_offsets.empty() || decoded_bytes == 0)
+        return 0;
+
+    struct aec_stream rng;
+    fill_stream(&rng, bits_per_sample, block_size, rsi, flags);
+    rng.next_in  = encoded.data();
+    rng.avail_in = encoded_bytes;
+
+    if (aec_decode_init(&rng) != AEC_OK)
+        return 0;
+
+    std::vector<uint8_t> rng_out(decoded_bytes);
+
+    /* (a) Full range. */
+    rng.next_out  = rng_out.data();
+    rng.avail_out = decoded_bytes;
+    aec_decode_range(&rng, dec_offsets.data(), dec_offsets.size(),
+                     0, decoded_bytes);
+
+    /* (b) Second RSI boundary onwards. */
+    if (dec_offsets.size() >= 2) {
+        /* Mirror the bytes_per_sample calculation in aec_decode_init.
+         * Note: AEC_DATA_3BYTE is excluded from the flags mask above so
+         * bits_per_sample 17-24 always maps to 4 bytes here. */
+        size_t bytes_per_sample =
+            (bits_per_sample > 16) ? 4 : (bits_per_sample > 8) ? 2 : 1;
+        size_t rsi_bytes = (size_t)rsi * block_size * bytes_per_sample;
+        if (rsi_bytes > 0 && rsi_bytes < decoded_bytes) {
+            size_t sz = decoded_bytes - rsi_bytes;
+            rng.next_out  = rng_out.data();
+            rng.avail_out = sz;
+            aec_decode_range(&rng, dec_offsets.data(), dec_offsets.size(),
+                             rsi_bytes, sz);
+        }
+    }
+
+    aec_decode_end(&rng);
+    return 0;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libaec-v1.1.6/src/CMakeLists.txt 
new/libaec-v1.1.7/src/CMakeLists.txt
--- old/libaec-v1.1.6/src/CMakeLists.txt        2026-02-24 10:19:36.000000000 
+0100
+++ new/libaec-v1.1.7/src/CMakeLists.txt        2026-05-19 12:20:48.000000000 
+0200
@@ -43,7 +43,7 @@
   # Shared libaec versioning
   set(libaec_VERSION_MAJOR 0)
   set(libaec_VERSION_MINOR 1)
-  set(libaec_VERSION_PATCH 6)
+  set(libaec_VERSION_PATCH 7)
 
   # libtool compatible versioning for Mach-O
   math(EXPR libaec_MACHO_COMPATIBILITY_VERSION
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libaec-v1.1.6/src/Makefile.am 
new/libaec-v1.1.7/src/Makefile.am
--- old/libaec-v1.1.6/src/Makefile.am   2026-02-24 10:19:36.000000000 +0100
+++ new/libaec-v1.1.7/src/Makefile.am   2026-05-19 12:20:48.000000000 +0200
@@ -5,7 +5,7 @@
 libaec_la_SOURCES = encode.c encode_accessors.c decode.c vector.c\
 encode.h encode_accessors.h decode.h vector.h
 libaec_la_CPPFLAGS = $(AM_CPPFLAGS) -DLIBAEC_BUILD $(LIBAEC_SHARED)
-libaec_la_LDFLAGS = -version-info 1:6:1 -no-undefined
+libaec_la_LDFLAGS = -version-info 1:7:1 -no-undefined
 libsz_la_SOURCES = sz_compat.c
 libsz_la_LIBADD = libaec.la
 libsz_la_CPPFLAGS = $(AM_CPPFLAGS) -DLIBAEC_BUILD $(LIBAEC_SHARED)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libaec-v1.1.6/src/decode.c 
new/libaec-v1.1.7/src/decode.c
--- old/libaec-v1.1.6/src/decode.c      2026-02-24 10:19:36.000000000 +0100
+++ new/libaec-v1.1.7/src/decode.c      2026-05-19 12:20:48.000000000 +0200
@@ -195,13 +195,22 @@
     /**
        Get n bit from input stream
 
-       No checking whatsoever. Read bits are dumped.
+       Optimised fast path: no checking whatsoever. Read bits are dumped.
+       The caller is responsible for ensuring avail_in >= in_blklen before
+       invoking the fast path.  As a defensive measure we clamp the byte
+       load to avail_in; if fewer bytes than requested are available the
+       accumulator is zero-padded and the returned value may be wrong, but
+       we will not read past the end of the buffer.
      */
 
     struct internal_state *state = strm->state;
     if (state->bitp < n)
     {
         int b = (63 - state->bitp) >> 3;
+        /* Clamp to available bytes – avail_in may have been drained by
+         * earlier direct_get_fs calls within the same fast-path block. */
+        if ((size_t)b > strm->avail_in)
+            b = (int)strm->avail_in;
         if (b == 6) {
             state->acc = (state->acc << 48)
                 | ((uint64_t)strm->next_in[0] << 40)
@@ -250,6 +259,9 @@
         state->bitp += b << 3;
     }
 
+    if (state->bitp < n)
+        return 0;  /* Ran out of input; return zero rather than undefined. */
+
     state->bitp -= n;
     return (state->acc >> state->bitp) & (UINT64_MAX >> (64 - n));
 }
@@ -458,6 +470,12 @@
         int k = state->id - 1;
         size_t binary_part = (k * state->encoded_block_size) / 8 + 9;
 
+        /* Check input availability before any side effects on rsip so
+         * that a premature M_ERROR doesn't leave rsip partially
+         * advanced and corrupt the rsi_buffer on a subsequent call. */
+        if (k && strm->avail_in < binary_part)
+            return M_ERROR;
+
         if (state->ref)
             *state->rsip++ = direct_get(strm, strm->bits_per_sample);
 
@@ -465,9 +483,6 @@
             state->rsip[i] = direct_get_fs(strm) << k;
 
         if (k) {
-            if (strm->avail_in < binary_part)
-                return M_ERROR;
-
             for (size_t i = 0; i < state->encoded_block_size; i++)
                 *state->rsip++ += direct_get(strm, k);
         } else {
@@ -519,6 +534,8 @@
         zero_blocks--;
     }
 
+    if (zero_blocks > UINT32_MAX / strm->block_size)
+        return M_ERROR;
     zero_samples = zero_blocks * strm->block_size - state->ref;
     if (state->rsi_size - RSI_USED_SIZE(state) < zero_samples)
         return M_ERROR;
@@ -675,7 +692,9 @@
     if (strm->bits_per_sample > 32
         || strm->bits_per_sample == 0
         || strm->rsi == 0
+        || strm->rsi > 4096
         || strm->block_size & 1
+        || strm->block_size > 256
         || strm->block_size == 0)
         return AEC_CONF_ERROR;
 
@@ -812,8 +831,15 @@
         return AEC_DATA_ERROR;
 
     if (status == M_EXIT && strm->avail_out > 0 &&
-        strm->avail_out < state->bytes_per_sample)
+        strm->avail_out < state->bytes_per_sample) {
+        /* Flush the samples already decoded into rsi_buffer so that
+         * next_out and avail_out remain consistent with each other.
+         * The caller can detect partial output via AEC_MEM_ERROR. */
+        state->flush_output(strm);
+        strm->total_in -= strm->avail_in;
+        strm->total_out -= strm->avail_out;
         return AEC_MEM_ERROR;
+    }
 
     state->flush_output(strm);
 
@@ -881,6 +907,9 @@
     unsigned char *out_tmp;
     struct aec_stream strm_tmp = *strm;
 
+    if (strm->avail_out < size)
+        return AEC_MEM_ERROR;
+
     if (state->pp) {
         state->ref = 1;
         state->encoded_block_size = strm->block_size - 1;
@@ -896,6 +925,8 @@
     state->mode = m_id;
 
     rsi_size = strm->rsi * strm->block_size * state->bytes_per_sample;
+    if (size > SIZE_MAX - (pos % rsi_size) - state->bytes_per_sample - 1)
+        return AEC_DATA_ERROR;
     rsi_n = pos / rsi_size;
     if (rsi_n >= rsi_offsets_count)
         return AEC_DATA_ERROR;
@@ -908,11 +939,15 @@
         return AEC_MEM_ERROR;
     strm_tmp.next_out = out_tmp;
 
-    if ((status = aec_buffer_seek(&strm_tmp, rsi_offsets[rsi_n])) != AEC_OK)
+    if ((status = aec_buffer_seek(&strm_tmp, rsi_offsets[rsi_n])) != AEC_OK) {
+        free(out_tmp);
         return status;
+    }
 
-    if ((status = aec_decode(&strm_tmp, AEC_FLUSH)) != 0)
+    if ((status = aec_decode(&strm_tmp, AEC_FLUSH)) != 0) {
+        free(out_tmp);
         return status;
+    }
 
     memcpy(strm->next_out, out_tmp + (pos - rsi_n * rsi_size), size);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libaec-v1.1.6/src/encode.c 
new/libaec-v1.1.7/src/encode.c
--- old/libaec-v1.1.6/src/encode.c      2026-02-24 10:19:36.000000000 +0100
+++ new/libaec-v1.1.7/src/encode.c      2026-05-19 12:20:48.000000000 +0200
@@ -971,7 +971,8 @@
     if (offsets_count < vector_size(state->offsets)) {
         return AEC_MEM_ERROR;
     }
-    memcpy(offsets, vector_data(state->offsets), offsets_count * 
sizeof(size_t));
+    memcpy(offsets, vector_data(state->offsets),
+           vector_size(state->offsets) * sizeof(size_t));
     return AEC_OK;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libaec-v1.1.6/src/sz_compat.c 
new/libaec-v1.1.7/src/sz_compat.c
--- old/libaec-v1.1.6/src/sz_compat.c   2026-02-24 10:19:36.000000000 +0100
+++ new/libaec-v1.1.7/src/sz_compat.c   2026-05-19 12:20:48.000000000 +0200
@@ -182,6 +182,11 @@
     scanlines = (sourceLen / pixel_size + param->pixels_per_scanline - 1)
         / param->pixels_per_scanline;
     padbuf_size = strm.rsi * strm.block_size * pixel_size * scanlines;
+    if (scanlines != 0
+        && padbuf_size / scanlines != (size_t)strm.rsi * strm.block_size * 
pixel_size) {
+        status = SZ_PARAM_ERROR;
+        goto CLEANUP;
+    }
     padbuf = malloc(padbuf_size);
     if (padbuf == NULL) {
         status = SZ_MEM_ERROR;
@@ -229,6 +234,7 @@
     size_t scanlines;
 
     if (param->pixels_per_scanline == 0
+        || param->pixels_per_scanline > 4096
         || param->pixels_per_block == 0
         || param->pixels_per_block & 1
         || param->bits_per_pixel == 0

Reply via email to