static inline bool resize_mul(uint8_t **buf, size_t *size, size_t nsize, size_t mul) { size_t nsz; if (unlikely(chck_mul_ofsz(nsize, mul, &nsz))) return false; return resize(buf, size, nsz); }
bool chck_buffer_decompress_zlib(struct chck_buffer *buf) { #if HAS_ZLIB size_t dsize, bsize; { size_t sz; if (unlikely(chck_mul_ofsz(buf->size, 2, &sz))) return false; dsize = bsize = sz; } void *decompressed; if (!(decompressed = malloc(dsize))) return false; int ret; while ((ret = uncompress(decompressed, &dsize, buf->buffer, buf->size)) == Z_BUF_ERROR) { void *tmp; if (!(tmp = chck_realloc_mul_of(decompressed, bsize, 2))) goto fail; decompressed = tmp; dsize = (bsize *= 2); } if (unlikely(ret != Z_OK)) goto fail; chck_buffer_set_pointer(buf, decompressed, bsize, buf->endianess); buf->copied = true; if (bsize > dsize) chck_buffer_resize(buf, dsize); return true; fail: free(decompressed); return false; #else (void)buf; assert(0 && "not compiled with zlib support"); return false; #endif }
size_t chck_buffer_read(void *dst, size_t size, size_t memb, struct chck_buffer *buf) { assert(dst && buf); size_t nsz; if (unlikely(chck_mul_ofsz(size, memb, &nsz))) return 0; if (unlikely(nsz > buf->size - (buf->curpos - buf->buffer))) { assert(size != 0); // should never happen // read as much as we can memb = (buf->size - (buf->curpos - buf->buffer)) / size; } memcpy(dst, buf->curpos, size * memb); buf->curpos += size * memb; return memb; }
static bool bounds_check(struct chck_buffer *buf, size_t size, size_t memb) { size_t nsz; if (unlikely(chck_mul_ofsz(size, memb, &nsz))) return false; size_t sz = buf->size - (buf->curpos - buf->buffer); if (nsz > sz) { /* buf->size + size * memb + buf->step */ if (unlikely(chck_add_ofsz(buf->size, nsz, &nsz)) || unlikely(chck_add_ofsz(buf->step, nsz, &nsz))) return false; if (!chck_buffer_resize(buf, nsz)) return false; } return true; }