Fixed spdylay_frame_count_nv_space() bug. Check all data is processed in spdylay_frame_count_unpack_nv_space()

This commit is contained in:
Tatsuhiro Tsujikawa 2012-02-18 17:25:13 +09:00
parent b1da54a549
commit 122c619260
3 changed files with 24 additions and 12 deletions

View File

@ -105,7 +105,7 @@ int spdylay_frame_count_unpack_nv_space
const size_t len_size = sizeof(uint16_t); const size_t len_size = sizeof(uint16_t);
int i; int i;
if(inlen < len_size) { if(inlen < len_size) {
return SPDYLAY_ERR_INVALID_ARGUMENT; return SPDYLAY_ERR_INVALID_FRAME;
} }
n = spdylay_get_uint16(in); n = spdylay_get_uint16(in);
off += len_size; off += len_size;
@ -114,26 +114,30 @@ int spdylay_frame_count_unpack_nv_space
int j; int j;
for(j = 0; j < 2; ++j) { for(j = 0; j < 2; ++j) {
if(inlen-off < len_size) { if(inlen-off < len_size) {
return SPDYLAY_ERR_INVALID_ARGUMENT; return SPDYLAY_ERR_INVALID_FRAME;
} }
len = spdylay_get_uint16(in+off); len = spdylay_get_uint16(in+off);
off += 2; off += 2;
if(inlen-off < len) { if(inlen-off < len) {
return SPDYLAY_ERR_INVALID_ARGUMENT; return SPDYLAY_ERR_INVALID_FRAME;
} }
buflen += len+1; buflen += len+1;
off += len; off += len;
} }
for(off -= len, j = off+len; off != j; ++off) { for(j = off, off -= len; off != j; ++off) {
if(in[off] == '\0') { if(in[off] == '\0') {
++nvlen; ++nvlen;
} }
} }
++nvlen; ++nvlen;
} }
if(inlen == off) {
*nvlen_ptr = nvlen; *nvlen_ptr = nvlen;
*buflen_ptr = buflen+(nvlen*2+1)*sizeof(char*); *buflen_ptr = buflen+(nvlen*2+1)*sizeof(char*);
return 0; return 0;
} else {
return SPDYLAY_ERR_INVALID_FRAME;
}
} }
int spdylay_frame_unpack_nv(char ***nv_ptr, const uint8_t *in, size_t inlen) int spdylay_frame_unpack_nv(char ***nv_ptr, const uint8_t *in, size_t inlen)
@ -231,6 +235,7 @@ size_t spdylay_frame_count_nv_space(char **nv)
sum += vallen+1; sum += vallen+1;
} else { } else {
prev = key; prev = key;
prevlen = keylen;
/* SPDY NV header does not include terminating NULL byte */ /* SPDY NV header does not include terminating NULL byte */
sum += keylen+vallen+4; sum += keylen+vallen+4;
} }

View File

@ -242,7 +242,8 @@ int spdylay_frame_unpack_settings(spdylay_settings *frame,
* Returns number of bytes to pack name/value pairs |nv|. This * Returns number of bytes to pack name/value pairs |nv|. This
* function expects |nv| is sorted in ascending order of key. This * function expects |nv| is sorted in ascending order of key. This
* function can handles duplicate keys and concatenation of thier * function can handles duplicate keys and concatenation of thier
* values with '\0'. * values with '\0'. This function returns 0 if it succeeds, or
* negative error code.
*/ */
size_t spdylay_frame_count_nv_space(char **nv); size_t spdylay_frame_count_nv_space(char **nv);

View File

@ -148,7 +148,7 @@ void test_spdylay_frame_pack_nv_duplicate_keys()
void test_spdylay_frame_count_nv_space() void test_spdylay_frame_count_nv_space()
{ {
CU_ASSERT(83 == spdylay_frame_count_nv_space((char**)headers)); CU_ASSERT(74 == spdylay_frame_count_nv_space((char**)headers));
} }
void test_spdylay_frame_count_unpack_nv_space() void test_spdylay_frame_count_unpack_nv_space()
@ -161,20 +161,26 @@ void test_spdylay_frame_count_unpack_nv_space()
out, inlen)); out, inlen));
CU_ASSERT(6 == nvlen); CU_ASSERT(6 == nvlen);
CU_ASSERT(166 == buflen); CU_ASSERT(166 == buflen);
/* Trailing garbage */
CU_ASSERT(SPDYLAY_ERR_INVALID_FRAME ==
spdylay_frame_count_unpack_nv_space(&nvlen, &buflen,
out, inlen+2));
/* Change number of nv pair to a bogus value */ /* Change number of nv pair to a bogus value */
temp = spdylay_get_uint16(out); temp = spdylay_get_uint16(out);
spdylay_put_uint16be(out, temp+1); spdylay_put_uint16be(out, temp+1);
CU_ASSERT(SPDYLAY_ERR_INVALID_ARGUMENT == CU_ASSERT(SPDYLAY_ERR_INVALID_FRAME ==
spdylay_frame_count_unpack_nv_space(&nvlen, &buflen, out, inlen)); spdylay_frame_count_unpack_nv_space(&nvlen, &buflen, out, inlen));
spdylay_put_uint16be(out, temp); spdylay_put_uint16be(out, temp);
/* Change the length of name to a bogus value */ /* Change the length of name to a bogus value */
temp = spdylay_get_uint16(out+2); temp = spdylay_get_uint16(out+2);
spdylay_put_uint16be(out+2, temp+1); spdylay_put_uint16be(out+2, temp+1);
CU_ASSERT(SPDYLAY_ERR_INVALID_ARGUMENT == CU_ASSERT(SPDYLAY_ERR_INVALID_FRAME ==
spdylay_frame_count_unpack_nv_space(&nvlen, &buflen, out, inlen)); spdylay_frame_count_unpack_nv_space(&nvlen, &buflen, out, inlen));
spdylay_put_uint16be(out+2, 65535); spdylay_put_uint16be(out+2, 65535);
CU_ASSERT(SPDYLAY_ERR_INVALID_ARGUMENT == CU_ASSERT(SPDYLAY_ERR_INVALID_FRAME ==
spdylay_frame_count_unpack_nv_space(&nvlen, &buflen, out, inlen)); spdylay_frame_count_unpack_nv_space(&nvlen, &buflen, out, inlen));
} }