From e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 10 Apr 2024 22:34:10 +0200 Subject: Adding upstream version 4.2.2. Signed-off-by: Daniel Baumann --- epan/media_params.c | 228 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 228 insertions(+) create mode 100644 epan/media_params.c (limited to 'epan/media_params.c') diff --git a/epan/media_params.c b/epan/media_params.c new file mode 100644 index 0000000..ae310df --- /dev/null +++ b/epan/media_params.c @@ -0,0 +1,228 @@ +/* media_params.c + * Routines for parsing media type parameters as per RFC 822 and RFC 2045 + * Copyright 2004, Anders Broman. + * Copyright 2004, Olivier Biot. + * + * Refer to the AUTHORS file or the AUTHORS section in the man page + * for contacting the author(s) of this file. + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "config.h" + +#include +#include + +#include + +static const char * +ws_get_next_media_type_parameter(const char *pos, gsize *retnamelen, + const char **retvalue, gsize *retvaluelen, + const char **nextp) +{ + const char *p, *namep, *valuep; + char c; + + p = pos; + while ((c = *p) != '\0' && g_ascii_isspace(c)) + p++; /* Skip white space */ + + if (c == '\0') { + /* No more parameters left */ + return NULL; + } + + namep = p; + + /* Look for a '\0' (end of string), '=' (end of parameter name, + beginning of parameter value), or ';' (end of parameter). */ + while ((c = *p) != '\0' && c != '=' && c != ';') + p++; + *retnamelen = (gsize) (p - namep); + if (c == '\0') { + /* End of string, so end of parameter, no parameter value */ + if (retvalue != NULL) + *retvalue = NULL; + if (retvaluelen != NULL) + *retvaluelen = 0; + *nextp = p; + return namep; + } + if (c == ';') { + /* End of parameter, no parameter value */ + if (retvalue != NULL) + *retvalue = NULL; + if (retvaluelen != NULL) + *retvaluelen = 0; + *nextp = p + 1; + return namep; + } + /* The parameter has a value. Skip the '=' */ + p++; + valuep = p; + if (retvalue != NULL) + *retvalue = valuep; + /* Is the value a quoted string? */ + if (*p == '"') { + /* Yes. Skip the opening quote, and scan forward looking for + a non-escaped closing quote. */ + p++; + for (;;) { + c = *p; + if (c == '\0') { + /* End-of-string. We're done. + (XXX - this is an error.) */ + if (retvaluelen != NULL) { + *retvaluelen = (gsize) (p - valuep); + } + *nextp = p; + return namep; + } + if (c == '"') { + /* Closing quote. Skip it; we're done with + the quoted-string. */ + p++; + break; + } + if (c == '\\') { + /* Backslash; this escapes the next character + (quoted-pair). Skip the backslash, and make + sure there *is* a next character. */ + p++; + if (*p == '\0') { + /* Nothing left; we're done. + (XXX - this is an error.) */ + break; + } + } + /* Skip the character we just processed. */ + p++; + } + /* Now scan forward looking for a '\0' (end of string) + or ';' (end of parameter), in case there's any + extra cruft after the quoted-string. */ + while ((c = *p) != '\0' && c != ';') + p++; + } else { + /* No. Just scan forward looking for a '\0' (end + of string) or ';' (end of parameter). */ + while ((c = *p) != '\0' && c != ';') + p++; + } + if (c == '\0') { + /* End of string, so end of parameter */ + if (retvaluelen != NULL) { + *retvaluelen = (gsize) (p - valuep); + } + *nextp = p; + return namep; + } + /* End of parameter; point past the terminating ';' */ + if (retvaluelen != NULL) { + *retvaluelen = (gsize) (p - valuep); + } + *nextp = p + 1; + return namep; +} + +char * +ws_find_media_type_parameter(wmem_allocator_t *scope, const char *parameters, const char *key) +{ + const char *p, *name, *value; + char c; + gsize keylen, namelen, valuelen; + char *valuestr, *vp; + + if (parameters == NULL || key == NULL) + /* we won't be able to find anything */ + return NULL; + + keylen = (gsize) strlen(key); + if (keylen == 0) { + /* There's no parameter name to searh for */ + return NULL; + } + p = parameters; + if (*p == '\0') { + /* There are no parameters in which to search */ + return NULL; + } + + do { + /* Get the next parameter. */ + name = ws_get_next_media_type_parameter(p, &namelen, &value, + &valuelen, &p); + if (name == NULL) { + /* No more parameters - not found. */ + return NULL; + } + + /* Is it the parameter we're looking for? */ + if (namelen == keylen && g_ascii_strncasecmp(name, key, keylen) == 0) { + /* Yes. */ + break; + } + } while (*p); + + if (value == NULL) { + /* The parameter doesn't have a value. */ + return NULL; + } + + /* We found the parameter with that name; now extract the value. */ + valuestr = (char *)wmem_alloc(scope, valuelen + 1); + vp = valuestr; + p = value; + /* Is the value a quoted string? */ + if (*p == '"') { + /* Yes. Skip the opening quote, and scan forward looking for + a non-escaped closing quote, copying characters. */ + p++; + for (;;) { + c = *p; + if (c == '\0') { + /* End-of-string. We're done. + (XXX - this is an error.) */ + *vp = '\0'; + return valuestr; + } + if (c == '"') { + /* Closing quote. Skip it; we're done with + the quoted-string. */ + p++; + break; + } + if (c == '\\') { + /* Backslash; this escapes the next character + (quoted-pair). Skip the backslash, and make + sure there *is* a next character. */ + p++; + if (*p == '\0') { + /* Nothing left; we're done. + (XXX - this is an error.) */ + break; + } + } + /* Copy the character. */ + *vp++ = *p++; + } + } else { + /* No. Just scan forward until we see a '\0' (end of + string or a non-token character, copying characters. */ + while ((c = *p) != '\0' && g_ascii_isgraph(c) && c != '(' && + c != ')' && c != '<' && c != '>' && c != '@' && + c != ',' && c != ';' && c != ':' && c != '\\' && + c != '"' && c != '/' && c != '[' && c != ']' && + c != '?' && c != '=' && c != '{' && c != '}') { + *vp++ = c; + p++; + } + } + *vp = '\0'; + return valuestr; +} -- cgit v1.2.3