Skip to content

Commit 49dff6f

Browse files
eustasaduh95
authored andcommitted
deps: brotli: cherry-pick 0ed4268a4401abcb44720963
Original commit message: Detect and report invalid stream earlier. PiperOrigin-RevId: 876198329 PR-URL: nodejs-private/node-private#1002 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> CVE-ID: CVE-2026-111497
1 parent 4d6990b commit 49dff6f

2 files changed

Lines changed: 59 additions & 32 deletions

File tree

‎deps/brotli/c/dec/decode.c‎

Lines changed: 58 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,7 +1176,7 @@ static BrotliDecoderErrorCode DecodeContextMap(brotli_reg_t context_map_size,
11761176

11771177
/* Decodes a command or literal and updates block type ring-buffer.
11781178
Reads 3..54 bits. */
1179-
static BROTLI_INLINE BROTLI_BOOL DecodeBlockTypeAndLength(
1179+
static BROTLI_INLINE BrotliDecoderErrorCode DecodeBlockTypeAndLength(
11801180
int safe, BrotliDecoderState* s, int tree_type) {
11811181
brotli_reg_t max_block_type = s->num_block_types[tree_type];
11821182
const HuffmanCode* type_tree = &s->block_type_trees[
@@ -1187,7 +1187,7 @@ static BROTLI_INLINE BROTLI_BOOL DecodeBlockTypeAndLength(
11871187
brotli_reg_t* ringbuffer = &s->block_type_rb[tree_type * 2];
11881188
brotli_reg_t block_type;
11891189
if (max_block_type <= 1) {
1190-
return BROTLI_FALSE;
1190+
return BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH;
11911191
}
11921192

11931193
/* Read 0..15 + 3..39 bits. */
@@ -1197,11 +1197,13 @@ static BROTLI_INLINE BROTLI_BOOL DecodeBlockTypeAndLength(
11971197
} else {
11981198
BrotliBitReaderState memento;
11991199
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+
}
12011203
if (!SafeReadBlockLength(s, &s->block_length[tree_type], len_tree, br)) {
12021204
s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_NONE;
12031205
BrotliBitReaderRestoreState(br, &memento);
1204-
return BROTLI_FALSE;
1206+
return BROTLI_DECODER_NEEDS_MORE_INPUT;
12051207
}
12061208
}
12071209

@@ -1217,7 +1219,7 @@ static BROTLI_INLINE BROTLI_BOOL DecodeBlockTypeAndLength(
12171219
}
12181220
ringbuffer[0] = ringbuffer[1];
12191221
ringbuffer[1] = block_type;
1220-
return BROTLI_TRUE;
1222+
return BROTLI_DECODER_SUCCESS;
12211223
}
12221224

12231225
static BROTLI_INLINE void DetectTrivialLiteralBlockTypes(
@@ -1254,59 +1256,65 @@ static BROTLI_INLINE void PrepareLiteralDecoding(BrotliDecoderState* s) {
12541256

12551257
/* Decodes the block type and updates the state for literal context.
12561258
Reads 3..54 bits. */
1257-
static BROTLI_INLINE BROTLI_BOOL DecodeLiteralBlockSwitchInternal(
1259+
static BROTLI_INLINE BrotliDecoderErrorCode DecodeLiteralBlockSwitchInternal(
12581260
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;
12611264
}
12621265
PrepareLiteralDecoding(s);
1263-
return BROTLI_TRUE;
1266+
return BROTLI_DECODER_SUCCESS;
12641267
}
12651268

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);
12681272
}
12691273

1270-
static BROTLI_BOOL BROTLI_NOINLINE SafeDecodeLiteralBlockSwitch(
1274+
static BROTLI_NOINLINE BrotliDecoderErrorCode SafeDecodeLiteralBlockSwitch(
12711275
BrotliDecoderState* s) {
12721276
return DecodeLiteralBlockSwitchInternal(1, s);
12731277
}
12741278

12751279
/* Block switch for insert/copy length.
12761280
Reads 3..54 bits. */
1277-
static BROTLI_INLINE BROTLI_BOOL DecodeCommandBlockSwitchInternal(
1281+
static BROTLI_INLINE BrotliDecoderErrorCode DecodeCommandBlockSwitchInternal(
12781282
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;
12811286
}
12821287
s->htree_command = s->insert_copy_hgroup.htrees[s->block_type_rb[3]];
1283-
return BROTLI_TRUE;
1288+
return BROTLI_DECODER_SUCCESS;
12841289
}
12851290

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);
12881294
}
12891295

1290-
static BROTLI_BOOL BROTLI_NOINLINE SafeDecodeCommandBlockSwitch(
1291-
BrotliDecoderState* s) {
1296+
static BROTLI_NOINLINE BrotliDecoderErrorCode
1297+
SafeDecodeCommandBlockSwitch(BrotliDecoderState* s) {
12921298
return DecodeCommandBlockSwitchInternal(1, s);
12931299
}
12941300

12951301
/* Block switch for distance codes.
12961302
Reads 3..54 bits. */
1297-
static BROTLI_INLINE BROTLI_BOOL DecodeDistanceBlockSwitchInternal(
1303+
static BROTLI_INLINE BrotliDecoderErrorCode DecodeDistanceBlockSwitchInternal(
12981304
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;
13011308
}
13021309
s->dist_context_map_slice = s->dist_context_map +
13031310
(s->block_type_rb[5] << BROTLI_DISTANCE_CONTEXT_BITS);
13041311
s->dist_htree_index = s->dist_context_map_slice[s->distance_context];
1305-
return BROTLI_TRUE;
1312+
return BROTLI_DECODER_SUCCESS;
13061313
}
13071314

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);
13101318
}
13111319

13121320
static BROTLI_BOOL BROTLI_NOINLINE SafeDecodeDistanceBlockSwitch(
@@ -1940,6 +1948,9 @@ static BROTLI_INLINE BROTLI_BOOL CheckInputAmount(
19401948
return BrotliCheckInputAmount(br);
19411949
}
19421950

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. */
19431954
#define BROTLI_SAFE(METHOD) \
19441955
{ \
19451956
if (safe) { \
@@ -1952,6 +1963,22 @@ static BROTLI_INLINE BROTLI_BOOL CheckInputAmount(
19521963
} \
19531964
}
19541965

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+
19551982
static BROTLI_INLINE BrotliDecoderErrorCode ProcessCommandsInternal(
19561983
int safe, BrotliDecoderState* s) {
19571984
int pos = s->pos;
@@ -1991,7 +2018,7 @@ static BROTLI_INLINE BrotliDecoderErrorCode ProcessCommandsInternal(
19912018
goto saveStateAndReturn;
19922019
}
19932020
if (BROTLI_PREDICT_FALSE(s->block_length[1] == 0)) {
1994-
BROTLI_SAFE(DecodeCommandBlockSwitch(s));
2021+
BROTLI_SAFE_WITH_STATUS(DecodeCommandBlockSwitch(s));
19952022
goto CommandBegin;
19962023
}
19972024
/* Read the insert/copy length in the command. */
@@ -2136,7 +2163,7 @@ static BROTLI_INLINE BrotliDecoderErrorCode ProcessCommandsInternal(
21362163
} else {
21372164
/* Read distance code in the command, unless it was implicitly zero. */
21382165
if (BROTLI_PREDICT_FALSE(s->block_length[2] == 0)) {
2139-
BROTLI_SAFE(DecodeDistanceBlockSwitch(s));
2166+
BROTLI_SAFE_WITH_STATUS(DecodeDistanceBlockSwitch(s));
21402167
}
21412168
BROTLI_SAFE(ReadDistance(s, br));
21422169
}
@@ -2330,7 +2357,7 @@ static BROTLI_INLINE BrotliDecoderErrorCode ProcessCommandsInternal(
23302357
}
23312358

23322359
NextLiteralBlock:
2333-
BROTLI_SAFE(DecodeLiteralBlockSwitch(s));
2360+
BROTLI_SAFE_WITH_STATUS(DecodeLiteralBlockSwitch(s));
23342361
goto CommandInner;
23352362

23362363
saveStateAndReturn:
@@ -2552,6 +2579,8 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
25522579
if (result != BROTLI_DECODER_SUCCESS) {
25532580
break;
25542581
}
2582+
BROTLI_DCHECK(s->meta_block_remaining_len <=
2583+
(int)BROTLI_BLOCK_SIZE_CAP);
25552584
BROTLI_LOG_UINT(s->is_last_metablock);
25562585
BROTLI_LOG_UINT(s->meta_block_remaining_len);
25572586
BROTLI_LOG_UINT(s->is_metadata);

‎deps/brotli/c/include/brotli/decode.h‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,7 @@ typedef enum {
8585
BROTLI_ERROR_CODE(_ERROR_FORMAT_, PADDING_1, -14) SEPARATOR \
8686
BROTLI_ERROR_CODE(_ERROR_FORMAT_, PADDING_2, -15) SEPARATOR \
8787
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 \
9189
BROTLI_ERROR_CODE(_ERROR_, COMPOUND_DICTIONARY, -18) SEPARATOR \
9290
BROTLI_ERROR_CODE(_ERROR_, DICTIONARY_NOT_SET, -19) SEPARATOR \
9391
BROTLI_ERROR_CODE(_ERROR_, INVALID_ARGUMENTS, -20) SEPARATOR \

0 commit comments

Comments
 (0)