diff options
author | Guy Harris <guy@alum.mit.edu> | 2013-03-22 23:18:30 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2013-03-22 23:18:30 +0000 |
commit | 3295912210fa1a8d7d0b1a18aa7c100f27905ed1 (patch) | |
tree | 59ba420143924de8ef069607beb234868612cbd2 /epan/dissectors/packet-http.c | |
parent | 100b208c9a3e093e942d2908980b60bf20ed309b (diff) |
Try to handle lines with NULs in them. They aren't valid lines, but at
least one fuzzed capture contains them, and using ep_strndup() to copy
the line means that the actual amount of memory allocated for the copy
will be less than the length of the line, and code that parses the line
assuming that there are value_len+1 bytes in the buffer (including the
terminating NUL), such as the current parsing code, will break.
We should really have code in Wireshark to handle counted strings, and
have those be what we extract from packets. (And we should handle
non-UTF-8/non-UTF-16 encodings, and octet sequences that aren't valid
strings for their encoding, and handle display of invalid strings and
non-printable characters, and....).
Use g_ascii_ versions of various isXXX() and to{upper,lower}(), so we
don't get surprised by the behavior of the user's locale.
svn path=/trunk/; revision=48490
Diffstat (limited to 'epan/dissectors/packet-http.c')
-rw-r--r-- | epan/dissectors/packet-http.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/epan/dissectors/packet-http.c b/epan/dissectors/packet-http.c index 895097330f..721b085fb0 100644 --- a/epan/dissectors/packet-http.c +++ b/epan/dissectors/packet-http.c @@ -2323,9 +2323,19 @@ process_header(tvbuff_t *tvb, int offset, int next_offset, /* * Fetch the value. + * + * XXX - the line may well have a NUL in it. Wireshark should + * really treat strings extracted from packets as counted + * strings, so that NUL isn't any different from any other + * character. For now, we just allocate a buffer that's + * value_len+1 bytes long, copy value_len bytes, and stick + * in a NUL terminator, so that the buffer for value actually + * has value_len bytes in it. */ value_len = line_end_offset - value_offset; - value = ep_strndup(&line[value_offset - offset], value_len); + value = (char *)ep_alloc(value_len+1); + memcpy(value, &line[value_offset - offset], value_len); + value[value_len] = '\0'; if (hf_index == -1) { /* @@ -2399,7 +2409,7 @@ process_header(tvbuff_t *tvb, int offset, int next_offset, for (i = 0; i < value_len; i++) { c = value[i]; - if (c == ';' || isspace(c)) { + if (c == ';' || g_ascii_isspace(c)) { /* * End of subtype - either * white space or a ";" @@ -2413,7 +2423,7 @@ process_header(tvbuff_t *tvb, int offset, int next_offset, * Map the character to lower case; * content types are case-insensitive. */ - eh_ptr->content_type[i] = tolower(eh_ptr->content_type[i]); + eh_ptr->content_type[i] = g_ascii_tolower(eh_ptr->content_type[i]); } eh_ptr->content_type[i] = '\0'; /* @@ -2424,7 +2434,7 @@ process_header(tvbuff_t *tvb, int offset, int next_offset, i++; while (i < value_len) { c = eh_ptr->content_type[i]; - if (c == ';' || isspace(c)) + if (c == ';' || g_ascii_isspace(c)) /* Skip till start of parameters */ i++; else |