brotli 0.9.0 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6e39135e3c6e289c1b4f233d8e0bec31f1cfb6be48f63280b5a7609965b88459
4
- data.tar.gz: 5f0bae9eb2e35baf822e7eff9e8432e24043893afe29c70506050d41c073bbaa
3
+ metadata.gz: 035e04e32804b36b5525cf4ba7688e19a199288e0056fcfceeeac67f11f72c9f
4
+ data.tar.gz: 8ce5e925a781060c0d46dfebd69beb367c62622fb808ef247906e0bf2229aaa8
5
5
  SHA512:
6
- metadata.gz: 46ae27522c3cb015279531a8d6b91af3afcd40a0b61c552db76e7caa9562a547f8f4e2f09873f5e113314cbc0ffe811fcfdc9a0c02b84aa2df4ade1d005857e9
7
- data.tar.gz: cc393196d928f8d761b83bf7f04415c7f1ddd1b2f113008063e9b99615004adf00af95171932d009efeeb0e6ad2f5edb3c26196610475b08a4e5db0d56e5e201
6
+ metadata.gz: 70c2bdf0f5028d80f5f0c578f89bf2c6818de1c9c4f795fe61aeeffbbcf570353d97699ce02f9e44e713f54e34fd9c0a745d9b6f3ef9e7f9b62e5ffc6f1b0707
7
+ data.tar.gz: dd17edfde50109928ca623452044288b6d369cd6a29706727248623f8ad6d03ea89857fd668e67ca01b22a1baf39b27fbd47c86635a2455ec1c1d2400c4c5d77
data/ext/brotli/brotli.c CHANGED
@@ -74,6 +74,7 @@ typedef struct {
74
74
  BrotliDecoderResult r;
75
75
  uint8_t* dict;
76
76
  size_t dict_len;
77
+ int oom;
77
78
  } brotli_inflate_args_t;
78
79
 
79
80
  static void
@@ -116,14 +117,19 @@ brotli_inflate_no_gvl(void *arg)
116
117
  if (r != BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) {
117
118
  break;
118
119
  }
119
- append_buffer(buffer, output, BUFSIZ);
120
+ if (append_buffer(buffer, output, BUFSIZ) != 0) {
121
+ args->oom = 1;
122
+ break;
123
+ }
120
124
  available_out = BUFSIZ;
121
125
  next_out = output;
122
126
  }
123
127
 
124
128
  if (r == BROTLI_DECODER_RESULT_SUCCESS) {
125
129
  if (next_out != output) {
126
- append_buffer(buffer, output, next_out - output);
130
+ if (append_buffer(buffer, output, next_out - output) != 0) {
131
+ args->oom = 1;
132
+ }
127
133
  }
128
134
  }
129
135
  args->r = r;
@@ -166,6 +172,10 @@ brotli_inflate(int argc, VALUE *argv, VALUE self)
166
172
  args.len = (size_t)RSTRING_LEN(str);
167
173
  args.s = brotli_decoder_state_create();
168
174
  args.buffer = create_buffer(BUFSIZ);
175
+ if (!args.buffer) {
176
+ brotli_inflate_cleanup(&args);
177
+ rb_raise(rb_eNoMemError, "failed to allocate decompression buffer");
178
+ }
169
179
  args.r = BROTLI_DECODER_RESULT_ERROR;
170
180
 
171
181
  if (!NIL_P(dict)) {
@@ -180,6 +190,12 @@ brotli_inflate(int argc, VALUE *argv, VALUE self)
180
190
  RB_GC_GUARD(str);
181
191
  RB_GC_GUARD(dict);
182
192
 
193
+ /* Check before args.r: a failed final append leaves r at SUCCESS. */
194
+ if (args.oom) {
195
+ brotli_inflate_cleanup(&args);
196
+ rb_raise(rb_eNoMemError, "failed to allocate decompression buffer");
197
+ }
198
+
183
199
  if (args.r == BROTLI_DECODER_RESULT_SUCCESS) {
184
200
  int state = 0;
185
201
  value = rb_protect(brotli_inflate_take_result, (VALUE)&args, &state);
@@ -324,6 +340,7 @@ typedef struct {
324
340
  buffer_t* buffer;
325
341
  BROTLI_BOOL finished;
326
342
  BrotliEncoderPreparedDictionary* prepared_dict;
343
+ int oom;
327
344
  } brotli_deflate_args_t;
328
345
 
329
346
  static void
@@ -364,7 +381,11 @@ brotli_deflate_no_gvl(void *arg)
364
381
  args->finished = BROTLI_FALSE;
365
382
  break;
366
383
  } else {
367
- append_buffer(buffer, output, next_out - output);
384
+ if (append_buffer(buffer, output, next_out - output) != 0) {
385
+ args->oom = 1;
386
+ args->finished = BROTLI_FALSE;
387
+ break;
388
+ }
368
389
  available_out = BUFSIZ;
369
390
  next_out = output;
370
391
 
@@ -418,6 +439,10 @@ brotli_deflate(int argc, VALUE *argv, VALUE self)
418
439
  }
419
440
  max_compressed_size = BrotliEncoderMaxCompressedSize(args.len);
420
441
  args.buffer = create_buffer(max_compressed_size);
442
+ if (!args.buffer) {
443
+ brotli_deflate_cleanup(&args);
444
+ rb_raise(rb_eNoMemError, "failed to allocate compression buffer");
445
+ }
421
446
  args.finished = BROTLI_FALSE;
422
447
 
423
448
  args.prepared_dict = NULL;
@@ -443,6 +468,10 @@ brotli_deflate(int argc, VALUE *argv, VALUE self)
443
468
  rb_thread_call_without_gvl(brotli_deflate_no_gvl, &args, NULL, NULL);
444
469
  RB_GC_GUARD(str);
445
470
  RB_GC_GUARD(dict);
471
+ if (args.oom) {
472
+ brotli_deflate_cleanup(&args);
473
+ rb_raise(rb_eNoMemError, "failed to allocate compression buffer");
474
+ }
446
475
  if (args.finished == BROTLI_TRUE) {
447
476
  int state = 0;
448
477
  value = rb_protect(brotli_deflate_take_result, (VALUE)&args, &state);
data/ext/brotli/buffer.c CHANGED
@@ -1,18 +1,32 @@
1
1
  #include "buffer.h"
2
- #include "ruby/ruby.h"
3
2
 
4
3
  #include <stdint.h>
4
+ #include <stdlib.h>
5
5
  #include <string.h>
6
6
 
7
7
  #define BUFFER_INITIAL_SIZE 1024
8
8
 
9
+ /*
10
+ * append_buffer runs inside rb_thread_call_without_gvl. A failing Ruby
11
+ * allocator there raises NoMemoryError past the caller's cleanup, so this
12
+ * buffer uses malloc/realloc/free and reports failure through return values.
13
+ */
14
+
9
15
  buffer_t*
10
16
  create_buffer(size_t initial)
11
17
  {
12
- buffer_t *buffer = ruby_xmalloc(sizeof(*buffer));
18
+ buffer_t *buffer = malloc(sizeof(*buffer));
19
+
20
+ if (!buffer) {
21
+ return NULL;
22
+ }
13
23
  buffer->used = 0;
14
24
  buffer->size = initial > 0 ? initial : BUFFER_INITIAL_SIZE;
15
- buffer->ptr = ruby_xmalloc(buffer->size);
25
+ buffer->ptr = malloc(buffer->size);
26
+ if (!buffer->ptr) {
27
+ free(buffer);
28
+ return NULL;
29
+ }
16
30
  return buffer;
17
31
  }
18
32
 
@@ -23,8 +37,8 @@ delete_buffer(buffer_t* buffer)
23
37
  return;
24
38
  }
25
39
 
26
- ruby_xfree(buffer->ptr);
27
- ruby_xfree(buffer);
40
+ free(buffer->ptr);
41
+ free(buffer);
28
42
  }
29
43
 
30
44
  static size_t
@@ -42,27 +56,37 @@ buffer_size_for(size_t current, size_t required)
42
56
  return size;
43
57
  }
44
58
 
45
- static void
59
+ static int
46
60
  expand_buffer(buffer_t* buffer, size_t required)
47
61
  {
48
- buffer->size = buffer_size_for(buffer->size, required);
49
- buffer->ptr = ruby_xrealloc(buffer->ptr, buffer->size);
62
+ size_t size = buffer_size_for(buffer->size, required);
63
+ char* ptr = realloc(buffer->ptr, size);
64
+
65
+ if (!ptr) {
66
+ return -1;
67
+ }
68
+ buffer->ptr = ptr;
69
+ buffer->size = size;
70
+ return 0;
50
71
  }
51
72
 
52
- void
73
+ int
53
74
  append_buffer(buffer_t* buffer, const void* ptr, size_t size)
54
75
  {
55
76
  size_t required;
56
77
 
57
78
  if (size == 0) {
58
- return;
79
+ return 0;
59
80
  }
60
81
 
61
82
  required = buffer->used + size;
62
83
  if (required > buffer->size) {
63
- expand_buffer(buffer, required);
84
+ if (expand_buffer(buffer, required) != 0) {
85
+ return -1;
86
+ }
64
87
  }
65
88
 
66
89
  memcpy(buffer->ptr + buffer->used, ptr, size);
67
90
  buffer->used += size;
91
+ return 0;
68
92
  }
data/ext/brotli/buffer.h CHANGED
@@ -9,8 +9,10 @@ typedef struct {
9
9
  size_t used;
10
10
  } buffer_t;
11
11
 
12
+ /* Never raise, so they are safe without the GVL. create_buffer returns NULL
13
+ * and append_buffer returns -1 when allocation fails. */
12
14
  buffer_t* create_buffer(size_t initial);
13
15
  void delete_buffer(buffer_t* buffer);
14
- void append_buffer(buffer_t* buffer, const void* ptr, size_t size);
16
+ int append_buffer(buffer_t* buffer, const void* ptr, size_t size);
15
17
 
16
18
  #endif /* BUFFER_H */
@@ -106,7 +106,9 @@ def system_brotli_available?
106
106
  have_header("brotli/shared_dictionary.h") &&
107
107
  have_func("BrotliEncoderPrepareDictionary", "brotli/encode.h") &&
108
108
  have_func("BrotliEncoderAttachPreparedDictionary", "brotli/encode.h") &&
109
- have_func("BrotliDecoderAttachDictionary", "brotli/decode.h")
109
+ have_func("BrotliDecoderAttachDictionary", "brotli/decode.h") &&
110
+ # CVE-2026-111497: patched decoders (1.2.1+, or distro backports) define this error code.
111
+ have_const("BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH", "brotli/decode.h")
110
112
 
111
113
  restore_mkmf_flags(flags) unless available
112
114
  available
@@ -127,5 +129,19 @@ if use_vendored_brotli
127
129
  $INCFLAGS << " -Ienc -Idec -Icommon -Iinclude"
128
130
  end
129
131
 
132
+ # Leak-harness build hooks (inert unless the env var is set).
133
+ # One append reaches brotli.c, buffer.c, and the vendored sources, because
134
+ # add_vendored_sources_to_makefile rewrites ORIG_SRCS/OBJS after create_makefile.
135
+ if ENV["BROTLI_DEBUG"] || ENV["BROTLI_ASAN"]
136
+ # Append -O0 last so it overrides any earlier optimization flag already in
137
+ # $CFLAGS (-O2/-O3/-Os/-Ofast/bare -O) -- the last -O on the command line wins
138
+ # for both gcc and clang. A gsub(/-O\d/) would miss -Os/-Ofast/-O.
139
+ $CFLAGS << " -O0 -g3 -fno-omit-frame-pointer"
140
+ end
141
+ if ENV["BROTLI_ASAN"]
142
+ $CFLAGS << " -fsanitize=address"
143
+ $LDFLAGS << " -fsanitize=address"
144
+ end
145
+
130
146
  create_makefile("brotli/brotli")
131
147
  add_vendored_sources_to_makefile if use_vendored_brotli
@@ -1,3 +1,3 @@
1
1
  module Brotli
2
- VERSION = '0.9.0'
2
+ VERSION = '0.9.2'
3
3
  end
@@ -19,7 +19,7 @@
19
19
 
20
20
  #define BROTLI_VERSION_MAJOR 1
21
21
  #define BROTLI_VERSION_MINOR 2
22
- #define BROTLI_VERSION_PATCH 0
22
+ #define BROTLI_VERSION_PATCH 1
23
23
 
24
24
  #define BROTLI_VERSION BROTLI_MAKE_HEX_VERSION( \
25
25
  BROTLI_VERSION_MAJOR, BROTLI_VERSION_MINOR, BROTLI_VERSION_PATCH)
@@ -33,7 +33,7 @@
33
33
  */
34
34
 
35
35
  #define BROTLI_ABI_CURRENT 3
36
- #define BROTLI_ABI_REVISION 0
36
+ #define BROTLI_ABI_REVISION 1
37
37
  #define BROTLI_ABI_AGE 2
38
38
 
39
39
  #if BROTLI_VERSION_MAJOR != (BROTLI_ABI_CURRENT - BROTLI_ABI_AGE)
@@ -1176,7 +1176,7 @@ static BrotliDecoderErrorCode DecodeContextMap(brotli_reg_t context_map_size,
1176
1176
 
1177
1177
  /* Decodes a command or literal and updates block type ring-buffer.
1178
1178
  Reads 3..54 bits. */
1179
- static BROTLI_INLINE BROTLI_BOOL DecodeBlockTypeAndLength(
1179
+ static BROTLI_INLINE BrotliDecoderErrorCode DecodeBlockTypeAndLength(
1180
1180
  int safe, BrotliDecoderState* s, int tree_type) {
1181
1181
  brotli_reg_t max_block_type = s->num_block_types[tree_type];
1182
1182
  const HuffmanCode* type_tree = &s->block_type_trees[
@@ -1187,7 +1187,7 @@ static BROTLI_INLINE BROTLI_BOOL DecodeBlockTypeAndLength(
1187
1187
  brotli_reg_t* ringbuffer = &s->block_type_rb[tree_type * 2];
1188
1188
  brotli_reg_t block_type;
1189
1189
  if (max_block_type <= 1) {
1190
- return BROTLI_FALSE;
1190
+ return BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH;
1191
1191
  }
1192
1192
 
1193
1193
  /* Read 0..15 + 3..39 bits. */
@@ -1197,11 +1197,13 @@ static BROTLI_INLINE BROTLI_BOOL DecodeBlockTypeAndLength(
1197
1197
  } else {
1198
1198
  BrotliBitReaderState memento;
1199
1199
  BrotliBitReaderSaveState(br, &memento);
1200
- if (!SafeReadSymbol(type_tree, br, &block_type)) return BROTLI_FALSE;
1200
+ if (!SafeReadSymbol(type_tree, br, &block_type)) {
1201
+ return BROTLI_DECODER_NEEDS_MORE_INPUT;
1202
+ }
1201
1203
  if (!SafeReadBlockLength(s, &s->block_length[tree_type], len_tree, br)) {
1202
1204
  s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_NONE;
1203
1205
  BrotliBitReaderRestoreState(br, &memento);
1204
- return BROTLI_FALSE;
1206
+ return BROTLI_DECODER_NEEDS_MORE_INPUT;
1205
1207
  }
1206
1208
  }
1207
1209
 
@@ -1217,7 +1219,7 @@ static BROTLI_INLINE BROTLI_BOOL DecodeBlockTypeAndLength(
1217
1219
  }
1218
1220
  ringbuffer[0] = ringbuffer[1];
1219
1221
  ringbuffer[1] = block_type;
1220
- return BROTLI_TRUE;
1222
+ return BROTLI_DECODER_SUCCESS;
1221
1223
  }
1222
1224
 
1223
1225
  static BROTLI_INLINE void DetectTrivialLiteralBlockTypes(
@@ -1254,62 +1256,68 @@ static BROTLI_INLINE void PrepareLiteralDecoding(BrotliDecoderState* s) {
1254
1256
 
1255
1257
  /* Decodes the block type and updates the state for literal context.
1256
1258
  Reads 3..54 bits. */
1257
- static BROTLI_INLINE BROTLI_BOOL DecodeLiteralBlockSwitchInternal(
1259
+ static BROTLI_INLINE BrotliDecoderErrorCode DecodeLiteralBlockSwitchInternal(
1258
1260
  int safe, BrotliDecoderState* s) {
1259
- if (!DecodeBlockTypeAndLength(safe, s, 0)) {
1260
- return BROTLI_FALSE;
1261
+ BrotliDecoderErrorCode result = DecodeBlockTypeAndLength(safe, s, 0);
1262
+ if (result != BROTLI_DECODER_SUCCESS) {
1263
+ return result;
1261
1264
  }
1262
1265
  PrepareLiteralDecoding(s);
1263
- return BROTLI_TRUE;
1266
+ return BROTLI_DECODER_SUCCESS;
1264
1267
  }
1265
1268
 
1266
- static void BROTLI_NOINLINE DecodeLiteralBlockSwitch(BrotliDecoderState* s) {
1267
- DecodeLiteralBlockSwitchInternal(0, s);
1269
+ static BROTLI_NOINLINE BrotliDecoderErrorCode
1270
+ DecodeLiteralBlockSwitch(BrotliDecoderState* s) {
1271
+ return DecodeLiteralBlockSwitchInternal(0, s);
1268
1272
  }
1269
1273
 
1270
- static BROTLI_BOOL BROTLI_NOINLINE SafeDecodeLiteralBlockSwitch(
1274
+ static BROTLI_NOINLINE BrotliDecoderErrorCode SafeDecodeLiteralBlockSwitch(
1271
1275
  BrotliDecoderState* s) {
1272
1276
  return DecodeLiteralBlockSwitchInternal(1, s);
1273
1277
  }
1274
1278
 
1275
1279
  /* Block switch for insert/copy length.
1276
1280
  Reads 3..54 bits. */
1277
- static BROTLI_INLINE BROTLI_BOOL DecodeCommandBlockSwitchInternal(
1281
+ static BROTLI_INLINE BrotliDecoderErrorCode DecodeCommandBlockSwitchInternal(
1278
1282
  int safe, BrotliDecoderState* s) {
1279
- if (!DecodeBlockTypeAndLength(safe, s, 1)) {
1280
- return BROTLI_FALSE;
1283
+ BrotliDecoderErrorCode result = DecodeBlockTypeAndLength(safe, s, 1);
1284
+ if (result != BROTLI_DECODER_SUCCESS) {
1285
+ return result;
1281
1286
  }
1282
1287
  s->htree_command = s->insert_copy_hgroup.htrees[s->block_type_rb[3]];
1283
- return BROTLI_TRUE;
1288
+ return BROTLI_DECODER_SUCCESS;
1284
1289
  }
1285
1290
 
1286
- static void BROTLI_NOINLINE DecodeCommandBlockSwitch(BrotliDecoderState* s) {
1287
- DecodeCommandBlockSwitchInternal(0, s);
1291
+ static BROTLI_NOINLINE BrotliDecoderErrorCode
1292
+ DecodeCommandBlockSwitch(BrotliDecoderState* s) {
1293
+ return DecodeCommandBlockSwitchInternal(0, s);
1288
1294
  }
1289
1295
 
1290
- static BROTLI_BOOL BROTLI_NOINLINE SafeDecodeCommandBlockSwitch(
1291
- BrotliDecoderState* s) {
1296
+ static BROTLI_NOINLINE BrotliDecoderErrorCode
1297
+ SafeDecodeCommandBlockSwitch(BrotliDecoderState* s) {
1292
1298
  return DecodeCommandBlockSwitchInternal(1, s);
1293
1299
  }
1294
1300
 
1295
1301
  /* Block switch for distance codes.
1296
1302
  Reads 3..54 bits. */
1297
- static BROTLI_INLINE BROTLI_BOOL DecodeDistanceBlockSwitchInternal(
1303
+ static BROTLI_INLINE BrotliDecoderErrorCode DecodeDistanceBlockSwitchInternal(
1298
1304
  int safe, BrotliDecoderState* s) {
1299
- if (!DecodeBlockTypeAndLength(safe, s, 2)) {
1300
- return BROTLI_FALSE;
1305
+ BrotliDecoderErrorCode result = DecodeBlockTypeAndLength(safe, s, 2);
1306
+ if (result != BROTLI_DECODER_SUCCESS) {
1307
+ return result;
1301
1308
  }
1302
1309
  s->dist_context_map_slice = s->dist_context_map +
1303
1310
  (s->block_type_rb[5] << BROTLI_DISTANCE_CONTEXT_BITS);
1304
1311
  s->dist_htree_index = s->dist_context_map_slice[s->distance_context];
1305
- return BROTLI_TRUE;
1312
+ return BROTLI_DECODER_SUCCESS;
1306
1313
  }
1307
1314
 
1308
- static void BROTLI_NOINLINE DecodeDistanceBlockSwitch(BrotliDecoderState* s) {
1309
- DecodeDistanceBlockSwitchInternal(0, s);
1315
+ static BROTLI_NOINLINE BrotliDecoderErrorCode
1316
+ DecodeDistanceBlockSwitch(BrotliDecoderState* s) {
1317
+ return DecodeDistanceBlockSwitchInternal(0, s);
1310
1318
  }
1311
1319
 
1312
- static BROTLI_BOOL BROTLI_NOINLINE SafeDecodeDistanceBlockSwitch(
1320
+ static BROTLI_NOINLINE BrotliDecoderErrorCode SafeDecodeDistanceBlockSwitch(
1313
1321
  BrotliDecoderState* s) {
1314
1322
  return DecodeDistanceBlockSwitchInternal(1, s);
1315
1323
  }
@@ -1940,6 +1948,9 @@ static BROTLI_INLINE BROTLI_BOOL CheckInputAmount(
1940
1948
  return BrotliCheckInputAmount(br);
1941
1949
  }
1942
1950
 
1951
+ /* NB: METHOD should return BROTLI_FALSE only in case there is not enough input;
1952
+ in case of "unsafe" execution, when input is guaranteed to be sufficient,
1953
+ result is ignored. */
1943
1954
  #define BROTLI_SAFE(METHOD) \
1944
1955
  { \
1945
1956
  if (safe) { \
@@ -1952,6 +1963,22 @@ static BROTLI_INLINE BROTLI_BOOL CheckInputAmount(
1952
1963
  } \
1953
1964
  }
1954
1965
 
1966
+ /* NB: METHOD should return BROTLI_DECODER_SUCCESS, BROTLI_DECODER_ERROR_*, or
1967
+ BROTLI_DECODER_NEEDS_MORE_INPUT; the later two break the processing. */
1968
+ #define BROTLI_SAFE_WITH_STATUS(METHOD) \
1969
+ { \
1970
+ BrotliDecoderErrorCode status; \
1971
+ if (safe) { \
1972
+ status = Safe##METHOD; \
1973
+ } else { \
1974
+ status = METHOD; \
1975
+ } \
1976
+ if (status != BROTLI_DECODER_SUCCESS) { \
1977
+ result = status; \
1978
+ goto saveStateAndReturn; \
1979
+ } \
1980
+ }
1981
+
1955
1982
  static BROTLI_INLINE BrotliDecoderErrorCode ProcessCommandsInternal(
1956
1983
  int safe, BrotliDecoderState* s) {
1957
1984
  int pos = s->pos;
@@ -1991,7 +2018,7 @@ CommandBegin:
1991
2018
  goto saveStateAndReturn;
1992
2019
  }
1993
2020
  if (BROTLI_PREDICT_FALSE(s->block_length[1] == 0)) {
1994
- BROTLI_SAFE(DecodeCommandBlockSwitch(s));
2021
+ BROTLI_SAFE_WITH_STATUS(DecodeCommandBlockSwitch(s));
1995
2022
  goto CommandBegin;
1996
2023
  }
1997
2024
  /* Read the insert/copy length in the command. */
@@ -2136,7 +2163,7 @@ CommandPostDecodeLiterals:
2136
2163
  } else {
2137
2164
  /* Read distance code in the command, unless it was implicitly zero. */
2138
2165
  if (BROTLI_PREDICT_FALSE(s->block_length[2] == 0)) {
2139
- BROTLI_SAFE(DecodeDistanceBlockSwitch(s));
2166
+ BROTLI_SAFE_WITH_STATUS(DecodeDistanceBlockSwitch(s));
2140
2167
  }
2141
2168
  BROTLI_SAFE(ReadDistance(s, br));
2142
2169
  }
@@ -2330,7 +2357,7 @@ CommandPostWrapCopy:
2330
2357
  }
2331
2358
 
2332
2359
  NextLiteralBlock:
2333
- BROTLI_SAFE(DecodeLiteralBlockSwitch(s));
2360
+ BROTLI_SAFE_WITH_STATUS(DecodeLiteralBlockSwitch(s));
2334
2361
  goto CommandInner;
2335
2362
 
2336
2363
  saveStateAndReturn:
@@ -2552,6 +2579,8 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
2552
2579
  if (result != BROTLI_DECODER_SUCCESS) {
2553
2580
  break;
2554
2581
  }
2582
+ BROTLI_DCHECK(s->meta_block_remaining_len <=
2583
+ (int)BROTLI_BLOCK_SIZE_CAP);
2555
2584
  BROTLI_LOG_UINT(s->is_last_metablock);
2556
2585
  BROTLI_LOG_UINT(s->meta_block_remaining_len);
2557
2586
  BROTLI_LOG_UINT(s->is_metadata);
@@ -85,9 +85,7 @@ typedef enum {
85
85
  BROTLI_ERROR_CODE(_ERROR_FORMAT_, PADDING_1, -14) SEPARATOR \
86
86
  BROTLI_ERROR_CODE(_ERROR_FORMAT_, PADDING_2, -15) SEPARATOR \
87
87
  BROTLI_ERROR_CODE(_ERROR_FORMAT_, DISTANCE, -16) SEPARATOR \
88
- \
89
- /* -17 code is reserved */ \
90
- \
88
+ BROTLI_ERROR_CODE(_ERROR_FORMAT_, BLOCK_SWITCH, -17) SEPARATOR \
91
89
  BROTLI_ERROR_CODE(_ERROR_, COMPOUND_DICTIONARY, -18) SEPARATOR \
92
90
  BROTLI_ERROR_CODE(_ERROR_, DICTIONARY_NOT_SET, -19) SEPARATOR \
93
91
  BROTLI_ERROR_CODE(_ERROR_, INVALID_ARGUMENTS, -20) SEPARATOR \
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brotli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.9.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - miyucy