From 5c89604a32bff8682587dd67d9cf67a9a2c70598 Mon Sep 17 00:00:00 2001 From: Joshua Colp Date: Tue, 15 Nov 2016 00:18:21 +0000 Subject: [PATCH] res_format_attr_opus: Fix crash when fmtp contains spaces. When an opus offer or answer was received that contained an fmtp line with spaces between the attributes the module would fail to properly parse it and crash due to recursion. This change makes the module handle the space properly and also removes the recursion requirement. ASTERISK-26579 Change-Id: I01f53e5d9fa9f1925a7365f8d25071b5b3ac2dc3 --- res/res_format_attr_opus.c | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/res/res_format_attr_opus.c b/res/res_format_attr_opus.c index 45aa5e5c67..1367f95788 100644 --- a/res/res_format_attr_opus.c +++ b/res/res_format_attr_opus.c @@ -101,27 +101,35 @@ static int opus_clone(const struct ast_format *src, struct ast_format *dst) static void sdp_fmtp_get(const char *attributes, const char *name, int *attr) { - const char *kvp = ""; + const char *kvp = attributes; int val; - if (attributes && !(kvp = strstr(attributes, name))) { + if (ast_strlen_zero(attributes)) { return; } - /* - * If the named attribute is not at the start of the given attributes, and - * the preceding character is not a space or semicolon then it's not the - * attribute we are looking for. It's an attribute with the name embedded - * within it (e.g. ptime in maxptime, stereo in sprop-stereo). + /* This logic goes through each attribute in the fmtp line looking for the + * requested named attribute. */ - if (kvp != attributes && *(kvp - 1) != ' ' && *(kvp - 1) != ';') { - /* Keep searching as it might still be in the attributes string */ - sdp_fmtp_get(strchr(kvp, ';'), name, attr); - /* - * Otherwise it's a match, so retrieve the value and set the attribute. - */ - } else if (sscanf(kvp, "%*[^=]=%30d", &val) == 1) { - *attr = val; + while (*kvp) { + /* Skip any preceeding blanks as some implementations separate attributes using spaces too */ + kvp = ast_skip_blanks(kvp); + + /* If we are at at the requested attribute get its value and return */ + if (!strncmp(kvp, name, strlen(name)) && kvp[strlen(name)] == '=') { + if (sscanf(kvp, "%*[^=]=%30d", &val) == 1) { + *attr = val; + break; + } + } + + /* Move on to the next attribute if possible */ + kvp = strchr(kvp, ';'); + if (!kvp) { + break; + } + + kvp++; } }