It turns out that 0-bit prefix is wrong, and the author now
clearly stated that the intention is 8-bit prefix for 8+ fields.
This commit is contained in:
Tatsuhiro Tsujikawa 2013-10-18 19:27:15 +09:00
parent e85418f045
commit f7389ff2e6
1 changed files with 40 additions and 48 deletions

View File

@ -359,16 +359,14 @@ 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 len = 0;
if(prefix > 0) {
size_t k = (1 << prefix) - 1; size_t k = (1 << prefix) - 1;
size_t len = 0;
if(n >= k) { if(n >= k) {
n -= k; n -= k;
++len; ++len;
} else { } else {
return 1; return 1;
} }
}
do { do {
++len; ++len;
if(n >= 128) { if(n >= 128) {
@ -382,9 +380,8 @@ 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 len = 0;
if(prefix > 0) {
size_t k = (1 << prefix) - 1; size_t k = (1 << prefix) - 1;
size_t len = 0;
if(n >= k) { if(n >= k) {
*buf++ = k; *buf++ = k;
n -= k; n -= k;
@ -393,7 +390,6 @@ static size_t encode_length(uint8_t *buf, size_t n, int prefix)
*buf++ = n; *buf++ = n;
return 1; return 1;
} }
}
do { do {
++len; ++len;
if(n >= 128) { if(n >= 128) {
@ -425,7 +421,6 @@ static uint8_t* decode_length(ssize_t *res, uint8_t *in, uint8_t *last,
*res = -1; *res = -1;
return in; return in;
} }
if(prefix > 0) {
if((*in & k) == k) { if((*in & k) == k) {
*res = k; *res = k;
} else { } else {
@ -433,9 +428,6 @@ static uint8_t* decode_length(ssize_t *res, uint8_t *in, uint8_t *last,
return in + 1; return in + 1;
} }
++in; ++in;
} else {
*res = 0;
}
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)) {
@ -479,14 +471,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, 0) + valuelen; count_encoded_length(valuelen, 8) + 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, 0); bufp += encode_length(bufp, valuelen, 8);
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);
@ -500,18 +492,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, 0) + nv->namelen + size_t blocklen = 1 + count_encoded_length(nv->namelen, 8) + nv->namelen +
count_encoded_length(nv->valuelen, 0) + nv->valuelen; count_encoded_length(nv->valuelen, 8) + 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, 0); bufp += encode_length(bufp, nv->namelen, 8);
memcpy(bufp, nv->name, nv->namelen); memcpy(bufp, nv->name, nv->namelen);
bufp += nv->namelen; bufp += nv->namelen;
bufp += encode_length(bufp, nv->valuelen, 0); bufp += encode_length(bufp, nv->valuelen, 8);
memcpy(bufp, nv->value, nv->valuelen); memcpy(bufp, nv->value, nv->valuelen);
*offset_ptr += blocklen; *offset_ptr += blocklen;
return 0; return 0;
@ -525,16 +517,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, 0) + count_encoded_length(subindex, 8) +
count_encoded_length(valuelen, 0) + valuelen; count_encoded_length(valuelen, 8) + 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, 0); bufp += encode_length(bufp, subindex, 8);
bufp += encode_length(bufp, valuelen, 0); bufp += encode_length(bufp, valuelen, 8);
memcpy(bufp, value, valuelen); memcpy(bufp, value, valuelen);
*offset_ptr += blocklen; *offset_ptr += blocklen;
return 0; return 0;
@ -546,20 +538,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, 0) + nv->namelen + size_t blocklen = 1 + count_encoded_length(nv->namelen, 8) + nv->namelen +
count_encoded_length(subindex, 0) + count_encoded_length(subindex, 8) +
count_encoded_length(nv->valuelen, 0) + nv->valuelen; count_encoded_length(nv->valuelen, 8) + 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, 0); bufp += encode_length(bufp, nv->namelen, 8);
memcpy(bufp, nv->name, nv->namelen); memcpy(bufp, nv->name, nv->namelen);
bufp += nv->namelen; bufp += nv->namelen;
bufp += encode_length(bufp, subindex, 0); bufp += encode_length(bufp, subindex, 8);
bufp += encode_length(bufp, nv->valuelen, 0); bufp += encode_length(bufp, nv->valuelen, 8);
memcpy(bufp, nv->value, nv->valuelen); memcpy(bufp, nv->value, nv->valuelen);
*offset_ptr += blocklen; *offset_ptr += blocklen;
return 0; return 0;
@ -918,7 +910,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, 0); in = decode_length(&namelen, in, last, 8);
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;
@ -930,13 +922,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, 0); in = decode_length(&subindex, in, last, 8);
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, 0); in = decode_length(&valuelen, in, last, 8);
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;
@ -981,13 +973,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, 0); in = decode_length(&subindex, in, last, 8);
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, 0); in = decode_length(&valuelen, in , last, 8);
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;