res_geolocation: Fix segfault when there's an empty element

Fixed a segfault caused by var_list_from_loc_info() encountering
an empty location info element.

Fixed an issue in ast_strsep() where a value with only whitespace
wasn't being preserved.

Fixed an issue in ast_variable_list_from_quoted_string() where
an empty value was considered a failure.

ASTERISK-30215
Reported by: Dan Cropp

Change-Id: Ieca64e061a6d9298f0196c694b60d986ef82613a
pull/30/head
George Joseph 3 years ago
parent fc63688e3b
commit bd2fb077ac

@ -265,6 +265,7 @@ enum ast_strsep_flags {
\param sep A single character delimiter. \param sep A single character delimiter.
\param flags Controls post-processing of the result. \param flags Controls post-processing of the result.
AST_STRSEP_TRIM trims all leading and trailing whitespace from the result. AST_STRSEP_TRIM trims all leading and trailing whitespace from the result.
If the result containes only whitespace, it'll be passed through unchanged.
AST_STRSEP_STRIP does a trim then strips the outermost quotes. You may want AST_STRSEP_STRIP does a trim then strips the outermost quotes. You may want
to trim again after the strip. Just OR both the TRIM and STRIP flags. to trim again after the strip. Just OR both the TRIM and STRIP flags.
AST_STRSEP_UNESCAPE unescapes '\' sequences. AST_STRSEP_UNESCAPE unescapes '\' sequences.

@ -646,15 +646,16 @@ struct ast_variable *ast_variable_list_sort(struct ast_variable *start)
struct ast_variable *ast_variable_list_append_hint(struct ast_variable **head, struct ast_variable *search_hint, struct ast_variable *newvar) struct ast_variable *ast_variable_list_append_hint(struct ast_variable **head, struct ast_variable *search_hint, struct ast_variable *newvar)
{ {
struct ast_variable *curr; struct ast_variable *curr;
struct ast_variable *sh = search_hint;
ast_assert(head != NULL); ast_assert(head != NULL);
if (!*head) { if (!*head) {
*head = newvar; *head = newvar;
} else { } else {
if (search_hint == NULL) { if (sh == NULL) {
search_hint = *head; sh = *head;
} }
for (curr = search_hint; curr->next; curr = curr->next); for (curr = sh; curr->next; curr = curr->next);
curr->next = newvar; curr->next = newvar;
} }
@ -752,12 +753,8 @@ struct ast_variable *ast_variable_list_from_quoted_string(const char *input, con
} }
item_value = ast_strsep_quoted(&item, nv_sep, quote, AST_STRSEP_ALL); item_value = ast_strsep_quoted(&item, nv_sep, quote, AST_STRSEP_ALL);
if (!item_value) {
ast_variables_destroy(new_list);
return NULL;
}
new_var = ast_variable_new(item_name, item_value, ""); new_var = ast_variable_new(item_name, item_value ?: "", "");
if (!new_var) { if (!new_var) {
ast_variables_destroy(new_list); ast_variables_destroy(new_list);
return NULL; return NULL;

@ -1849,7 +1849,10 @@ char *ast_strsep(char **iss, const char sep, uint32_t flags)
} }
if (flags & AST_STRSEP_TRIM) { if (flags & AST_STRSEP_TRIM) {
st = ast_strip(st); char *trimmed = ast_strip(st);
if (!ast_strlen_zero(trimmed)) {
st = trimmed;
}
} }
if (flags & AST_STRSEP_UNESCAPE) { if (flags & AST_STRSEP_UNESCAPE) {
@ -1910,7 +1913,10 @@ char *ast_strsep_quoted(char **iss, const char sep, const char quote, uint32_t f
} }
if (flags & AST_STRSEP_TRIM) { if (flags & AST_STRSEP_TRIM) {
st = ast_strip(st); char *trimmed = ast_strip(st);
if (!ast_strlen_zero(trimmed)) {
st = trimmed;
}
} }
if (flags & AST_STRSEP_UNESCAPE) { if (flags & AST_STRSEP_UNESCAPE) {

@ -498,6 +498,7 @@ static struct ast_variable *var_list_from_loc_info(struct ast_xml_node *locinfo,
enum ast_geoloc_format format, const char *ref_str) enum ast_geoloc_format format, const char *ref_str)
{ {
struct ast_variable *list = NULL; struct ast_variable *list = NULL;
struct ast_variable *locinfo_list = NULL;
struct ast_xml_node *container; struct ast_xml_node *container;
struct ast_variable *var = NULL; struct ast_variable *var = NULL;
const char *attr; const char *attr;
@ -531,7 +532,12 @@ static struct ast_variable *var_list_from_loc_info(struct ast_xml_node *locinfo,
ast_variable_list_append(&list, var); ast_variable_list_append(&list, var);
} }
ast_variable_list_append(&list, var_list_from_node(container, ref_str)); locinfo_list = var_list_from_node(container, ref_str);
if (locinfo_list == NULL) {
ast_log(LOG_WARNING, "%s: There were no elements in the location info\n", ref_str);
SCOPE_EXIT_RTN_VALUE(list, "%s: There were no elements in the location info\n", ref_str);
}
ast_variable_list_append(&list, locinfo_list);
if (TRACE_ATLEAST(5)) { if (TRACE_ATLEAST(5)) {
struct ast_str *buf = NULL; struct ast_str *buf = NULL;

@ -1961,13 +1961,13 @@ AST_TEST_DEFINE(variable_list_from_string)
break; break;
} }
parse_string = "abc = 'def', ghi = 'j,kl', mno='pq=r', stu = 'vwx=\"yz\", ABC = \"DEF\"'"; parse_string = "000= '', 111=, 222 = , 333 = ' ', abc = 'def', ghi = 'j,kl', mno='pq=r', stu = 'vwx=\"yz\", ABC = \"DEF\"'";
list = ast_variable_list_from_quoted_string(parse_string, ",", "=", "'"); list = ast_variable_list_from_quoted_string(parse_string, ",", "=", "'");
ast_test_validate(test, list != NULL); ast_test_validate(test, list != NULL);
str = ast_variable_list_join(list, "|", "^", "@", NULL); str = ast_variable_list_join(list, "|", "^", "@", NULL);
ast_test_validate(test, ast_test_validate(test,
strcmp(ast_str_buffer(str), "abc^@def@|ghi^@j,kl@|mno^@pq=r@|stu^@vwx=\"yz\", ABC = \"DEF\"@") == 0); strcmp(ast_str_buffer(str), "000^@@|111^@@|222^@@|333^@ @|abc^@def@|ghi^@j,kl@|mno^@pq=r@|stu^@vwx=\"yz\", ABC = \"DEF\"@") == 0);
return AST_TEST_PASS; return AST_TEST_PASS;
} }

Loading…
Cancel
Save