ngx_str_t value;
u_char *field_end;
+ size_t header_limit;
size_t field_length;
size_t field_rest;
u_char field_state;
if (ctx->type == NGX_HTTP_V2_HEADERS_FRAME) {
ctx->parsing_headers = 1;
ctx->fragment_state = 0;
+ ctx->header_limit = r->upstream->conf->buffer_size;
min = (ctx->flags & NGX_HTTP_V2_PADDED_FLAG ? 1 : 0)
+ (ctx->flags & NGX_HTTP_V2_PRIORITY_FLAG ? 5 : 0);
ngx_buf_t *b)
{
u_char ch, *p, *last;
- size_t size;
+ size_t len, size;
ngx_uint_t index, size_update;
enum {
sw_start = 0,
ctx->name.len = ctx->field_huffman ?
ctx->field_length * 8 / 5 : ctx->field_length;
+ if (ctx->name.len > ctx->header_limit) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "upstream sent too large http2 "
+ "header name length: %uz",
+ ctx->name.len);
+ return NGX_ERROR;
+ }
+
ctx->name.data = ngx_pnalloc(r->pool, ctx->name.len + 1);
if (ctx->name.data == NULL) {
return NGX_ERROR;
ctx->value.len = ctx->field_huffman ?
ctx->field_length * 8 / 5 : ctx->field_length;
+ if (ctx->value.len > ctx->header_limit) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "upstream sent too large http2 "
+ "header value length: %uz",
+ ctx->value.len);
+ return NGX_ERROR;
+ }
+
ctx->value.data = ngx_pnalloc(r->pool, ctx->value.len + 1);
if (ctx->value.data == NULL) {
return NGX_ERROR;
}
}
+ len = ctx->name.len + ctx->value.len;
+
+ if (len > ctx->header_limit) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "upstream sent too large http2 header");
+ return NGX_ERROR;
+ }
+
+ ctx->header_limit -= len;
+
return NGX_OK;
}
ngx_str_t value;
u_char *field_end;
+ size_t header_limit;
size_t field_length;
size_t field_rest;
u_char field_state;
if (ctx->type == NGX_HTTP_V2_HEADERS_FRAME) {
ctx->parsing_headers = 1;
ctx->fragment_state = 0;
+ ctx->header_limit = r->upstream->conf->buffer_size;
min = (ctx->flags & NGX_HTTP_V2_PADDED_FLAG ? 1 : 0)
+ (ctx->flags & NGX_HTTP_V2_PRIORITY_FLAG ? 5 : 0);
ngx_http_proxy_v2_ctx_t *ctx, ngx_buf_t *b)
{
u_char ch, *p, *last;
- size_t size;
+ size_t len, size;
ngx_uint_t index, size_update;
enum {
sw_start = 0,
ctx->name.len = ctx->field_huffman ?
ctx->field_length * 8 / 5 : ctx->field_length;
+ if (ctx->name.len > ctx->header_limit) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "upstream sent too large http2 "
+ "header name length: %uz",
+ ctx->name.len);
+ return NGX_ERROR;
+ }
+
ctx->name.data = ngx_pnalloc(r->pool, ctx->name.len + 1);
if (ctx->name.data == NULL) {
return NGX_ERROR;
ctx->value.len = ctx->field_huffman ?
ctx->field_length * 8 / 5 : ctx->field_length;
+ if (ctx->value.len > ctx->header_limit) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "upstream sent too large http2 "
+ "header value length: %uz",
+ ctx->value.len);
+ return NGX_ERROR;
+ }
+
ctx->value.data = ngx_pnalloc(r->pool, ctx->value.len + 1);
if (ctx->value.data == NULL) {
return NGX_ERROR;
}
}
+ len = ctx->name.len + ctx->value.len;
+
+ if (len > ctx->header_limit) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "upstream sent too large http2 header");
+ return NGX_ERROR;
+ }
+
+ ctx->header_limit -= len;
+
return NGX_OK;
}