summaryrefslogtreecommitdiff
path: root/openjpeg/src/lib/openjp2/bio.c
diff options
context:
space:
mode:
Diffstat (limited to 'openjpeg/src/lib/openjp2/bio.c')
-rw-r--r--openjpeg/src/lib/openjp2/bio.c39
1 files changed, 24 insertions, 15 deletions
diff --git a/openjpeg/src/lib/openjp2/bio.c b/openjpeg/src/lib/openjp2/bio.c
index 5d4958017..269769b45 100644
--- a/openjpeg/src/lib/openjp2/bio.c
+++ b/openjpeg/src/lib/openjp2/bio.c
@@ -78,27 +78,27 @@ static OPJ_BOOL opj_bio_bytein(opj_bio_t *bio);
==========================================================
*/
-OPJ_BOOL opj_bio_byteout(opj_bio_t *bio) {
+static OPJ_BOOL opj_bio_byteout(opj_bio_t *bio) {
bio->buf = (bio->buf << 8) & 0xffff;
bio->ct = bio->buf == 0xff00 ? 7 : 8;
- if (bio->bp >= bio->end) {
+ if ((OPJ_SIZE_T)bio->bp >= (OPJ_SIZE_T)bio->end) {
return OPJ_FALSE;
}
*bio->bp++ = (OPJ_BYTE)(bio->buf >> 8);
return OPJ_TRUE;
}
-OPJ_BOOL opj_bio_bytein(opj_bio_t *bio) {
+static OPJ_BOOL opj_bio_bytein(opj_bio_t *bio) {
bio->buf = (bio->buf << 8) & 0xffff;
bio->ct = bio->buf == 0xff00 ? 7 : 8;
- if (bio->bp >= bio->end) {
+ if ((OPJ_SIZE_T)bio->bp >= (OPJ_SIZE_T)bio->end) {
return OPJ_FALSE;
}
bio->buf |= *bio->bp++;
return OPJ_TRUE;
}
-void opj_bio_putbit(opj_bio_t *bio, OPJ_UINT32 b) {
+static void opj_bio_putbit(opj_bio_t *bio, OPJ_UINT32 b) {
if (bio->ct == 0) {
opj_bio_byteout(bio); /* MSD: why not check the return value of this function ? */
}
@@ -106,7 +106,7 @@ void opj_bio_putbit(opj_bio_t *bio, OPJ_UINT32 b) {
bio->buf |= b << bio->ct;
}
-OPJ_UINT32 opj_bio_getbit(opj_bio_t *bio) {
+static OPJ_UINT32 opj_bio_getbit(opj_bio_t *bio) {
if (bio->ct == 0) {
opj_bio_bytein(bio); /* MSD: why not check the return value of this function ? */
}
@@ -151,30 +151,40 @@ void opj_bio_init_dec(opj_bio_t *bio, OPJ_BYTE *bp, OPJ_UINT32 len) {
bio->ct = 0;
}
+OPJ_NOSANITIZE("unsigned-integer-overflow")
void opj_bio_write(opj_bio_t *bio, OPJ_UINT32 v, OPJ_UINT32 n) {
OPJ_UINT32 i;
- for (i = n - 1; i < n; i--) {
+
+ assert((n > 0U) && (n <= 32U));
+ for (i = n - 1; i < n; i--) { /* overflow used for end-loop condition */
opj_bio_putbit(bio, (v >> i) & 1);
}
}
+OPJ_NOSANITIZE("unsigned-integer-overflow")
OPJ_UINT32 opj_bio_read(opj_bio_t *bio, OPJ_UINT32 n) {
OPJ_UINT32 i;
- OPJ_UINT32 v;
- v = 0;
- for (i = n - 1; i < n; i--) {
- v += opj_bio_getbit(bio) << i;
+ OPJ_UINT32 v;
+
+ assert((n > 0U) /* && (n <= 32U)*/);
+#ifdef OPJ_UBSAN_BUILD
+ /* This assert fails for some corrupted images which are gracefully rejected */
+ /* Add this assert only for ubsan build. */
+ /* This is the condition for overflow not to occur below which is needed because of OPJ_NOSANITIZE */
+ assert(n <= 32U);
+#endif
+ v = 0U;
+ for (i = n - 1; i < n; i--) { /* overflow used for end-loop condition */
+ v |= opj_bio_getbit(bio) << i; /* can't overflow, opj_bio_getbit returns 0 or 1 */
}
return v;
}
OPJ_BOOL opj_bio_flush(opj_bio_t *bio) {
- bio->ct = 0;
if (! opj_bio_byteout(bio)) {
return OPJ_FALSE;
}
if (bio->ct == 7) {
- bio->ct = 0;
if (! opj_bio_byteout(bio)) {
return OPJ_FALSE;
}
@@ -183,12 +193,11 @@ OPJ_BOOL opj_bio_flush(opj_bio_t *bio) {
}
OPJ_BOOL opj_bio_inalign(opj_bio_t *bio) {
- bio->ct = 0;
if ((bio->buf & 0xff) == 0xff) {
if (! opj_bio_bytein(bio)) {
return OPJ_FALSE;
}
- bio->ct = 0;
}
+ bio->ct = 0;
return OPJ_TRUE;
}