Handle indexing entry greater than header table limit without error
This commit is contained in:
parent
4fe056d208
commit
83b0c89e3c
|
@ -340,10 +340,6 @@ static nghttp2_hd_entry* add_hd_table_incremental(nghttp2_hd_context *context,
|
||||||
size_t i;
|
size_t i;
|
||||||
nghttp2_hd_entry *new_ent;
|
nghttp2_hd_entry *new_ent;
|
||||||
size_t room = entry_room(nv->namelen, nv->valuelen);
|
size_t room = entry_room(nv->namelen, nv->valuelen);
|
||||||
if(context->hd_tablelen == context->hd_table_capacity ||
|
|
||||||
room > NGHTTP2_HD_MAX_BUFFER_SIZE) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
context->hd_table_bufsize += room;
|
context->hd_table_bufsize += room;
|
||||||
for(i = 0; i < context->hd_tablelen &&
|
for(i = 0; i < context->hd_tablelen &&
|
||||||
context->hd_table_bufsize > NGHTTP2_HD_MAX_BUFFER_SIZE; ++i) {
|
context->hd_table_bufsize > NGHTTP2_HD_MAX_BUFFER_SIZE; ++i) {
|
||||||
|
@ -383,8 +379,20 @@ static nghttp2_hd_entry* add_hd_table_incremental(nghttp2_hd_context *context,
|
||||||
if(rv != 0) {
|
if(rv != 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
context->hd_table[context->hd_tablelen++] = new_ent;
|
if(room > NGHTTP2_HD_MAX_BUFFER_SIZE) {
|
||||||
new_ent->flags |= NGHTTP2_HD_FLAG_REFSET;
|
/* The entry taking more than NGHTTP2_HD_MAX_BUFFER_SIZE is
|
||||||
|
immediately evicted. */
|
||||||
|
new_ent->index = NGHTTP2_HD_INVALID_INDEX;
|
||||||
|
--new_ent->ref;
|
||||||
|
} else {
|
||||||
|
/* Because of current NGHTTP2_HD_MAX_BUFFER_SIZE,
|
||||||
|
NGHTTP2_HD_ENTRY_OVERHEAD and NGHTTP2_INITIAL_HD_TABLE_SIZE,
|
||||||
|
context->hd_tablelen is strictly less than
|
||||||
|
context->hd_table_capacity. */
|
||||||
|
assert(context->hd_tablelen < context->hd_table_capacity);
|
||||||
|
context->hd_table[context->hd_tablelen++] = new_ent;
|
||||||
|
new_ent->flags |= NGHTTP2_HD_FLAG_REFSET;
|
||||||
|
}
|
||||||
return new_ent;
|
return new_ent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,8 +404,7 @@ static nghttp2_hd_entry* add_hd_table_subst(nghttp2_hd_context *context,
|
||||||
int k;
|
int k;
|
||||||
nghttp2_hd_entry *new_ent;
|
nghttp2_hd_entry *new_ent;
|
||||||
size_t room = entry_room(nv->namelen, nv->valuelen);
|
size_t room = entry_room(nv->namelen, nv->valuelen);
|
||||||
if(room > NGHTTP2_HD_MAX_BUFFER_SIZE ||
|
if(context->hd_tablelen <= subindex) {
|
||||||
context->hd_tablelen <= subindex) {
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
context->hd_table_bufsize -=
|
context->hd_table_bufsize -=
|
||||||
|
@ -429,6 +436,9 @@ static nghttp2_hd_entry* add_hd_table_subst(nghttp2_hd_context *context,
|
||||||
}
|
}
|
||||||
if(i > 0) {
|
if(i > 0) {
|
||||||
size_t j;
|
size_t j;
|
||||||
|
/* k < 0 means that the index to substitute originally was
|
||||||
|
evicted. Therefore, index 0 is the position to substitute
|
||||||
|
now. */
|
||||||
if(k < 0) {
|
if(k < 0) {
|
||||||
j = 1;
|
j = 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -470,8 +480,14 @@ static nghttp2_hd_entry* add_hd_table_subst(nghttp2_hd_context *context,
|
||||||
if(rv != 0) {
|
if(rv != 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
context->hd_table[new_ent->index] = new_ent;
|
if(room > NGHTTP2_HD_MAX_BUFFER_SIZE) {
|
||||||
new_ent->flags |= NGHTTP2_HD_FLAG_REFSET;
|
new_ent->index = NGHTTP2_HD_INVALID_INDEX;
|
||||||
|
--new_ent->ref;
|
||||||
|
context->hd_tablelen = 0;
|
||||||
|
} else {
|
||||||
|
context->hd_table[new_ent->index] = new_ent;
|
||||||
|
new_ent->flags |= NGHTTP2_HD_FLAG_REFSET;
|
||||||
|
}
|
||||||
return new_ent;
|
return new_ent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -238,6 +238,10 @@ int main(int argc, char* argv[])
|
||||||
test_nghttp2_hd_inflate_indname_subst_eviction_neg) ||
|
test_nghttp2_hd_inflate_indname_subst_eviction_neg) ||
|
||||||
!CU_add_test(pSuite, "hd_inflate_newname_subst",
|
!CU_add_test(pSuite, "hd_inflate_newname_subst",
|
||||||
test_nghttp2_hd_inflate_newname_subst) ||
|
test_nghttp2_hd_inflate_newname_subst) ||
|
||||||
|
!CU_add_test(pSuite, "hd_inflate_clearall_subst",
|
||||||
|
test_nghttp2_hd_inflate_clearall_subst) ||
|
||||||
|
!CU_add_test(pSuite, "hd_inflate_clearall_inc",
|
||||||
|
test_nghttp2_hd_inflate_clearall_inc) ||
|
||||||
!CU_add_test(pSuite, "hd_deflate_inflate",
|
!CU_add_test(pSuite, "hd_deflate_inflate",
|
||||||
test_nghttp2_hd_deflate_inflate) ||
|
test_nghttp2_hd_deflate_inflate) ||
|
||||||
!CU_add_test(pSuite, "gzip_inflate", test_nghttp2_gzip_inflate) ||
|
!CU_add_test(pSuite, "gzip_inflate", test_nghttp2_gzip_inflate) ||
|
||||||
|
|
|
@ -380,6 +380,90 @@ void test_nghttp2_hd_inflate_newname_subst(void)
|
||||||
nghttp2_hd_inflate_free(&inflater);
|
nghttp2_hd_inflate_free(&inflater);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_nghttp2_hd_inflate_clearall_inc(void)
|
||||||
|
{
|
||||||
|
nghttp2_hd_context inflater;
|
||||||
|
uint8_t *buf = NULL;
|
||||||
|
size_t buflen = 0;
|
||||||
|
size_t offset = 0;
|
||||||
|
nghttp2_nv nv;
|
||||||
|
nghttp2_nv *resnva;
|
||||||
|
uint8_t value[4060];
|
||||||
|
|
||||||
|
/* Total 4097 bytes space required to hold this entry */
|
||||||
|
nv.name = (uint8_t*)"alpha";
|
||||||
|
nv.namelen = strlen((char*)nv.name);
|
||||||
|
memset(value, '0', sizeof(value));
|
||||||
|
nv.value = value;
|
||||||
|
nv.valuelen = sizeof(value);
|
||||||
|
|
||||||
|
nghttp2_hd_inflate_init(&inflater, NGHTTP2_HD_SIDE_SERVER);
|
||||||
|
|
||||||
|
CU_ASSERT(0 == nghttp2_hd_emit_newname_block(&buf, &buflen, &offset,
|
||||||
|
&nv, 1));
|
||||||
|
CU_ASSERT(1 == nghttp2_hd_inflate_hd(&inflater, &resnva, buf, offset));
|
||||||
|
assert_nv_equal(&nv, resnva, 1);
|
||||||
|
CU_ASSERT(0 == inflater.hd_tablelen);
|
||||||
|
|
||||||
|
nghttp2_nv_array_del(resnva);
|
||||||
|
nghttp2_hd_end_headers(&inflater);
|
||||||
|
|
||||||
|
/* Do it again */
|
||||||
|
CU_ASSERT(1 == nghttp2_hd_inflate_hd(&inflater, &resnva, buf, offset));
|
||||||
|
assert_nv_equal(&nv, resnva, 1);
|
||||||
|
CU_ASSERT(0 == inflater.hd_tablelen);
|
||||||
|
|
||||||
|
nghttp2_nv_array_del(resnva);
|
||||||
|
nghttp2_hd_end_headers(&inflater);
|
||||||
|
|
||||||
|
/* This time, 4096 bytes space required, which is just fits in the
|
||||||
|
header table */
|
||||||
|
nv.valuelen = sizeof(value) - 1;
|
||||||
|
|
||||||
|
offset = 0;
|
||||||
|
CU_ASSERT(0 == nghttp2_hd_emit_newname_block(&buf, &buflen, &offset,
|
||||||
|
&nv, 1));
|
||||||
|
CU_ASSERT(1 == nghttp2_hd_inflate_hd(&inflater, &resnva, buf, offset));
|
||||||
|
assert_nv_equal(&nv, resnva, 1);
|
||||||
|
CU_ASSERT(1 == inflater.hd_tablelen);
|
||||||
|
|
||||||
|
nghttp2_nv_array_del(resnva);
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
nghttp2_hd_inflate_free(&inflater);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_nghttp2_hd_inflate_clearall_subst(void)
|
||||||
|
{
|
||||||
|
nghttp2_hd_context inflater;
|
||||||
|
uint8_t *buf = NULL;
|
||||||
|
size_t buflen = 0;
|
||||||
|
size_t offset = 0;
|
||||||
|
nghttp2_nv nv;
|
||||||
|
nghttp2_nv *resnva;
|
||||||
|
uint8_t value[4060];
|
||||||
|
|
||||||
|
/* Total 4097 bytes space required to hold this entry */
|
||||||
|
nv.name = (uint8_t*)"alpha";
|
||||||
|
nv.namelen = strlen((char*)nv.name);
|
||||||
|
memset(value, '0', sizeof(value));
|
||||||
|
nv.value = value;
|
||||||
|
nv.valuelen = sizeof(value);
|
||||||
|
|
||||||
|
nghttp2_hd_inflate_init(&inflater, NGHTTP2_HD_SIDE_SERVER);
|
||||||
|
|
||||||
|
CU_ASSERT(0 == nghttp2_hd_emit_subst_newname_block(&buf, &buflen, &offset,
|
||||||
|
&nv, 1));
|
||||||
|
CU_ASSERT(1 == nghttp2_hd_inflate_hd(&inflater, &resnva, buf, offset));
|
||||||
|
assert_nv_equal(&nv, resnva, 1);
|
||||||
|
CU_ASSERT(0 == inflater.hd_tablelen);
|
||||||
|
|
||||||
|
nghttp2_nv_array_del(resnva);
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
nghttp2_hd_inflate_free(&inflater);
|
||||||
|
}
|
||||||
|
|
||||||
static void check_deflate_inflate(nghttp2_hd_context *deflater,
|
static void check_deflate_inflate(nghttp2_hd_context *deflater,
|
||||||
nghttp2_hd_context *inflater,
|
nghttp2_hd_context *inflater,
|
||||||
nghttp2_nv *nva, size_t nvlen)
|
nghttp2_nv *nva, size_t nvlen)
|
||||||
|
|
|
@ -34,6 +34,8 @@ void test_nghttp2_hd_inflate_indname_subst(void);
|
||||||
void test_nghttp2_hd_inflate_indname_subst_eviction(void);
|
void test_nghttp2_hd_inflate_indname_subst_eviction(void);
|
||||||
void test_nghttp2_hd_inflate_indname_subst_eviction_neg(void);
|
void test_nghttp2_hd_inflate_indname_subst_eviction_neg(void);
|
||||||
void test_nghttp2_hd_inflate_newname_subst(void);
|
void test_nghttp2_hd_inflate_newname_subst(void);
|
||||||
|
void test_nghttp2_hd_inflate_clearall_inc(void);
|
||||||
|
void test_nghttp2_hd_inflate_clearall_subst(void);
|
||||||
void test_nghttp2_hd_deflate_inflate(void);
|
void test_nghttp2_hd_deflate_inflate(void);
|
||||||
|
|
||||||
#endif /* NGHTTP2_HD_TEST_H */
|
#endif /* NGHTTP2_HD_TEST_H */
|
||||||
|
|
Loading…
Reference in New Issue