diff --git a/plugin/protocol/http2/include/internal/http2_common.h b/plugin/protocol/http2/include/internal/http2_common.h index 5aba7df..79ed3de 100644 --- a/plugin/protocol/http2/include/internal/http2_common.h +++ b/plugin/protocol/http2/include/internal/http2_common.h @@ -52,7 +52,7 @@ str_to_val(const char *val, const struct value_string *vs); const char* http2_header_val_to_str(unsigned int val, const char * map[], unsigned int map_size); int -http2_header_str_to_val(const char *str, const char * map[], unsigned int map_size); +http2_header_str_to_val(const char *str, size_t slen, const char * map[], unsigned int map_size); #define BV(x) (1 << x) #define HTTP2_CONTENT_ENCODING_NONE 0 diff --git a/plugin/protocol/http2/src/http2_common.cpp b/plugin/protocol/http2/src/http2_common.cpp index f4b7007..b8b2a2c 100644 --- a/plugin/protocol/http2/src/http2_common.cpp +++ b/plugin/protocol/http2/src/http2_common.cpp @@ -36,11 +36,13 @@ Http2Plugin *http2_plugin() } int -http2_header_str_to_val(const char *str, const char * map[], unsigned int map_size) +http2_header_str_to_val(const char *str, size_t slen, const char * map[], unsigned int map_size) { + size_t normlen = 0; for (unsigned int i = 2; i < map_size; i++) { - if ( (strlen(str) == strlen(map[i])) && !strncasecmp(str, map[i], strlen(map[i]))) + normlen = strlen(map[i]); + if ( (slen == normlen) && !strncasecmp(str, map[i], normlen)) { return i; } @@ -48,7 +50,8 @@ http2_header_str_to_val(const char *str, const char * map[], unsigned int map_si // in http [TFE_HTTP_UNKNOWN_FIELD] = NULL; [TFE_HTTP_HOST] = "Host", // in http2 [TFE_HTTP_UNKNOWN_FIELD] = "unknown"; [TFE_HTTP_HOST] = ":authority" - if ( (strlen(str) == strlen(":authority")) && !strncasecmp(str, ":authority", strlen(":authority"))) + normlen = strlen(":authority"); + if ( (slen == normlen) && !strncasecmp(str, ":authority", normlen)) { return TFE_HTTP_HOST; } else { diff --git a/plugin/protocol/http2/src/http2_stream.cpp b/plugin/protocol/http2/src/http2_stream.cpp index 2f88dba..29f8c69 100644 --- a/plugin/protocol/http2/src/http2_stream.cpp +++ b/plugin/protocol/http2/src/http2_stream.cpp @@ -1872,7 +1872,8 @@ nghttp2_fill_up_header(nghttp2_session *ngh2_session, const nghttp2_frame *frame struct tfe_h2_half_private *half = (dir == CONN_DIR_UPSTREAM) ? h2_session->resp : h2_session->req; struct http_field_name field; - field.field_id = (enum tfe_http_std_field)http2_header_str_to_val((const char *)name, __str_std_header_field_map, __str_std_header_field_map_size); + // "name" may not terminated with '\0', so use "namelen" + field.field_id = (enum tfe_http_std_field)http2_header_str_to_val((const char *)name, namelen, __str_std_header_field_map, __str_std_header_field_map_size); if (field.field_id == TFE_HTTP_UNKNOWN_FIELD) { field.field_name = (const char *)name; @@ -1906,7 +1907,8 @@ nghttp2_fill_up_promise(nghttp2_session *ngh2_session, const nghttp2_frame *fram } resp = h2_session->resp; struct http_field_name field; - field.field_id = (enum tfe_http_std_field)http2_header_str_to_val((const char *)name, __str_std_header_field_map, __str_std_header_field_map_size); + // "name" may not terminated with '\0', so use "namelen" + field.field_id = (enum tfe_http_std_field)http2_header_str_to_val((const char *)name, namelen, __str_std_header_field_map, __str_std_header_field_map_size); if (field.field_id == TFE_HTTP_UNKNOWN_FIELD) { field.field_name = (const char *)name;