From b3b778ddcfae0b6bb19d6c05584720dd7a6c68dc Mon Sep 17 00:00:00 2001 From: rome-xi Date: Mon, 24 Aug 2026 02:22:55 +0000 Subject: [PATCH] fix: use BrotliDecoderAttachDictionary for custom dictionaries Signed-off-by: rome-xi --- src/brotlicffi/_api.py | 5 ++++- src/brotlicffi/_build.py | 11 +++++++++++ test/test_custom_dictionary.py | 22 ++++++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 test/test_custom_dictionary.py diff --git a/src/brotlicffi/_api.py b/src/brotlicffi/_api.py index 75a5182..002f68c 100644 --- a/src/brotlicffi/_api.py +++ b/src/brotlicffi/_api.py @@ -390,11 +390,14 @@ def __init__(self, dictionary=b''): if dictionary: self._dictionary = ffi.new("uint8_t []", dictionary) self._dictionary_size = len(dictionary) - lib.BrotliDecoderSetCustomDictionary( + attached = lib.BrotliDecoderAttachDictionary( self._decoder, + lib.BROTLI_SHARED_DICTIONARY_RAW, self._dictionary_size, self._dictionary ) + if attached != lib.BROTLI_TRUE: + raise error("Error attaching custom dictionary.") @staticmethod def _calculate_buffer_size( diff --git a/src/brotlicffi/_build.py b/src/brotlicffi/_build.py index 115be2e..8ddb000 100644 --- a/src/brotlicffi/_build.py +++ b/src/brotlicffi/_build.py @@ -19,6 +19,7 @@ "_brotlicffi", """#include #include + #include """, libraries=libraries, include_dirs=["libbrotli/c", "libbrotli/c/include", "libbrotli/c/common"] @@ -112,6 +113,16 @@ const char* BrotliDecoderErrorString(BrotliDecoderErrorCode c); + typedef enum BrotliSharedDictionaryType { + BROTLI_SHARED_DICTIONARY_RAW = 0, + BROTLI_SHARED_DICTIONARY_SERIALIZED = 1 + } BrotliSharedDictionaryType; + + BROTLI_BOOL BrotliDecoderAttachDictionary(BrotliDecoderState* state, + BrotliSharedDictionaryType type, + size_t data_size, + const uint8_t* data); + /* enc/encode.h */ typedef ... BrotliEncoderState; diff --git a/test/test_custom_dictionary.py b/test/test_custom_dictionary.py new file mode 100644 index 0000000..d50bd8c --- /dev/null +++ b/test/test_custom_dictionary.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +""" +Regression tests for Decompressor custom dictionary support (#215). +""" +import brotlicffi + + +def test_decompressor_accepts_custom_dictionary(): + """ + Constructing Decompressor(dictionary=...) must not raise AttributeError + for the removed BrotliDecoderSetCustomDictionary API. + """ + decompressor = brotlicffi.Decompressor(dictionary=b"custom dictionary") + assert decompressor is not None + + +def test_decompressor_without_dictionary_still_works(): + """Attaching no dictionary leaves ordinary decompression working.""" + payload = b"hello world from brotlicffi custom dictionary regression" + compressed = brotlicffi.compress(payload) + decompressor = brotlicffi.Decompressor() + assert decompressor.decompress(compressed) + decompressor.finish() == payload