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.
|
* The user callback function failed due to the temporal error.
|
||||||
*/
|
*/
|
||||||
SPDYLAY_ERR_TEMPORAL_CALLBACK_FAILURE = -521,
|
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
|
* The errors < :enum:`SPDYLAY_ERR_FATAL` mean that the library is
|
||||||
* under unexpected condition and cannot process any further data
|
* 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;
|
return framelen;
|
||||||
}
|
}
|
||||||
framelen += nv_offset;
|
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;
|
return framelen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,8 @@
|
||||||
#include "spdylay_client_cert_vector.h"
|
#include "spdylay_client_cert_vector.h"
|
||||||
|
|
||||||
#define SPDYLAY_STREAM_ID_MASK 0x7fffffff
|
#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_LENGTH_MASK 0xffffff
|
||||||
#define SPDYLAY_VERSION_MASK 0x7fff
|
#define SPDYLAY_VERSION_MASK 0x7fff
|
||||||
#define SPDYLAY_DELTA_WINDOW_SIZE_MASK 0x7fffffff
|
#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.
|
* The version is not supported.
|
||||||
* SPDYLAY_ERR_ZLIB
|
* SPDYLAY_ERR_ZLIB
|
||||||
* The deflate operation failed.
|
* The deflate operation failed.
|
||||||
|
* SPDYLAY_ERR_FRAME_TOO_LARGE
|
||||||
|
* The length of the frame is too large.
|
||||||
* SPDYLAY_ERR_NOMEM
|
* SPDYLAY_ERR_NOMEM
|
||||||
* Out of memory.
|
* Out of memory.
|
||||||
*/
|
*/
|
||||||
|
@ -201,6 +205,8 @@ int spdylay_frame_unpack_syn_stream_without_nv(spdylay_syn_stream *frame,
|
||||||
* The version is not supported.
|
* The version is not supported.
|
||||||
* SPDYLAY_ERR_ZLIB
|
* SPDYLAY_ERR_ZLIB
|
||||||
* The deflate operation failed.
|
* The deflate operation failed.
|
||||||
|
* SPDYLAY_ERR_FRAME_TOO_LARGE
|
||||||
|
* The length of the frame is too large.
|
||||||
* SPDYLAY_ERR_NOMEM
|
* SPDYLAY_ERR_NOMEM
|
||||||
* Out of memory.
|
* Out of memory.
|
||||||
*/
|
*/
|
||||||
|
@ -335,6 +341,8 @@ int spdylay_frame_unpack_goaway(spdylay_goaway *frame,
|
||||||
* The version is not supported.
|
* The version is not supported.
|
||||||
* SPDYLAY_ERR_ZLIB
|
* SPDYLAY_ERR_ZLIB
|
||||||
* The deflate operation failed.
|
* The deflate operation failed.
|
||||||
|
* SPDYLAY_ERR_FRAME_TOO_LARGE
|
||||||
|
* The length of the frame is too large.
|
||||||
* SPDYLAY_ERR_NOMEM
|
* SPDYLAY_ERR_NOMEM
|
||||||
* Out of memory.
|
* 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
|
* SPDYLAY_ERR_ZLIB
|
||||||
* The deflate operation failed.
|
* The deflate operation failed.
|
||||||
|
* SPDYLAY_ERR_FRAME_TOO_LARGE
|
||||||
|
* The length of the frame is too large.
|
||||||
* SPDYLAY_ERR_NOMEM
|
* SPDYLAY_ERR_NOMEM
|
||||||
* Out of memory.
|
* Out of memory.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -119,6 +119,8 @@ const char* spdylay_strerror(int error_code)
|
||||||
return "Gzip error";
|
return "Gzip error";
|
||||||
case SPDYLAY_ERR_TEMPORAL_CALLBACK_FAILURE:
|
case SPDYLAY_ERR_TEMPORAL_CALLBACK_FAILURE:
|
||||||
return "The user callback function failed due to the temporal error";
|
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:
|
case SPDYLAY_ERR_NOMEM:
|
||||||
return "Out of memory";
|
return "Out of memory";
|
||||||
case SPDYLAY_ERR_CALLBACK_FAILURE:
|
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],
|
/* Internal error code. They must be in the range [-499, -100],
|
||||||
inclusive. */
|
inclusive. */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SPDYLAY_ERR_CREDENTIAL_PENDING = -101,
|
SPDYLAY_ERR_CREDENTIAL_PENDING = -101
|
||||||
SPDYLAY_ERR_FRAME_TOO_LARGE = -102
|
|
||||||
} spdylay_internal_error;
|
} spdylay_internal_error;
|
||||||
|
|
||||||
#endif /* SPDYLAY_INT_H */
|
#endif /* SPDYLAY_INT_H */
|
||||||
|
|
|
@ -186,6 +186,8 @@ int main(int argc, char* argv[])
|
||||||
test_spdylay_frame_pack_syn_stream_spdy2) ||
|
test_spdylay_frame_pack_syn_stream_spdy2) ||
|
||||||
!CU_add_test(pSuite, "frame_pack_syn_stream_spdy3",
|
!CU_add_test(pSuite, "frame_pack_syn_stream_spdy3",
|
||||||
test_spdylay_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",
|
!CU_add_test(pSuite, "frame_pack_syn_reply_spdy2",
|
||||||
test_spdylay_frame_pack_syn_reply_spdy2) ||
|
test_spdylay_frame_pack_syn_reply_spdy2) ||
|
||||||
!CU_add_test(pSuite, "frame_pack_syn_reply_spdy3",
|
!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);
|
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)
|
static void test_spdylay_frame_pack_syn_reply_version(uint16_t version)
|
||||||
{
|
{
|
||||||
spdylay_zlib deflater, inflater;
|
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_goaway_spdy3(void);
|
||||||
void test_spdylay_frame_pack_syn_stream_spdy2(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_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_spdy2(void);
|
||||||
void test_spdylay_frame_pack_syn_reply_spdy3(void);
|
void test_spdylay_frame_pack_syn_reply_spdy3(void);
|
||||||
void test_spdylay_frame_pack_headers_spdy2(void);
|
void test_spdylay_frame_pack_headers_spdy2(void);
|
||||||
|
|
Loading…
Reference in New Issue