Check that empty name and NULL value are not included in nv

This commit is contained in:
Tatsuhiro Tsujikawa 2012-08-21 23:19:15 +09:00
parent cdded94305
commit f8fcee122a
7 changed files with 104 additions and 2 deletions

View File

@ -1653,7 +1653,8 @@ const char* spdylay_strerror(int error_code);
* negative error codes: * negative error codes:
* *
* :enum:`SPDYLAY_ERR_INVALID_ARGUMENT` * :enum:`SPDYLAY_ERR_INVALID_ARGUMENT`
* The |pri| is invalid. * The |pri| is invalid; or the |nv| includes empty name or NULL
* value.
* :enum:`SPDYLAY_ERR_NOMEM` * :enum:`SPDYLAY_ERR_NOMEM`
* Out of memory. * Out of memory.
*/ */
@ -1697,6 +1698,8 @@ int spdylay_submit_request(spdylay_session *session, uint8_t pri,
* This function returns 0 if it succeeds, or one of the following * This function returns 0 if it succeeds, or one of the following
* negative error codes: * negative error codes:
* *
* :enum:`SPDYLAY_ERR_INVALID_ARGUMENT`
* The |nv| includes empty name or NULL value.
* :enum:`SPDYLAY_ERR_NOMEM` * :enum:`SPDYLAY_ERR_NOMEM`
* Out of memory. * Out of memory.
*/ */
@ -1744,7 +1747,7 @@ int spdylay_submit_response(spdylay_session *session,
* *
* :enum:`SPDYLAY_ERR_INVALID_ARGUMENT` * :enum:`SPDYLAY_ERR_INVALID_ARGUMENT`
* The |pri| is invalid; or the Associated-To-Stream-ID is * The |pri| is invalid; or the Associated-To-Stream-ID is
* invalid. * invalid; or the |nv| includes empty name or NULL value.
* :enum:`SPDYLAY_ERR_NOMEM` * :enum:`SPDYLAY_ERR_NOMEM`
* Out of memory. * Out of memory.
*/ */
@ -1778,6 +1781,8 @@ int spdylay_submit_syn_stream(spdylay_session *session, uint8_t flags,
* This function returns 0 if it succeeds, or one of the following * This function returns 0 if it succeeds, or one of the following
* negative error codes: * negative error codes:
* *
* :enum:`SPDYLAY_ERR_INVALID_ARGUMENT`
* The |nv| includes empty name or NULL value.
* :enum:`SPDYLAY_ERR_NOMEM` * :enum:`SPDYLAY_ERR_NOMEM`
* Out of memory. * Out of memory.
*/ */
@ -1810,6 +1815,8 @@ int spdylay_submit_syn_reply(spdylay_session *session, uint8_t flags,
* This function returns 0 if it succeeds, or one of the following * This function returns 0 if it succeeds, or one of the following
* negative error codes: * negative error codes:
* *
* :enum:`SPDYLAY_ERR_INVALID_ARGUMENT`
* The |nv| includes empty name or NULL value.
* :enum:`SPDYLAY_ERR_NOMEM` * :enum:`SPDYLAY_ERR_NOMEM`
* Out of memory. * Out of memory.
*/ */

View File

@ -1267,3 +1267,14 @@ ssize_t spdylay_frame_nv_offset(spdylay_frame_type type, uint16_t version)
} }
return -1; return -1;
} }
int spdylay_frame_nv_check_null(const char **nv)
{
size_t i;
for(i = 0; nv[i]; i += 2) {
if(nv[i][0] == '\0' || nv[i+1] == NULL) {
return 0;
}
}
return 1;
}

View File

@ -783,4 +783,11 @@ void spdylay_frame_iv_sort(spdylay_settings_entry *iv, size_t niv);
*/ */
ssize_t spdylay_frame_nv_offset(spdylay_frame_type type, uint16_t version); ssize_t spdylay_frame_nv_offset(spdylay_frame_type type, uint16_t version);
/*
* Checks names are not empty string and values are not NULL.
*
* This function returns nonzero if it succeeds, or 0.
*/
int spdylay_frame_nv_check_null(const char **nv);
#endif /* SPDYLAY_FRAME_H */ #endif /* SPDYLAY_FRAME_H */

View File

@ -55,6 +55,9 @@ static int spdylay_submit_syn_stream_shared
return SPDYLAY_ERR_INVALID_ARGUMENT; return SPDYLAY_ERR_INVALID_ARGUMENT;
} }
} }
if(!spdylay_frame_nv_check_null(nv)) {
return SPDYLAY_ERR_INVALID_ARGUMENT;
}
if(data_prd != NULL && data_prd->read_callback != NULL) { if(data_prd != NULL && data_prd->read_callback != NULL) {
data_prd_copy = malloc(sizeof(spdylay_data_provider)); data_prd_copy = malloc(sizeof(spdylay_data_provider));
if(data_prd_copy == NULL) { if(data_prd_copy == NULL) {
@ -119,6 +122,9 @@ int spdylay_submit_syn_reply(spdylay_session *session, uint8_t flags,
spdylay_frame *frame; spdylay_frame *frame;
char **nv_copy; char **nv_copy;
uint8_t flags_copy; uint8_t flags_copy;
if(!spdylay_frame_nv_check_null(nv)) {
return SPDYLAY_ERR_INVALID_ARGUMENT;
}
frame = malloc(sizeof(spdylay_frame)); frame = malloc(sizeof(spdylay_frame));
if(frame == NULL) { if(frame == NULL) {
return SPDYLAY_ERR_NOMEM; return SPDYLAY_ERR_NOMEM;
@ -149,6 +155,9 @@ int spdylay_submit_headers(spdylay_session *session, uint8_t flags,
spdylay_frame *frame; spdylay_frame *frame;
char **nv_copy; char **nv_copy;
uint8_t flags_copy; uint8_t flags_copy;
if(!spdylay_frame_nv_check_null(nv)) {
return SPDYLAY_ERR_INVALID_ARGUMENT;
}
frame = malloc(sizeof(spdylay_frame)); frame = malloc(sizeof(spdylay_frame));
if(frame == NULL) { if(frame == NULL) {
return SPDYLAY_ERR_NOMEM; return SPDYLAY_ERR_NOMEM;
@ -270,6 +279,9 @@ int spdylay_submit_response(spdylay_session *session,
char **nv_copy; char **nv_copy;
uint8_t flags = 0; uint8_t flags = 0;
spdylay_data_provider *data_prd_copy = NULL; spdylay_data_provider *data_prd_copy = NULL;
if(!spdylay_frame_nv_check_null(nv)) {
return SPDYLAY_ERR_INVALID_ARGUMENT;
}
if(data_prd != NULL && data_prd->read_callback != NULL) { if(data_prd != NULL && data_prd->read_callback != NULL) {
data_prd_copy = malloc(sizeof(spdylay_data_provider)); data_prd_copy = malloc(sizeof(spdylay_data_provider));
if(data_prd_copy == NULL) { if(data_prd_copy == NULL) {

View File

@ -100,6 +100,8 @@ int main(int argc, char* argv[])
test_spdylay_submit_syn_stream) || test_spdylay_submit_syn_stream) ||
!CU_add_test(pSuite, "submit_syn_reply", test_spdylay_submit_syn_reply) || !CU_add_test(pSuite, "submit_syn_reply", test_spdylay_submit_syn_reply) ||
!CU_add_test(pSuite, "submit_headers", test_spdylay_submit_headers) || !CU_add_test(pSuite, "submit_headers", test_spdylay_submit_headers) ||
!CU_add_test(pSuite, "submit_invalid_nv",
test_spdylay_submit_invalid_nv) ||
!CU_add_test(pSuite, "session_reply_fail", !CU_add_test(pSuite, "session_reply_fail",
test_spdylay_session_reply_fail) || test_spdylay_session_reply_fail) ||
!CU_add_test(pSuite, "session_on_headers_received", !CU_add_test(pSuite, "session_on_headers_received",

View File

@ -249,6 +249,14 @@ static spdylay_settings_entry* dup_iv(const spdylay_settings_entry *iv,
return spdylay_frame_iv_copy(iv, niv); return spdylay_frame_iv_copy(iv, niv);
} }
static const char *empty_name_nv[] = { "Version", "HTTP/1.1",
"", "empty name",
NULL };
static const char *null_val_nv[] = { "Version", "HTTP/1.1",
"Foo", NULL,
NULL };
void test_spdylay_session_recv(void) void test_spdylay_session_recv(void)
{ {
spdylay_session *session; spdylay_session *session;
@ -1065,6 +1073,60 @@ void test_spdylay_submit_headers(void)
spdylay_session_del(session); spdylay_session_del(session);
} }
void test_spdylay_submit_invalid_nv(void)
{
spdylay_session *session;
spdylay_session_callbacks callbacks;
memset(&callbacks, 0, sizeof(spdylay_session_callbacks));
CU_ASSERT(0 == spdylay_session_client_new(&session, SPDYLAY_PROTO_SPDY3,
&callbacks, NULL));
/* spdylay_submit_request */
CU_ASSERT(SPDYLAY_ERR_INVALID_ARGUMENT ==
spdylay_submit_request(session, 3, empty_name_nv, NULL, NULL));
CU_ASSERT(SPDYLAY_ERR_INVALID_ARGUMENT ==
spdylay_submit_request(session, 3, null_val_nv, NULL, NULL));
/* spdylay_submit_response */
CU_ASSERT(SPDYLAY_ERR_INVALID_ARGUMENT ==
spdylay_submit_response(session, 2, empty_name_nv, NULL));
CU_ASSERT(SPDYLAY_ERR_INVALID_ARGUMENT ==
spdylay_submit_response(session, 2, null_val_nv, NULL));
/* spdylay_submit_syn_stream */
CU_ASSERT(SPDYLAY_ERR_INVALID_ARGUMENT ==
spdylay_submit_syn_stream(session, SPDYLAY_CTRL_FLAG_NONE, 0,
0, empty_name_nv, NULL));
CU_ASSERT(SPDYLAY_ERR_INVALID_ARGUMENT ==
spdylay_submit_syn_stream(session, SPDYLAY_CTRL_FLAG_NONE, 0,
0, null_val_nv, NULL));
/* spdylay_submit_syn_reply */
CU_ASSERT(SPDYLAY_ERR_INVALID_ARGUMENT ==
spdylay_submit_syn_reply(session, SPDYLAY_CTRL_FLAG_NONE, 2,
empty_name_nv));
CU_ASSERT(SPDYLAY_ERR_INVALID_ARGUMENT ==
spdylay_submit_syn_reply(session, SPDYLAY_CTRL_FLAG_NONE, 2,
null_val_nv));
/* spdylay_submit_headers */
CU_ASSERT(SPDYLAY_ERR_INVALID_ARGUMENT ==
spdylay_submit_headers(session, SPDYLAY_CTRL_FLAG_NONE, 2,
empty_name_nv));
CU_ASSERT(SPDYLAY_ERR_INVALID_ARGUMENT ==
spdylay_submit_headers(session, SPDYLAY_CTRL_FLAG_NONE, 2,
null_val_nv));
spdylay_session_del(session);
}
void test_spdylay_session_reply_fail(void) void test_spdylay_session_reply_fail(void)
{ {
spdylay_session *session; spdylay_session *session;

View File

@ -41,6 +41,7 @@ void test_spdylay_submit_request_with_null_data_read_callback(void);
void test_spdylay_submit_syn_stream(void); void test_spdylay_submit_syn_stream(void);
void test_spdylay_submit_syn_reply(void); void test_spdylay_submit_syn_reply(void);
void test_spdylay_submit_headers(void); void test_spdylay_submit_headers(void);
void test_spdylay_submit_invalid_nv(void);
void test_spdylay_session_reply_fail(void); void test_spdylay_session_reply_fail(void);
void test_spdylay_session_on_headers_received(void); void test_spdylay_session_on_headers_received(void);
void test_spdylay_session_on_ping_received(void); void test_spdylay_session_on_ping_received(void);