Skip to content

Commit 67d2947

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 dd6b475 commit 67d2947

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
@@ -1124,7 +1124,7 @@ static BrotliDecoderErrorCode DecodeContextMap(brotli_reg_t context_map_size,
11241124

11251125
/* Decodes a command or literal and updates block type ring-buffer.
11261126
Reads 3..54 bits. */
1127-
static BROTLI_INLINE BROTLI_BOOL DecodeBlockTypeAndLength(
1127+
static BROTLI_INLINE BrotliDecoderErrorCode DecodeBlockTypeAndLength(
11281128
int safe, BrotliDecoderState* s, int tree_type) {
11291129
brotli_reg_t max_block_type = s->num_block_types[tree_type];
11301130
const HuffmanCode* type_tree = &s->block_type_trees[
@@ -1135,7 +1135,7 @@ static BROTLI_INLINE BROTLI_BOOL DecodeBlockTypeAndLength(
11351135
brotli_reg_t* ringbuffer = &s->block_type_rb[tree_type * 2];
11361136
brotli_reg_t block_type;
11371137
if (max_block_type <= 1) {
1138-
return BROTLI_FALSE;
1138+
return BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH;
11391139
}
11401140

11411141
/* Read 0..15 + 3..39 bits. */
@@ -1145,11 +1145,13 @@ static BROTLI_INLINE BROTLI_BOOL DecodeBlockTypeAndLength(
11451145
} else {
11461146
BrotliBitReaderState memento;
11471147
BrotliBitReaderSaveState(br, &memento);
1148-
if (!SafeReadSymbol(type_tree, br, &block_type)) return BROTLI_FALSE;
1148+
if (!SafeReadSymbol(type_tree, br, &block_type)) {
1149+
return BROTLI_DECODER_NEEDS_MORE_INPUT;
1150+
}
11491151
if (!SafeReadBlockLength(s, &s->block_length[tree_type], len_tree, br)) {
11501152
s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_NONE;
11511153
BrotliBitReaderRestoreState(br, &memento);
1152-
return BROTLI_FALSE;
1154+
return BROTLI_DECODER_NEEDS_MORE_INPUT;
11531155
}
11541156
}
11551157

@@ -1165,7 +1167,7 @@ static BROTLI_INLINE BROTLI_BOOL DecodeBlockTypeAndLength(
11651167
}
11661168
ringbuffer[0] = ringbuffer[1];
11671169
ringbuffer[1] = block_type;
1168-
return BROTLI_TRUE;
1170+
return BROTLI_DECODER_SUCCESS;
11691171
}
11701172

11711173
static BROTLI_INLINE void DetectTrivialLiteralBlockTypes(
@@ -1202,59 +1204,65 @@ static BROTLI_INLINE void PrepareLiteralDecoding(BrotliDecoderState* s) {
12021204

12031205
/* Decodes the block type and updates the state for literal context.
12041206
Reads 3..54 bits. */
1205-
static BROTLI_INLINE BROTLI_BOOL DecodeLiteralBlockSwitchInternal(
1207+
static BROTLI_INLINE BrotliDecoderErrorCode DecodeLiteralBlockSwitchInternal(
12061208
int safe, BrotliDecoderState* s) {
1207-
if (!DecodeBlockTypeAndLength(safe, s, 0)) {
1208-
return BROTLI_FALSE;
1209+
BrotliDecoderErrorCode result = DecodeBlockTypeAndLength(safe, s, 0);
1210+
if (result != BROTLI_DECODER_SUCCESS) {
1211+
return result;
12091212
}
12101213
PrepareLiteralDecoding(s);
1211-
return BROTLI_TRUE;
1214+
return BROTLI_DECODER_SUCCESS;
12121215
}
12131216

1214-
static void BROTLI_NOINLINE DecodeLiteralBlockSwitch(BrotliDecoderState* s) {
1215-
DecodeLiteralBlockSwitchInternal(0, s);
1217+
static BROTLI_NOINLINE BrotliDecoderErrorCode
1218+
DecodeLiteralBlockSwitch(BrotliDecoderState* s) {
1219+
return DecodeLiteralBlockSwitchInternal(0, s);
12161220
}
12171221

1218-
static BROTLI_BOOL BROTLI_NOINLINE SafeDecodeLiteralBlockSwitch(
1222+
static BROTLI_NOINLINE BrotliDecoderErrorCode SafeDecodeLiteralBlockSwitch(
12191223
BrotliDecoderState* s) {
12201224
return DecodeLiteralBlockSwitchInternal(1, s);
12211225
}
12221226

12231227
/* Block switch for insert/copy length.
12241228
Reads 3..54 bits. */
1225-
static BROTLI_INLINE BROTLI_BOOL DecodeCommandBlockSwitchInternal(
1229+
static BROTLI_INLINE BrotliDecoderErrorCode DecodeCommandBlockSwitchInternal(
12261230
int safe, BrotliDecoderState* s) {
1227-
if (!DecodeBlockTypeAndLength(safe, s, 1)) {
1228-
return BROTLI_FALSE;
1231+
BrotliDecoderErrorCode result = DecodeBlockTypeAndLength(safe, s, 1);
1232+
if (result != BROTLI_DECODER_SUCCESS) {
1233+
return result;
12291234
}
12301235
s->htree_command = s->insert_copy_hgroup.htrees[s->block_type_rb[3]];
1231-
return BROTLI_TRUE;
1236+
return BROTLI_DECODER_SUCCESS;
12321237
}
12331238

1234-
static void BROTLI_NOINLINE DecodeCommandBlockSwitch(BrotliDecoderState* s) {
1235-
DecodeCommandBlockSwitchInternal(0, s);
1239+
static BROTLI_NOINLINE BrotliDecoderErrorCode
1240+
DecodeCommandBlockSwitch(BrotliDecoderState* s) {
1241+
return DecodeCommandBlockSwitchInternal(0, s);
12361242
}
12371243

1238-
static BROTLI_BOOL BROTLI_NOINLINE SafeDecodeCommandBlockSwitch(
1239-
BrotliDecoderState* s) {
1244+
static BROTLI_NOINLINE BrotliDecoderErrorCode
1245+
SafeDecodeCommandBlockSwitch(BrotliDecoderState* s) {
12401246
return DecodeCommandBlockSwitchInternal(1, s);
12411247
}
12421248

12431249
/* Block switch for distance codes.
12441250
Reads 3..54 bits. */
1245-
static BROTLI_INLINE BROTLI_BOOL DecodeDistanceBlockSwitchInternal(
1251+
static BROTLI_INLINE BrotliDecoderErrorCode DecodeDistanceBlockSwitchInternal(
12461252
int safe, BrotliDecoderState* s) {
1247-
if (!DecodeBlockTypeAndLength(safe, s, 2)) {
1248-
return BROTLI_FALSE;
1253+
BrotliDecoderErrorCode result = DecodeBlockTypeAndLength(safe, s, 2);
1254+
if (result != BROTLI_DECODER_SUCCESS) {
1255+
return result;
12491256
}
12501257
s->dist_context_map_slice = s->dist_context_map +
12511258
(s->block_type_rb[5] << BROTLI_DISTANCE_CONTEXT_BITS);
12521259
s->dist_htree_index = s->dist_context_map_slice[s->distance_context];
1253-
return BROTLI_TRUE;
1260+
return BROTLI_DECODER_SUCCESS;
12541261
}
12551262

1256-
static void BROTLI_NOINLINE DecodeDistanceBlockSwitch(BrotliDecoderState* s) {
1257-
DecodeDistanceBlockSwitchInternal(0, s);
1263+
static BROTLI_NOINLINE BrotliDecoderErrorCode
1264+
DecodeDistanceBlockSwitch(BrotliDecoderState* s) {
1265+
return DecodeDistanceBlockSwitchInternal(0, s);
12581266
}
12591267

12601268
static BROTLI_BOOL BROTLI_NOINLINE SafeDecodeDistanceBlockSwitch(
@@ -1887,6 +1895,9 @@ static BROTLI_INLINE BROTLI_BOOL CheckInputAmount(
18871895
return BrotliCheckInputAmount(br);
18881896
}
18891897

1898+
/* NB: METHOD should return BROTLI_FALSE only in case there is not enough input;
1899+
in case of "unsafe" execution, when input is guaranteed to be sufficient,
1900+
result is ignored. */
18901901
#define BROTLI_SAFE(METHOD) \
18911902
{ \
18921903
if (safe) { \
@@ -1899,6 +1910,22 @@ static BROTLI_INLINE BROTLI_BOOL CheckInputAmount(
18991910
} \
19001911
}
19011912

1913+
/* NB: METHOD should return BROTLI_DECODER_SUCCESS, BROTLI_DECODER_ERROR_*, or
1914+
BROTLI_DECODER_NEEDS_MORE_INPUT; the later two break the processing. */
1915+
#define BROTLI_SAFE_WITH_STATUS(METHOD) \
1916+
{ \
1917+
BrotliDecoderErrorCode status; \
1918+
if (safe) { \
1919+
status = Safe##METHOD; \
1920+
} else { \
1921+
status = METHOD; \
1922+
} \
1923+
if (status != BROTLI_DECODER_SUCCESS) { \
1924+
result = status; \
1925+
goto saveStateAndReturn; \
1926+
} \
1927+
}
1928+
19021929
static BROTLI_INLINE BrotliDecoderErrorCode ProcessCommandsInternal(
19031930
int safe, BrotliDecoderState* s) {
19041931
int pos = s->pos;
@@ -1938,7 +1965,7 @@ static BROTLI_INLINE BrotliDecoderErrorCode ProcessCommandsInternal(
19381965
goto saveStateAndReturn;
19391966
}
19401967
if (BROTLI_PREDICT_FALSE(s->block_length[1] == 0)) {
1941-
BROTLI_SAFE(DecodeCommandBlockSwitch(s));
1968+
BROTLI_SAFE_WITH_STATUS(DecodeCommandBlockSwitch(s));
19421969
goto CommandBegin;
19431970
}
19441971
/* Read the insert/copy length in the command. */
@@ -2046,7 +2073,7 @@ static BROTLI_INLINE BrotliDecoderErrorCode ProcessCommandsInternal(
20462073
} else {
20472074
/* Read distance code in the command, unless it was implicitly zero. */
20482075
if (BROTLI_PREDICT_FALSE(s->block_length[2] == 0)) {
2049-
BROTLI_SAFE(DecodeDistanceBlockSwitch(s));
2076+
BROTLI_SAFE_WITH_STATUS(DecodeDistanceBlockSwitch(s));
20502077
}
20512078
BROTLI_SAFE(ReadDistance(s, br));
20522079
}
@@ -2240,7 +2267,7 @@ static BROTLI_INLINE BrotliDecoderErrorCode ProcessCommandsInternal(
22402267
}
22412268

22422269
NextLiteralBlock:
2243-
BROTLI_SAFE(DecodeLiteralBlockSwitch(s));
2270+
BROTLI_SAFE_WITH_STATUS(DecodeLiteralBlockSwitch(s));
22442271
goto CommandInner;
22452272

22462273
saveStateAndReturn:
@@ -2462,6 +2489,8 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
24622489
if (result != BROTLI_DECODER_SUCCESS) {
24632490
break;
24642491
}
2492+
BROTLI_DCHECK(s->meta_block_remaining_len <=
2493+
(int)BROTLI_BLOCK_SIZE_CAP);
24652494
BROTLI_LOG_UINT(s->is_last_metablock);
24662495
BROTLI_LOG_UINT(s->meta_block_remaining_len);
24672496
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)