Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package chromaprint for openSUSE:Factory checked in at 2026-10-15 18:20:13 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/chromaprint (Old) and /work/SRC/openSUSE:Factory/.chromaprint.new.3698736 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "chromaprint" Thu Oct 15 18:20:13 2026 rev:29 rq:1384811 version:1.6.1 Changes: -------- --- /work/SRC/openSUSE:Factory/chromaprint/chromaprint.changes 2025-09-02 17:58:12.602212562 +0200 +++ /work/SRC/openSUSE:Factory/.chromaprint.new.3698736/chromaprint.changes 2026-10-15 18:20:22.366014150 +0200 @@ -1,0 +2,15 @@ +Tue Oct 13 14:52:04 UTC 2026 - Bjørn Lie <[email protected]> + +- Update to version 1.6.1: + * Fixed a heap buffer overflow when decoding a fingerprint that has extra + data after the encoded values. Applications that decode fingerprints from + untrusted sources should update. + * Fixed building against FFmpeg 4.x, which had not compiled since the channel + layout API changed in 5.1 + * Audio can now be fed in buffers that do not end on a frame boundary; + previously a partial frame at the end of a call was dropped + * Fixed an implicit integer conversion warning on LLVM + * Fixed installing to absolute paths + * Build fpcalc against the system FFmpeg in CI + +------------------------------------------------------------------- Old: ---- chromaprint-1.6.0.tar.gz New: ---- chromaprint-1.6.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ chromaprint.spec ++++++ --- /var/tmp/diff_new_pack.SviqAI/_old 2026-10-15 18:20:23.338054848 +0200 +++ /var/tmp/diff_new_pack.SviqAI/_new 2026-10-15 18:20:23.340054931 +0200 @@ -1,7 +1,7 @@ # # spec file for package chromaprint # -# Copyright (c) 2025 SUSE LLC and contributors +# Copyright (c) 2026 SUSE LLC and contributors # Copyright (c) 2012 Pascal Bleser <[email protected]> # # All modifications and additions to the file contributed by third parties @@ -20,7 +20,7 @@ %define rev aa67c95b9e486884a6d3ee8b0c91207d8c2b0551 %define sover 1 Name: chromaprint -Version: 1.6.0 +Version: 1.6.1 Release: 0 Summary: Audio Fingerprinting Library License: LGPL-2.1-only AND MIT ++++++ chromaprint-1.6.0.tar.gz -> chromaprint-1.6.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chromaprint-1.6.0/.github/workflows/build.yml new/chromaprint-1.6.1/.github/workflows/build.yml --- old/chromaprint-1.6.0/.github/workflows/build.yml 2025-08-28 19:54:00.000000000 +0200 +++ new/chromaprint-1.6.1/.github/workflows/build.yml 2026-07-28 08:12:40.000000000 +0200 @@ -30,6 +30,29 @@ make VERBOSE=1 make test VERBOSE=1 + # The other test jobs build with BUILD_TOOLS=OFF, and the packaging jobs build + # fpcalc against a pinned FFmpeg. Nothing builds the FFmpeg audio reader + # against the system FFmpeg, which is the configuration distributions use. + test-linux-tools: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y cmake libavcodec-dev libavformat-dev libavutil-dev libswresample-dev libfftw3-dev + - name: Show FFmpeg version + run: dpkg-query -W -f='${Package} ${Version}\n' libavcodec-dev libavformat-dev libavutil-dev libswresample-dev + - name: Build with tools against the system FFmpeg + run: | + mkdir build.test.tools + cd build.test.tools + cmake -DCMAKE_BUILD_TYPE=Release -DFFT_LIB=fftw3 -DBUILD_TESTS=ON -DBUILD_TOOLS=ON .. + make VERBOSE=1 + make test VERBOSE=1 + - name: Check fpcalc output + run: ./build.test.tools/src/cmd/fpcalc -raw tests/data/test.mp3 | diff -u - tests/data/test.mp3.fpcalc.out + test-macos: runs-on: macos-latest strategy: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chromaprint-1.6.0/CMakeLists.txt new/chromaprint-1.6.1/CMakeLists.txt --- old/chromaprint-1.6.0/CMakeLists.txt 2025-08-28 19:54:00.000000000 +0200 +++ new/chromaprint-1.6.1/CMakeLists.txt 2026-07-28 08:12:40.000000000 +0200 @@ -2,7 +2,7 @@ set(chromaprint_VERSION_MAJOR 1) set(chromaprint_VERSION_MINOR 6) -set(chromaprint_VERSION_PATCH 0) +set(chromaprint_VERSION_PATCH 1) set(chromaprint_VERSION "${chromaprint_VERSION_MAJOR}.${chromaprint_VERSION_MINOR}.${chromaprint_VERSION_PATCH}") project(chromaprint LANGUAGES C CXX VERSION "${chromaprint_VERSION}") @@ -106,7 +106,7 @@ if(NOT FFT_LIB) if(APPLE AND ACCELERATE_LIBRARIES) set(FFT_LIB "vdsp") - elseif(FFMPEG_LIBAVUTIL_TX_FOUND) + elseif(HAVE_FFMPEG_TX_RDFT) set(FFT_LIB "avtx") elseif(FFMPEG_LIBAVCODEC_FFT_FOUND) set(FFT_LIB "avfft") @@ -126,7 +126,7 @@ message(FATAL_ERROR "Selected ${FFT_LIB} for FFT calculations, but the library is not found") endif() elseif(FFT_LIB STREQUAL "avtx") - if(FFMPEG_LIBAVUTIL_TX_FOUND) + if(HAVE_FFMPEG_TX_RDFT) set(USE_AVTX ON) else() message(FATAL_ERROR "Selected ${FFT_LIB} for FFT calculations, but the library is not found") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chromaprint-1.6.0/NEWS.txt new/chromaprint-1.6.1/NEWS.txt --- old/chromaprint-1.6.0/NEWS.txt 2025-08-28 19:54:00.000000000 +0200 +++ new/chromaprint-1.6.1/NEWS.txt 2026-07-28 08:12:40.000000000 +0200 @@ -1,3 +1,17 @@ +Version 1.6.1 -- July 28, 2026 +============================== + + - Fixed a heap buffer overflow when decoding a fingerprint that has extra + data after the encoded values. Applications that decode fingerprints from + untrusted sources should update. + - Fixed building against FFmpeg 4.x, which had not compiled since the + channel layout API changed in 5.1 + - Audio can now be fed in buffers that do not end on a frame boundary; + previously a partial frame at the end of a call was dropped + - Fixed an implicit integer conversion warning on LLVM + - Fixed installing to absolute paths + - Build fpcalc against the system FFmpeg in CI + Version 1.6.0 -- August 28, 2025 ================================= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chromaprint-1.6.0/README.md new/chromaprint-1.6.1/README.md --- old/chromaprint-1.6.0/README.md 2025-08-28 19:54:00.000000000 +0200 +++ new/chromaprint-1.6.1/README.md 2026-07-28 08:12:40.000000000 +0200 @@ -62,7 +62,7 @@ You can use Doxygen to generate a HTML version of the API documentation: $ make docs - $ $BROWSER docs/html/index.html + $ $BROWSER doc/html/index.html ## Unit Tests diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chromaprint-1.6.0/cmake/modules/FindFFmpeg.cmake new/chromaprint-1.6.1/cmake/modules/FindFFmpeg.cmake --- old/chromaprint-1.6.0/cmake/modules/FindFFmpeg.cmake 2025-08-28 19:54:00.000000000 +0200 +++ new/chromaprint-1.6.1/cmake/modules/FindFFmpeg.cmake 2026-07-28 08:12:40.000000000 +0200 @@ -123,6 +123,17 @@ ${FFMPEG_LIBAVCODEC_LIBRARIES} ${FFMPEG_LIBAVUTIL_LIBRARIES}) + IF(FFMPEG_LIBAVUTIL_TX_FOUND) + include(CheckCSourceCompiles) + + cmake_push_check_state() + list(APPEND CMAKE_REQUIRED_INCLUDES ${FFMPEG_LIBAVUTIL_TX_INCLUDE_DIRS}) + check_c_source_compiles("#include <libavutil/tx.h> + static int test = AV_TX_FLOAT_RDFT; + int main(void) { return 0; }" HAVE_FFMPEG_TX_RDFT) + cmake_pop_check_state() + ENDIF() + ELSE () MESSAGE(STATUS "Could not find FFMPEG") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chromaprint-1.6.0/libchromaprint.pc.cmake new/chromaprint-1.6.1/libchromaprint.pc.cmake --- old/chromaprint-1.6.0/libchromaprint.pc.cmake 2025-08-28 19:54:00.000000000 +0200 +++ new/chromaprint-1.6.1/libchromaprint.pc.cmake 2026-07-28 08:12:40.000000000 +0200 @@ -1,7 +1,7 @@ prefix=@CMAKE_INSTALL_PREFIX@ -exec_prefix=${prefix}/@CMAKE_INSTALL_BINDIR@ -libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ -includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ +exec_prefix=@CMAKE_INSTALL_FULL_BINDIR@ +libdir=@CMAKE_INSTALL_FULL_LIBDIR@ +includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ Name: @PROJECT_NAME@ Description: Audio fingerprint library diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chromaprint-1.6.0/src/audio/ffmpeg_audio_processor_swresample.h new/chromaprint-1.6.1/src/audio/ffmpeg_audio_processor_swresample.h --- old/chromaprint-1.6.0/src/audio/ffmpeg_audio_processor_swresample.h 2025-08-28 19:54:00.000000000 +0200 +++ new/chromaprint-1.6.1/src/audio/ffmpeg_audio_processor_swresample.h 2026-07-28 08:12:40.000000000 +0200 @@ -6,8 +6,11 @@ extern "C" { #include <libswresample/swresample.h> +#include <libavutil/opt.h> } +#include "audio/ffmpeg_compat.h" + namespace chromaprint { class FFmpegAudioProcessor { @@ -28,9 +31,15 @@ av_opt_set_double(m_swr_ctx, "cutoff", 0.8, 0); } +#if CHROMAPRINT_HAVE_AV_CHANNEL_LAYOUT void SetInputChannelLayout(AVChannelLayout *channel_layout) { av_opt_set_chlayout(m_swr_ctx, "in_chlayout", channel_layout, 0); } +#else + void SetInputChannelLayout(uint64_t channel_layout) { + av_opt_set_int(m_swr_ctx, "in_channel_layout", channel_layout, 0); + } +#endif void SetInputSampleFormat(AVSampleFormat sample_format) { av_opt_set_sample_fmt(m_swr_ctx, "in_sample_fmt", sample_format, 0); @@ -40,9 +49,15 @@ av_opt_set_int(m_swr_ctx, "in_sample_rate", sample_rate, 0); } +#if CHROMAPRINT_HAVE_AV_CHANNEL_LAYOUT void SetOutputChannelLayout(AVChannelLayout *channel_layout) { av_opt_set_chlayout(m_swr_ctx, "out_chlayout", channel_layout, 0); } +#else + void SetOutputChannelLayout(uint64_t channel_layout) { + av_opt_set_int(m_swr_ctx, "out_channel_layout", channel_layout, 0); + } +#endif void SetOutputSampleFormat(AVSampleFormat sample_format) { av_opt_set_sample_fmt(m_swr_ctx, "out_sample_fmt", sample_format, 0); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chromaprint-1.6.0/src/audio/ffmpeg_audio_reader.h new/chromaprint-1.6.1/src/audio/ffmpeg_audio_reader.h --- old/chromaprint-1.6.0/src/audio/ffmpeg_audio_reader.h 2025-08-28 19:54:00.000000000 +0200 +++ new/chromaprint-1.6.1/src/audio/ffmpeg_audio_reader.h 2026-07-28 08:12:40.000000000 +0200 @@ -21,6 +21,7 @@ #include <libavutil/channel_layout.h> } +#include "audio/ffmpeg_compat.h" #include "audio/ffmpeg_audio_processor.h" namespace chromaprint { @@ -74,7 +75,7 @@ uint8_t *m_convert_buffer[1] = { nullptr }; int m_convert_buffer_nb_samples = 0; - const AVInputFormat *m_input_fmt = nullptr; + CHROMAPRINT_CONST_AVFORMAT AVInputFormat *m_input_fmt = nullptr; AVDictionary *m_input_opts = nullptr; AVFormatContext *m_format_ctx = nullptr; @@ -118,6 +119,7 @@ inline bool FFmpegAudioReader::SetInputChannels(int channels) { char buf[64]; +#if CHROMAPRINT_HAVE_AV_CHANNEL_LAYOUT if (channels == 1) sprintf(buf, "%s", "mono"); else if (channels == 2) @@ -125,6 +127,11 @@ else sprintf(buf, "%d channels", channels); return av_dict_set(&m_input_opts, "ch_layout", buf, 0) >= 0; +#else + // Before 5.1 the demuxers take a channel count, not a layout description. + sprintf(buf, "%d", channels); + return av_dict_set(&m_input_opts, "channels", buf, 0) >= 0; +#endif } inline bool FFmpegAudioReader::Open(const std::string &file_name) { @@ -149,7 +156,7 @@ return false; } - const AVCodec *codec; + CHROMAPRINT_CONST_AVFORMAT AVCodec *codec; ret = av_find_best_stream(m_format_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, &codec, 0); if (ret < 0) { SetError("Could not find any audio stream in the file", ret); @@ -184,23 +191,38 @@ m_output_sample_rate = m_codec_ctx->sample_rate; } +#if CHROMAPRINT_HAVE_AV_CHANNEL_LAYOUT AVChannelLayout output_channel_layout; - if (m_output_channels) { - av_channel_layout_default(&output_channel_layout, m_output_channels); - } else { - m_output_channels = m_codec_ctx->ch_layout.nb_channels; - av_channel_layout_default(&output_channel_layout, m_output_channels); + if (!m_output_channels) { + m_output_channels = CHROMAPRINT_CODEC_CHANNELS(m_codec_ctx); } + av_channel_layout_default(&output_channel_layout, m_output_channels); +#else + if (!m_output_channels) { + m_output_channels = CHROMAPRINT_CODEC_CHANNELS(m_codec_ctx); + } + uint64_t output_channel_layout = av_get_default_channel_layout(m_output_channels); +#endif - if (m_codec_ctx->sample_fmt != AV_SAMPLE_FMT_S16 || m_codec_ctx->ch_layout.nb_channels != m_output_channels || m_codec_ctx->sample_rate != m_output_sample_rate) { + if (m_codec_ctx->sample_fmt != AV_SAMPLE_FMT_S16 || CHROMAPRINT_CODEC_CHANNELS(m_codec_ctx) != m_output_channels || m_codec_ctx->sample_rate != m_output_sample_rate) { m_converter.reset(new FFmpegAudioProcessor()); m_converter->SetCompatibleMode(); m_converter->SetInputSampleFormat(m_codec_ctx->sample_fmt); m_converter->SetInputSampleRate(m_codec_ctx->sample_rate); +#if CHROMAPRINT_HAVE_AV_CHANNEL_LAYOUT m_converter->SetInputChannelLayout(&(m_codec_ctx->ch_layout)); +#else + m_converter->SetInputChannelLayout(m_codec_ctx->channel_layout + ? m_codec_ctx->channel_layout + : av_get_default_channel_layout(m_codec_ctx->channels)); +#endif m_converter->SetOutputSampleFormat(AV_SAMPLE_FMT_S16); m_converter->SetOutputSampleRate(m_output_sample_rate); +#if CHROMAPRINT_HAVE_AV_CHANNEL_LAYOUT m_converter->SetOutputChannelLayout(&output_channel_layout); +#else + m_converter->SetOutputChannelLayout(output_channel_layout); +#endif auto ret = m_converter->Init(); if (ret != 0) { SetError("Could not create an audio converter instance", ret); @@ -208,7 +230,9 @@ } } +#if CHROMAPRINT_HAVE_AV_CHANNEL_LAYOUT av_channel_layout_uninit(&output_channel_layout); +#endif m_opened = true; m_has_more_packets = true; @@ -315,7 +339,7 @@ int linsize; av_freep(&m_convert_buffer[0]); m_convert_buffer_nb_samples = std::max(1024 * 8, m_frame->nb_samples); - ret = av_samples_alloc(m_convert_buffer, &linsize, m_codec_ctx->ch_layout.nb_channels, m_convert_buffer_nb_samples, AV_SAMPLE_FMT_S16, 1); + ret = av_samples_alloc(m_convert_buffer, &linsize, CHROMAPRINT_CODEC_CHANNELS(m_codec_ctx), m_convert_buffer_nb_samples, AV_SAMPLE_FMT_S16, 1); if (ret < 0) { SetError("Couldn't allocate audio converter buffer", ret); return false; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chromaprint-1.6.0/src/audio/ffmpeg_compat.h new/chromaprint-1.6.1/src/audio/ffmpeg_compat.h --- old/chromaprint-1.6.0/src/audio/ffmpeg_compat.h 1970-01-01 01:00:00.000000000 +0100 +++ new/chromaprint-1.6.1/src/audio/ffmpeg_compat.h 2026-07-28 08:12:40.000000000 +0200 @@ -0,0 +1,36 @@ +// Copyright (C) 2026 Lukas Lalinsky +// Distributed under the MIT license, see the LICENSE file for details. + +#ifndef CHROMAPRINT_AUDIO_FFMPEG_COMPAT_H_ +#define CHROMAPRINT_AUDIO_FFMPEG_COMPAT_H_ + +extern "C" { +#include <libavformat/version.h> +#include <libavutil/channel_layout.h> +#include <libavutil/version.h> +} + +// AVChannelLayout, and the API around it, arrived in libavutil 57.24.100 +// (FFmpeg 5.1). Before that a layout is a plain bitmask and the channel count +// lives directly on AVCodecContext. +#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 24, 100) +#define CHROMAPRINT_HAVE_AV_CHANNEL_LAYOUT 1 +#else +#define CHROMAPRINT_HAVE_AV_CHANNEL_LAYOUT 0 +#endif + +#if CHROMAPRINT_HAVE_AV_CHANNEL_LAYOUT +#define CHROMAPRINT_CODEC_CHANNELS(ctx) ((ctx)->ch_layout.nb_channels) +#else +#define CHROMAPRINT_CODEC_CHANNELS(ctx) ((ctx)->channels) +#endif + +// avformat_open_input() and av_find_best_stream() took non-const AVInputFormat +// and AVCodec pointers before libavformat 59 (FFmpeg 5.0). +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(59, 0, 100) +#define CHROMAPRINT_CONST_AVFORMAT const +#else +#define CHROMAPRINT_CONST_AVFORMAT +#endif + +#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chromaprint-1.6.0/src/audio_processor.cpp new/chromaprint-1.6.1/src/audio_processor.cpp --- old/chromaprint-1.6.0/src/audio_processor.cpp 2025-08-28 19:54:00.000000000 +0200 +++ new/chromaprint-1.6.1/src/audio_processor.cpp 2026-07-28 08:12:40.000000000 +0200 @@ -140,6 +140,7 @@ return false; } m_buffer_offset = 0; + m_leftover.clear(); #if USE_INTERNAL_AVRESAMPLE if (m_resample_ctx) { @@ -168,16 +169,37 @@ void AudioProcessor::Consume(const int16_t *input, int length) { assert(length >= 0); + if (!m_leftover.empty()) { + while (length > 0 && static_cast<int>(m_leftover.size()) < m_num_channels) { + m_leftover.push_back(*input++); + length--; + } + if (static_cast<int>(m_leftover.size()) < m_num_channels) { + return; + } + ConsumeAligned(&m_leftover[0], m_num_channels); + m_leftover.clear(); + } + const int remainder = length % m_num_channels; + ConsumeAligned(input, length - remainder); + if (remainder > 0) { + m_leftover.assign(input + length - remainder, input + length); + } +} + +void AudioProcessor::ConsumeAligned(const int16_t *input, int length) +{ + assert(length >= 0); assert(length % m_num_channels == 0); length /= m_num_channels; while (length > 0) { - int consumed = Load(input, length); + int consumed = Load(input, length); input += consumed * m_num_channels; length -= consumed; if (m_buffer.size() == m_buffer_offset) { Resample(); if (m_buffer.size() == m_buffer_offset) { - DEBUG("chromaprint::AudioProcessor::Consume() -- Resampling failed?"); + DEBUG("chromaprint::AudioProcessor::ConsumeAligned() -- Resampling failed?"); return; } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chromaprint-1.6.0/src/audio_processor.h new/chromaprint-1.6.1/src/audio_processor.h --- old/chromaprint-1.6.0/src/audio_processor.h 2025-08-28 19:54:00.000000000 +0200 +++ new/chromaprint-1.6.1/src/audio_processor.h 2026-07-28 08:12:40.000000000 +0200 @@ -51,6 +51,7 @@ private: CHROMAPRINT_DISABLE_COPY(AudioProcessor); + void ConsumeAligned(const int16_t *input, int length); int Load(const int16_t *input, int length); void LoadMono(const int16_t *input, int length); void LoadStereo(const int16_t *input, int length); @@ -62,6 +63,9 @@ std::vector<int16_t> m_resample_buffer; int m_target_sample_rate; int m_num_channels; + // Trailing partial frame carried over between Consume() calls when a + // caller splits its audio on non-frame boundaries. + std::vector<int16_t> m_leftover; AudioConsumer *m_consumer; struct AVResampleContext *m_resample_ctx; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chromaprint-1.6.0/src/chromaprint.h new/chromaprint-1.6.1/src/chromaprint.h --- old/chromaprint-1.6.0/src/chromaprint.h 2025-08-28 19:54:00.000000000 +0200 +++ new/chromaprint-1.6.1/src/chromaprint.h 2026-07-28 08:12:40.000000000 +0200 @@ -84,7 +84,7 @@ #define CHROMAPRINT_VERSION_MAJOR 1 #define CHROMAPRINT_VERSION_MINOR 6 -#define CHROMAPRINT_VERSION_PATCH 0 +#define CHROMAPRINT_VERSION_PATCH 1 enum ChromaprintAlgorithm { CHROMAPRINT_ALGORITHM_TEST1 = 0, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chromaprint-1.6.0/src/fingerprint_decompressor.cpp new/chromaprint-1.6.1/src/fingerprint_decompressor.cpp --- old/chromaprint-1.6.0/src/fingerprint_decompressor.cpp 2025-08-28 19:54:00.000000000 +0200 +++ new/chromaprint-1.6.1/src/fingerprint_decompressor.cpp 2026-07-28 08:12:40.000000000 +0200 @@ -90,7 +90,9 @@ if (num_exceptional_bits) { m_exceptional_bits.resize(GetUnpackedInt5ArraySize(GetPackedInt5ArraySize(num_exceptional_bits))); - UnpackInt5Array(input.begin() + offset, input.end(), m_exceptional_bits.begin()); + UnpackInt5Array(input.begin() + offset, + input.begin() + offset + GetPackedInt5ArraySize(num_exceptional_bits), + m_exceptional_bits.begin()); for (size_t i = 0, j = 0; i < m_bits.size(); i++) { if (m_bits[i] == kMaxNormalValue) { m_bits[i] += m_exceptional_bits[j++]; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chromaprint-1.6.0/src/simhash.cpp new/chromaprint-1.6.1/src/simhash.cpp --- old/chromaprint-1.6.0/src/simhash.cpp 2025-08-28 19:54:00.000000000 +0200 +++ new/chromaprint-1.6.1/src/simhash.cpp 2026-07-28 08:12:40.000000000 +0200 @@ -20,7 +20,7 @@ } } - const int threshold = size / 2; + const size_t threshold = size / 2; uint32_t hash = 0; for (size_t i = 0; i < 32; i++) { const int b = v[i] > threshold ? 1 : 0; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chromaprint-1.6.0/tests/test_audio_processor.cpp new/chromaprint-1.6.1/tests/test_audio_processor.cpp --- old/chromaprint-1.6.0/tests/test_audio_processor.cpp 2025-08-28 19:54:00.000000000 +0200 +++ new/chromaprint-1.6.1/tests/test_audio_processor.cpp 2026-07-28 08:12:40.000000000 +0200 @@ -1,6 +1,7 @@ #include <gtest/gtest.h> #include <algorithm> #include <vector> +#include <string> #include <fstream> #include "test_utils.h" #include "audio_processor.h" @@ -110,3 +111,39 @@ ASSERT_EQ(data2[i], buffer.data()[i]) << "Signals differ at index " << i; } } + +TEST(AudioProcessor, ChunkedConsumeMatchesSingleConsume) +{ + std::vector<short> data = LoadAudioFile("data/test_stereo_44100.raw"); + + AudioBuffer expected; + AudioProcessor reference(11025, &expected); + reference.Reset(44100, 2); + reference.Consume(data.data(), data.size()); + reference.Flush(); + + // Some of these are multiples of the channel count and some are not. The + // ones that are not leave a partial frame to be carried into the next + // call; the rest are there as a control. However the caller splits its + // input, the result must be the same. + const size_t chunk_sizes[] = { 1, 2, 3, 5, 7, 17, 511, 997, 4096 }; + + for (size_t c = 0; c < NELEMS(chunk_sizes); c++) { + const size_t chunk_size = chunk_sizes[c]; + SCOPED_TRACE("chunk size " + std::to_string(chunk_size)); + + AudioBuffer buffer; + AudioProcessor processor(11025, &buffer); + processor.Reset(44100, 2); + for (size_t offset = 0; offset < data.size(); offset += chunk_size) { + processor.Consume(data.data() + offset, + std::min(chunk_size, data.size() - offset)); + } + processor.Flush(); + + ASSERT_EQ(expected.data().size(), buffer.data().size()); + for (size_t i = 0; i < expected.data().size(); i++) { + ASSERT_EQ(expected.data()[i], buffer.data()[i]) << "Signals differ at index " << i; + } + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/chromaprint-1.6.0/tests/test_fingerprint_decompressor.cpp new/chromaprint-1.6.1/tests/test_fingerprint_decompressor.cpp --- old/chromaprint-1.6.0/tests/test_fingerprint_decompressor.cpp 2025-08-28 19:54:00.000000000 +0200 +++ new/chromaprint-1.6.1/tests/test_fingerprint_decompressor.cpp 2026-07-28 08:12:40.000000000 +0200 @@ -68,6 +68,18 @@ ASSERT_EQ(0, algorithm); } +TEST(FingerprintDecompressor, OneItemOneBitExceptWithTrailingData) +{ + uint32_t expected[] = { 1<<6 }; + char data[] = { 0, 0, 0, 1, 7, 0, char(255), char(255), char(255), char(255) }; + + int algorithm = 1; + std::vector<uint32_t> value; + ASSERT_EQ(true, DecompressFingerprint(std::string(data, NELEMS(data)), value, algorithm)); + CheckFingerprints(value, expected, NELEMS(expected)); + ASSERT_EQ(0, algorithm); +} + TEST(FingerprintDecompressor, TwoItems) { uint32_t expected[] = { 1, 0 };
