Fix HPACK using 0-bit prefix instead of 8-bits
This commit is contained in:
parent
2e7edf88bc
commit
622b05aa31
|
@ -359,13 +359,15 @@ static int ensure_write_buffer(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||||
|
|
||||||
static size_t count_encoded_length(size_t n, int prefix)
|
static size_t count_encoded_length(size_t n, int prefix)
|
||||||
{
|
{
|
||||||
size_t k = (1 << prefix) - 1;
|
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
if(n >= k) {
|
if(prefix > 0) {
|
||||||
n -= k;
|
size_t k = (1 << prefix) - 1;
|
||||||
++len;
|
if(n >= k) {
|
||||||
} else {
|
n -= k;
|
||||||
return 1;
|
++len;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
++len;
|
++len;
|
||||||
|
@ -380,15 +382,17 @@ static size_t count_encoded_length(size_t n, int prefix)
|
||||||
|
|
||||||
static size_t encode_length(uint8_t *buf, size_t n, int prefix)
|
static size_t encode_length(uint8_t *buf, size_t n, int prefix)
|
||||||
{
|
{
|
||||||
size_t k = (1 << prefix) - 1;
|
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
if(n >= k) {
|
if(prefix > 0) {
|
||||||
*buf++ = k;
|
size_t k = (1 << prefix) - 1;
|
||||||
n -= k;
|
if(n >= k) {
|
||||||
++len;
|
*buf++ = k;
|
||||||
} else {
|
n -= k;
|
||||||
*buf++ = n;
|
++len;
|
||||||
return 1;
|
} else {
|
||||||
|
*buf++ = n;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
++len;
|
++len;
|
||||||
|
@ -421,13 +425,17 @@ static uint8_t* decode_length(ssize_t *res, uint8_t *in, uint8_t *last,
|
||||||
*res = -1;
|
*res = -1;
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
if((*in & k) == k) {
|
if(prefix > 0) {
|
||||||
*res = k;
|
if((*in & k) == k) {
|
||||||
|
*res = k;
|
||||||
|
} else {
|
||||||
|
*res = (*in) & k;
|
||||||
|
return in + 1;
|
||||||
|
}
|
||||||
|
++in;
|
||||||
} else {
|
} else {
|
||||||
*res = (*in) & k;
|
*res = 0;
|
||||||
return in + 1;
|
|
||||||
}
|
}
|
||||||
++in;
|
|
||||||
for(r = 0; in != last; ++in, r += 7) {
|
for(r = 0; in != last; ++in, r += 7) {
|
||||||
*res += (*in & 0x7f) << r;
|
*res += (*in & 0x7f) << r;
|
||||||
if(*res >= (1 << 16)) {
|
if(*res >= (1 << 16)) {
|
||||||
|
@ -471,14 +479,14 @@ static int emit_indname_block(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||||
int rv;
|
int rv;
|
||||||
uint8_t *bufp;
|
uint8_t *bufp;
|
||||||
size_t blocklen = count_encoded_length(index + 1, 5) +
|
size_t blocklen = count_encoded_length(index + 1, 5) +
|
||||||
count_encoded_length(valuelen, 8) + valuelen;
|
count_encoded_length(valuelen, 0) + valuelen;
|
||||||
rv = ensure_write_buffer(buf_ptr, buflen_ptr, *offset_ptr, blocklen);
|
rv = ensure_write_buffer(buf_ptr, buflen_ptr, *offset_ptr, blocklen);
|
||||||
if(rv != 0) {
|
if(rv != 0) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
bufp = *buf_ptr + *offset_ptr;
|
bufp = *buf_ptr + *offset_ptr;
|
||||||
bufp += encode_length(bufp, index + 1, 5);
|
bufp += encode_length(bufp, index + 1, 5);
|
||||||
bufp += encode_length(bufp, valuelen, 8);
|
bufp += encode_length(bufp, valuelen, 0);
|
||||||
memcpy(bufp, value, valuelen);
|
memcpy(bufp, value, valuelen);
|
||||||
(*buf_ptr)[*offset_ptr] |= inc_indexing ? 0x40u : 0x60u;
|
(*buf_ptr)[*offset_ptr] |= inc_indexing ? 0x40u : 0x60u;
|
||||||
assert(bufp+valuelen - (*buf_ptr + *offset_ptr) == (ssize_t)blocklen);
|
assert(bufp+valuelen - (*buf_ptr + *offset_ptr) == (ssize_t)blocklen);
|
||||||
|
@ -492,18 +500,18 @@ static int emit_newname_block(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
uint8_t *bufp;
|
uint8_t *bufp;
|
||||||
size_t blocklen = 1 + count_encoded_length(nv->namelen, 8) + nv->namelen +
|
size_t blocklen = 1 + count_encoded_length(nv->namelen, 0) + nv->namelen +
|
||||||
count_encoded_length(nv->valuelen, 8) + nv->valuelen;
|
count_encoded_length(nv->valuelen, 0) + nv->valuelen;
|
||||||
rv = ensure_write_buffer(buf_ptr, buflen_ptr, *offset_ptr, blocklen);
|
rv = ensure_write_buffer(buf_ptr, buflen_ptr, *offset_ptr, blocklen);
|
||||||
if(rv != 0) {
|
if(rv != 0) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
bufp = *buf_ptr + *offset_ptr;
|
bufp = *buf_ptr + *offset_ptr;
|
||||||
*bufp++ = inc_indexing ? 0x40u : 0x60u;
|
*bufp++ = inc_indexing ? 0x40u : 0x60u;
|
||||||
bufp += encode_length(bufp, nv->namelen, 8);
|
bufp += encode_length(bufp, nv->namelen, 0);
|
||||||
memcpy(bufp, nv->name, nv->namelen);
|
memcpy(bufp, nv->name, nv->namelen);
|
||||||
bufp += nv->namelen;
|
bufp += nv->namelen;
|
||||||
bufp += encode_length(bufp, nv->valuelen, 8);
|
bufp += encode_length(bufp, nv->valuelen, 0);
|
||||||
memcpy(bufp, nv->value, nv->valuelen);
|
memcpy(bufp, nv->value, nv->valuelen);
|
||||||
*offset_ptr += blocklen;
|
*offset_ptr += blocklen;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -517,16 +525,16 @@ static int emit_subst_indname_block(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||||
int rv;
|
int rv;
|
||||||
uint8_t *bufp;
|
uint8_t *bufp;
|
||||||
size_t blocklen = count_encoded_length(index + 1, 6) +
|
size_t blocklen = count_encoded_length(index + 1, 6) +
|
||||||
count_encoded_length(subindex, 8) +
|
count_encoded_length(subindex, 0) +
|
||||||
count_encoded_length(valuelen, 8) + valuelen;
|
count_encoded_length(valuelen, 0) + valuelen;
|
||||||
rv = ensure_write_buffer(buf_ptr, buflen_ptr, *offset_ptr, blocklen);
|
rv = ensure_write_buffer(buf_ptr, buflen_ptr, *offset_ptr, blocklen);
|
||||||
if(rv != 0) {
|
if(rv != 0) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
bufp = *buf_ptr + *offset_ptr;
|
bufp = *buf_ptr + *offset_ptr;
|
||||||
bufp += encode_length(bufp, index + 1, 6);
|
bufp += encode_length(bufp, index + 1, 6);
|
||||||
bufp += encode_length(bufp, subindex, 8);
|
bufp += encode_length(bufp, subindex, 0);
|
||||||
bufp += encode_length(bufp, valuelen, 8);
|
bufp += encode_length(bufp, valuelen, 0);
|
||||||
memcpy(bufp, value, valuelen);
|
memcpy(bufp, value, valuelen);
|
||||||
*offset_ptr += blocklen;
|
*offset_ptr += blocklen;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -538,20 +546,20 @@ static int emit_subst_newname_block(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
uint8_t *bufp;
|
uint8_t *bufp;
|
||||||
size_t blocklen = 1 + count_encoded_length(nv->namelen, 8) + nv->namelen +
|
size_t blocklen = 1 + count_encoded_length(nv->namelen, 0) + nv->namelen +
|
||||||
count_encoded_length(subindex, 8) +
|
count_encoded_length(subindex, 0) +
|
||||||
count_encoded_length(nv->valuelen, 8) + nv->valuelen;
|
count_encoded_length(nv->valuelen, 0) + nv->valuelen;
|
||||||
rv = ensure_write_buffer(buf_ptr, buflen_ptr, *offset_ptr, blocklen);
|
rv = ensure_write_buffer(buf_ptr, buflen_ptr, *offset_ptr, blocklen);
|
||||||
if(rv != 0) {
|
if(rv != 0) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
bufp = *buf_ptr + *offset_ptr;
|
bufp = *buf_ptr + *offset_ptr;
|
||||||
*bufp++ = 0;
|
*bufp++ = 0;
|
||||||
bufp += encode_length(bufp, nv->namelen, 8);
|
bufp += encode_length(bufp, nv->namelen, 0);
|
||||||
memcpy(bufp, nv->name, nv->namelen);
|
memcpy(bufp, nv->name, nv->namelen);
|
||||||
bufp += nv->namelen;
|
bufp += nv->namelen;
|
||||||
bufp += encode_length(bufp, subindex, 8);
|
bufp += encode_length(bufp, subindex, 0);
|
||||||
bufp += encode_length(bufp, nv->valuelen, 8);
|
bufp += encode_length(bufp, nv->valuelen, 0);
|
||||||
memcpy(bufp, nv->value, nv->valuelen);
|
memcpy(bufp, nv->value, nv->valuelen);
|
||||||
*offset_ptr += blocklen;
|
*offset_ptr += blocklen;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -910,7 +918,7 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_context *inflater,
|
||||||
rv = NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
in = decode_length(&namelen, in, last, 8);
|
in = decode_length(&namelen, in, last, 0);
|
||||||
if(namelen < 0 || in + namelen > last) {
|
if(namelen < 0 || in + namelen > last) {
|
||||||
rv = NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -922,13 +930,13 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_context *inflater,
|
||||||
nv.name = in;
|
nv.name = in;
|
||||||
in += namelen;
|
in += namelen;
|
||||||
if(c == 0) {
|
if(c == 0) {
|
||||||
in = decode_length(&subindex, in, last, 8);
|
in = decode_length(&subindex, in, last, 0);
|
||||||
if(subindex < 0) {
|
if(subindex < 0) {
|
||||||
rv = NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
in = decode_length(&valuelen, in, last, 8);
|
in = decode_length(&valuelen, in, last, 0);
|
||||||
if(valuelen < 0 || in + valuelen > last) {
|
if(valuelen < 0 || in + valuelen > last) {
|
||||||
rv = NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -973,13 +981,13 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_context *inflater,
|
||||||
}
|
}
|
||||||
ent = inflater->hd_table[index];
|
ent = inflater->hd_table[index];
|
||||||
if((c & 0x40u) == 0) {
|
if((c & 0x40u) == 0) {
|
||||||
in = decode_length(&subindex, in, last, 8);
|
in = decode_length(&subindex, in, last, 0);
|
||||||
if(subindex < 0) {
|
if(subindex < 0) {
|
||||||
rv = NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
in = decode_length(&valuelen, in , last, 8);
|
in = decode_length(&valuelen, in , last, 0);
|
||||||
if(valuelen < 0 || in + valuelen > last) {
|
if(valuelen < 0 || in + valuelen > last) {
|
||||||
rv = NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
Loading…
Reference in New Issue