Skip to content

Commit

Permalink
Fix #502 decoder bug
Browse files Browse the repository at this point in the history
Decoder may have produced invalid output if:
 * at offset 0..3 dictionary word with index 3..0 for some length N is used
   and distance is encoded with direct distance code 0, and
 * at least one of next 4 commands use value from distance ringbuffer
  • Loading branch information
eustas committed Feb 7, 2017
1 parent 11df843 commit 8e27fd7
Showing 1 changed file with 6 additions and 0 deletions.
6 changes: 6 additions & 0 deletions dec/decode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1391,6 +1391,8 @@ static BROTLI_INLINE void TakeDistanceFromRingBuffer(BrotliDecoderState* s) {
if (s->distance_code == 0) {
--s->dist_rb_idx;
s->distance_code = s->dist_rb[s->dist_rb_idx & 3];
/* Compensate double distance-ring-buffer roll for dictionary items. */
s->distance_context = 1;
} else {
int distance_code = s->distance_code << 1;
/* kDistanceShortCodeIndexOffset has 2-bit values from LSB: */
Expand Down Expand Up @@ -1712,6 +1714,8 @@ static BROTLI_INLINE BrotliDecoderErrorCode ProcessCommandsInternal(
if (BROTLI_PREDICT_FALSE(s->block_length[2] == 0)) {
BROTLI_SAFE(DecodeDistanceBlockSwitch(s));
}
/* Reuse distance_context variable. */
s->distance_context = 0;
BROTLI_SAFE(ReadDistance(s, br));
postReadDistance:
BROTLI_LOG(("[ProcessCommandsInternal] pos = %d distance = %d\n",
Expand All @@ -1732,6 +1736,8 @@ static BROTLI_INLINE BrotliDecoderErrorCode ProcessCommandsInternal(
int mask = (int)BitMask(shift);
int word_idx = word_id & mask;
int transform_idx = word_id >> shift;
/* Compensate double distance-ring-buffer roll. */
s->dist_rb_idx += s->distance_context;
offset += word_idx * i;
if (transform_idx < kNumTransforms) {
const uint8_t* word = &kBrotliDictionary[offset];
Expand Down

0 comments on commit 8e27fd7

Please sign in to comment.