int xbzrle_decode_buffer(uint8_t *src, int slen, uint8_t *dst, int dlen) { int i = 0, d = 0; int ret; uint32_t count = 0; while (i < slen) { /* zrun */ if ((slen - i) < 2) { return -1; } ret = uleb128_decode_small(src + i, &count); if (ret < 0 || (i && !count)) { return -1; } i += ret; d += count; /* overflow */ if (d > dlen) { return -1; } /* nzrun */ if ((slen - i) < 2) { return -1; } ret = uleb128_decode_small(src + i, &count); if (ret < 0 || !count) { return -1; } i += ret; /* overflow */ if (d + count > dlen || i + count > slen) { return -1; } memcpy(dst + d, src + i, count); d += count; i += count; } return d; }
static void test_uleb(void) { uint32_t i, val; uint8_t buf[2]; int encode_ret, decode_ret; for (i = 0; i <= 0x3fff; i++) { encode_ret = uleb128_encode_small(&buf[0], i); decode_ret = uleb128_decode_small(&buf[0], &val); g_assert(encode_ret == decode_ret); g_assert(i == val); } /* decode invalid value */ buf[0] = 0x80; buf[1] = 0x80; decode_ret = uleb128_decode_small(&buf[0], &val); g_assert(decode_ret == -1); g_assert(val == 0); }