lib: make capn_inflate() work with unaligned data

init_fp itself tries to read 4 bytes for the segment count.
This commit is contained in:
David Lamparter 2016-06-27 14:33:16 +02:00
parent 5d787b698e
commit 3059f4dd5c
2 changed files with 28 additions and 10 deletions

View file

@ -109,14 +109,28 @@ int capn_deflate(struct capn_stream* s) {
} }
int capn_inflate(struct capn_stream* s) { int capn_inflate(struct capn_stream* s) {
if (s->avail_out % 8) {
return CAPN_MISALIGNED;
}
while (s->avail_out) { while (s->avail_out) {
int i; int i;
size_t sz; size_t sz;
uint8_t hdr; uint8_t hdr;
uint8_t *wr;
if (s->avail_buf && s->avail_out >= s->avail_buf) {
memcpy(s->next_out, s->inflate_buf, s->avail_buf);
s->next_out += s->avail_buf;
s->avail_out -= s->avail_buf;
s->avail_buf = 0;
if (!s->avail_out)
return 0;
}
if (s->avail_buf && s->avail_out < s->avail_buf) {
memcpy(s->next_out, s->inflate_buf, s->avail_out);
memmove(s->inflate_buf, s->inflate_buf + s->avail_out,
s->avail_buf - s->avail_out);
s->avail_buf -= s->avail_out;
s->avail_out = 0;
return 0;
}
if (s->zeros > 0) { if (s->zeros > 0) {
sz = min(s->avail_out, s->zeros); sz = min(s->avail_out, s->zeros);
@ -153,12 +167,12 @@ int capn_inflate(struct capn_stream* s) {
if (s->avail_in < 10) if (s->avail_in < 10)
return CAPN_NEED_MORE; return CAPN_NEED_MORE;
memcpy(s->next_out, s->next_in+1, 8); memcpy(s->inflate_buf, s->next_in+1, 8);
s->avail_buf = 8;
s->raw = s->next_in[9] * 8; s->raw = s->next_in[9] * 8;
s->next_in += 10; s->next_in += 10;
s->avail_in -= 10; s->avail_in -= 10;
s->next_out += 8;
s->avail_out -= 8;
continue; continue;
case 0x00: case 0x00:
@ -182,15 +196,16 @@ int capn_inflate(struct capn_stream* s) {
s->next_in += 1; s->next_in += 1;
wr = s->inflate_buf;
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
if (hdr & (1 << i)) { if (hdr & (1 << i)) {
*(s->next_out++) = *(s->next_in++); *wr++ = *s->next_in++;
} else { } else {
*(s->next_out++) = 0; *wr++ = 0;
} }
} }
s->avail_out -= 8; s->avail_buf = 8;
s->avail_in -= 1 + sz; s->avail_in -= 1 + sz;
continue; continue;
} }

View file

@ -287,6 +287,9 @@ struct capn_stream {
uint8_t *next_out; uint8_t *next_out;
size_t avail_out; size_t avail_out;
unsigned zeros, raw; unsigned zeros, raw;
uint8_t inflate_buf[8];
size_t avail_buf;
}; };
#define CAPN_MISALIGNED -1 #define CAPN_MISALIGNED -1