diff --git a/doc/html/changelog.html b/doc/html/changelog.html
index 891c8e87..9595085f 100644
--- a/doc/html/changelog.html
+++ b/doc/html/changelog.html
@@ -120,6 +120,7 @@
libraries:
- libFLAC encoder was defaulting to level 0 compression instead of 5 (SF #1816825).
+ - Fix bug in bitreader handling of read callback returning a short count (SF #2490454).
diff --git a/src/libFLAC/bitreader.c b/src/libFLAC/bitreader.c
index 7bebdaa4..338125d1 100644
--- a/src/libFLAC/bitreader.c
+++ b/src/libFLAC/bitreader.c
@@ -758,7 +758,7 @@ FLAC__bool FLAC__bitreader_read_unary_unsigned(FLAC__BitReader *br, unsigned *va
* us data a byte at a time (unlikely), br->consumed_bits may not
* be zero.
*/
- if(br->bytes) {
+ if(br->bytes*8 > br->consumed_bits) {
const unsigned end = br->bytes * 8;
brword b = (br->buffer[br->consumed_words] & (FLAC__WORD_ALL_ONES << (FLAC__BITS_PER_WORD-end))) << br->consumed_bits;
if(b) {
@@ -771,7 +771,7 @@ FLAC__bool FLAC__bitreader_read_unary_unsigned(FLAC__BitReader *br, unsigned *va
}
else {
*val += end - br->consumed_bits;
- br->consumed_bits += end;
+ br->consumed_bits = end;
FLAC__ASSERT(br->consumed_bits < FLAC__BITS_PER_WORD);
/* didn't find stop bit yet, have to keep going... */
}
@@ -881,7 +881,7 @@ FLAC__bool FLAC__bitreader_read_rice_signed_block(FLAC__BitReader *br, int vals[
* us data a byte at a time (unlikely), br->consumed_bits may not
* be zero.
*/
- if(br->bytes) {
+ if(br->bytes*8 > cbits) {
const unsigned end = br->bytes * 8;
brword b = (br->buffer[cwords] & (FLAC__WORD_ALL_ONES << (FLAC__BITS_PER_WORD-end))) << cbits;
if(b) {
@@ -895,7 +895,7 @@ FLAC__bool FLAC__bitreader_read_rice_signed_block(FLAC__BitReader *br, int vals[
}
else {
uval += end - cbits;
- cbits += end;
+ cbits = end;
FLAC__ASSERT(cbits < FLAC__BITS_PER_WORD);
/* didn't find stop bit yet, have to keep going... */
}
@@ -1064,7 +1064,7 @@ break2:
* us data a byte at a time (unlikely), br->consumed_bits may not
* be zero.
*/
- if(br->bytes) {
+ if(br->bytes*8 > cbits) {
const unsigned end = br->bytes * 8;
brword b = (br->buffer[cwords] & ~(FLAC__WORD_ALL_ONES >> end)) << cbits;
if(b) {
@@ -1077,7 +1077,7 @@ break2:
}
else {
uval += end - cbits;
- cbits += end;
+ cbits = end;
FLAC__ASSERT(cbits < FLAC__BITS_PER_WORD);
/* didn't find stop bit yet, have to keep going... */
}
diff --git a/src/libFLAC/ia32/bitreader_asm.nasm b/src/libFLAC/ia32/bitreader_asm.nasm
index 4c65133e..ba2fc3cc 100644
--- a/src/libFLAC/ia32/bitreader_asm.nasm
+++ b/src/libFLAC/ia32/bitreader_asm.nasm
@@ -272,10 +272,11 @@ cident FLAC__bitreader_read_rice_signed_block_asm_ia32_bswap
;; edi uval
;; ebp br
mov edx, [ebp + 12] ; edx <- br->bytes
- test edx, edx
- jz .read1 ; if(br->bytes) { [NOTE: this case is rare so it doesn't have to be all that fast ]
+ shl edx, 3 ; edx <- br->bytes*8
+ cmp edx, ecx
+ jbe .read1 ; if(br->bytes*8 > cbits) { [NOTE: this case is rare so it doesn't have to be all that fast ]
mov ebx, [ebp]
- shl edx, 3 ; edx <- const unsigned end = br->bytes * 8;
+ ; edx <- const unsigned end = br->bytes * 8;
mov eax, [ebx + 4*esi] ; b = br->buffer[cwords]
xchg edx, ecx ; [edx <- cbits , ecx <- end]
mov ebx, 0xffffffff ; ebx <- FLAC__WORD_ALL_ONES
@@ -296,7 +297,7 @@ cident FLAC__bitreader_read_rice_signed_block_asm_ia32_bswap
.c1_next3: ; } else {
sub edi, ecx
add edi, edx ; uval += end - cbits;
- add ecx, edx ; cbits += end
+ mov ecx, edx ; cbits = end
; /* didn't find stop bit yet, have to keep going... */
; }
; }