Check frame length after packing a frame
If resultant length of a frame exceeds the maximum value (which is 2**24 - 1 for SPDY/2 and 3), SPDYLAY_ERR_FRAME_TOO_LARGE is used to indicate this error. This error will be notified by on_ctrl_not_send_callback.
This commit is contained in:
parent
744f35e7ea
commit
088e4f15a2
|
@ -167,6 +167,10 @@ typedef enum {
|
|||
* The user callback function failed due to the temporal error.
|
||||
*/
|
||||
SPDYLAY_ERR_TEMPORAL_CALLBACK_FAILURE = -521,
|
||||
/**
|
||||
* The length of the frame is too large.
|
||||
*/
|
||||
SPDYLAY_ERR_FRAME_TOO_LARGE = -522,
|
||||
/**
|
||||
* The errors < :enum:`SPDYLAY_ERR_FATAL` mean that the library is
|
||||
* under unexpected condition and cannot process any further data
|
||||
|
|
|
@ -107,6 +107,11 @@ ssize_t spdylay_frame_alloc_pack_nv(uint8_t **buf_ptr,
|
|||
return framelen;
|
||||
}
|
||||
framelen += nv_offset;
|
||||
|
||||
if(framelen - SPDYLAY_FRAME_HEAD_LENGTH > SPDYLAY_LENGTH_MASK) {
|
||||
/* In SPDY/2 and 3, Max frame size is 2**24 - 1. */
|
||||
return SPDYLAY_ERR_FRAME_TOO_LARGE;
|
||||
}
|
||||
return framelen;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
#include "spdylay_client_cert_vector.h"
|
||||
|
||||
#define SPDYLAY_STREAM_ID_MASK 0x7fffffff
|
||||
/* This is actually the maximum length of a control frame in SPDY/2
|
||||
and 3. */
|
||||
#define SPDYLAY_LENGTH_MASK 0xffffff
|
||||
#define SPDYLAY_VERSION_MASK 0x7fff
|
||||
#define SPDYLAY_DELTA_WINDOW_SIZE_MASK 0x7fffffff
|
||||
|
@ -124,6 +126,8 @@ size_t spdylay_frame_get_len_size(uint16_t version);
|
|||
* The version is not supported.
|
||||
* SPDYLAY_ERR_ZLIB
|
||||
* The deflate operation failed.
|
||||
* SPDYLAY_ERR_FRAME_TOO_LARGE
|
||||
* The length of the frame is too large.
|
||||
* SPDYLAY_ERR_NOMEM
|
||||
* Out of memory.
|
||||
*/
|
||||
|
@ -201,6 +205,8 @@ int spdylay_frame_unpack_syn_stream_without_nv(spdylay_syn_stream *frame,
|
|||
* The version is not supported.
|
||||
* SPDYLAY_ERR_ZLIB
|
||||
* The deflate operation failed.
|
||||
* SPDYLAY_ERR_FRAME_TOO_LARGE
|
||||
* The length of the frame is too large.
|
||||
* SPDYLAY_ERR_NOMEM
|
||||
* Out of memory.
|
||||
*/
|
||||
|
@ -335,6 +341,8 @@ int spdylay_frame_unpack_goaway(spdylay_goaway *frame,
|
|||
* The version is not supported.
|
||||
* SPDYLAY_ERR_ZLIB
|
||||
* The deflate operation failed.
|
||||
* SPDYLAY_ERR_FRAME_TOO_LARGE
|
||||
* The length of the frame is too large.
|
||||
* SPDYLAY_ERR_NOMEM
|
||||
* Out of memory.
|
||||
*/
|
||||
|
@ -539,6 +547,8 @@ ssize_t spdylay_frame_pack_nv(uint8_t *buf, char **nv, size_t len_size);
|
|||
*
|
||||
* SPDYLAY_ERR_ZLIB
|
||||
* The deflate operation failed.
|
||||
* SPDYLAY_ERR_FRAME_TOO_LARGE
|
||||
* The length of the frame is too large.
|
||||
* SPDYLAY_ERR_NOMEM
|
||||
* Out of memory.
|
||||
*/
|
||||
|
|
|
@ -119,6 +119,8 @@ const char* spdylay_strerror(int error_code)
|
|||
return "Gzip error";
|
||||
case SPDYLAY_ERR_TEMPORAL_CALLBACK_FAILURE:
|
||||
return "The user callback function failed due to the temporal error";
|
||||
case SPDYLAY_ERR_FRAME_TOO_LARGE:
|
||||
return "The length of the frame is too large";
|
||||
case SPDYLAY_ERR_NOMEM:
|
||||
return "Out of memory";
|
||||
case SPDYLAY_ERR_CALLBACK_FAILURE:
|
||||
|
|
|
@ -38,8 +38,7 @@ typedef int (*spdylay_compar)(const void *lhs, const void *rhs);
|
|||
/* Internal error code. They must be in the range [-499, -100],
|
||||
inclusive. */
|
||||
typedef enum {
|
||||
SPDYLAY_ERR_CREDENTIAL_PENDING = -101,
|
||||
SPDYLAY_ERR_FRAME_TOO_LARGE = -102
|
||||
SPDYLAY_ERR_CREDENTIAL_PENDING = -101
|
||||
} spdylay_internal_error;
|
||||
|
||||
#endif /* SPDYLAY_INT_H */
|
||||
|
|
|
@ -186,6 +186,8 @@ int main(int argc, char* argv[])
|
|||
test_spdylay_frame_pack_syn_stream_spdy2) ||
|
||||
!CU_add_test(pSuite, "frame_pack_syn_stream_spdy3",
|
||||
test_spdylay_frame_pack_syn_stream_spdy3) ||
|
||||
!CU_add_test(pSuite, "frame_pack_syn_stream_frame_too_large",
|
||||
test_spdylay_frame_pack_syn_stream_frame_too_large) ||
|
||||
!CU_add_test(pSuite, "frame_pack_syn_reply_spdy2",
|
||||
test_spdylay_frame_pack_syn_reply_spdy2) ||
|
||||
!CU_add_test(pSuite, "frame_pack_syn_reply_spdy3",
|
||||
|
|
|
@ -346,6 +346,35 @@ void test_spdylay_frame_pack_syn_stream_spdy3(void)
|
|||
test_spdylay_frame_pack_syn_stream_version(SPDYLAY_PROTO_SPDY3);
|
||||
}
|
||||
|
||||
void test_spdylay_frame_pack_syn_stream_frame_too_large(void)
|
||||
{
|
||||
spdylay_zlib deflater;
|
||||
spdylay_frame frame;
|
||||
uint8_t *buf = NULL, *nvbuf = NULL;
|
||||
size_t buflen = 0, nvbuflen = 0;
|
||||
ssize_t framelen;
|
||||
size_t big_vallen = 16777215;
|
||||
char *big_val = malloc(big_vallen + 1);
|
||||
const char *big_hds[] = { "header", big_val, NULL };
|
||||
memset(big_val, '0', big_vallen);
|
||||
big_val[big_vallen] = '\0';
|
||||
|
||||
spdylay_zlib_deflate_hd_init(&deflater, SPDYLAY_PROTO_SPDY3);
|
||||
spdylay_frame_syn_stream_init(&frame.syn_stream, SPDYLAY_PROTO_SPDY3,
|
||||
SPDYLAY_CTRL_FLAG_FIN, 65536, 1000000007, 3,
|
||||
spdylay_frame_nv_copy(big_hds));
|
||||
framelen = spdylay_frame_pack_syn_stream(&buf, &buflen,
|
||||
&nvbuf, &nvbuflen,
|
||||
&frame.syn_stream, &deflater);
|
||||
CU_ASSERT_EQUAL(SPDYLAY_ERR_FRAME_TOO_LARGE, framelen);
|
||||
|
||||
spdylay_frame_syn_stream_free(&frame.syn_stream);
|
||||
free(buf);
|
||||
free(nvbuf);
|
||||
free(big_val);
|
||||
spdylay_zlib_deflate_free(&deflater);
|
||||
}
|
||||
|
||||
static void test_spdylay_frame_pack_syn_reply_version(uint16_t version)
|
||||
{
|
||||
spdylay_zlib deflater, inflater;
|
||||
|
|
|
@ -35,6 +35,7 @@ void test_spdylay_frame_pack_goaway_spdy2(void);
|
|||
void test_spdylay_frame_pack_goaway_spdy3(void);
|
||||
void test_spdylay_frame_pack_syn_stream_spdy2(void);
|
||||
void test_spdylay_frame_pack_syn_stream_spdy3(void);
|
||||
void test_spdylay_frame_pack_syn_stream_frame_too_large(void);
|
||||
void test_spdylay_frame_pack_syn_reply_spdy2(void);
|
||||
void test_spdylay_frame_pack_syn_reply_spdy3(void);
|
||||
void test_spdylay_frame_pack_headers_spdy2(void);
|
||||
|
|
Loading…
Reference in New Issue