diff options
author | Ronald S. Bultje <rsbultje@gmail.com> | 2020-06-23 04:10:55 +0300 |
---|---|---|
committer | Ronald S. Bultje <rsbultje@gmail.com> | 2020-06-23 04:10:55 +0300 |
commit | 47daa4df3387c1529536243db80b81f3878cbf76 (patch) | |
tree | b91ce7b6d7e48c9e7b3fca477f5978f2da10f1e5 /tools | |
parent | 54f92068caa25ccf75af52067786caf0415a17e0 (diff) |
Accumulate leb128 value using uint64_t as intermediate type
The shift-amount can be up to 56, and left-shifting 32-bit integers
by values >=32 is undefined behaviour. Therefore, use 64-bit integers
instead. Also slightly rewrite so we only call dav1d_get_bits() once
for the combined more|bits value, and mask the relevant portions
out instead of reading twice. Lastly, move the overflow check out of
the loop (as suggested by @wtc)
Fixes #341.
Diffstat (limited to 'tools')
-rw-r--r-- | tools/input/parse.h | 42 |
1 files changed, 21 insertions, 21 deletions
diff --git a/tools/input/parse.h b/tools/input/parse.h index b10e8b7..f5805e8 100644 --- a/tools/input/parse.h +++ b/tools/input/parse.h @@ -34,19 +34,19 @@ #include "dav1d/headers.h" static int leb128(FILE *const f, size_t *const len) { - unsigned i = 0, more, max = UINT_MAX; - *len = 0; + uint64_t val = 0; + unsigned i = 0, more; do { - uint8_t byte; - if (fread(&byte, 1, 1, f) < 1) + uint8_t v; + if (fread(&v, 1, 1, f) < 1) return -1; - more = byte & 0x80; - const unsigned bits = byte & 0x7f; - if (bits > max) return -1; - *len |= bits << (i * 7); - max >>= 7; - if (++i == 8 && more) return -1; - } while (more); + more = v & 0x80; + val |= ((uint64_t) (v & 0x7F)) << (i * 7); + i++; + } while (more && i < 8); + if (val > UINT_MAX || more) + return -1; + *len = (size_t) val; return i; } @@ -54,18 +54,18 @@ static int leb128(FILE *const f, size_t *const len) { // with author's permission static int leb(const uint8_t *ptr, int sz, size_t *const len) { - unsigned i = 0, more, max = UINT_MAX; - *len = 0; + uint64_t val = 0; + unsigned i = 0, more; do { if (!sz--) return -1; - const int byte = *ptr++; - more = byte & 0x80; - const unsigned bits = byte & 0x7f; - if (bits > max) return -1; - *len |= bits << (i * 7); - max >>= 7; - if (++i == 8 && more) return -1; - } while (more); + const int v = *ptr++; + more = v & 0x80; + val |= ((uint64_t) (v & 0x7F)) << (i * 7); + i++; + } while (more && i < 8); + if (val > UINT_MAX || more) + return -1; + *len = (size_t) val; return i; } |