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
This commit is contained in:
George Joseph
2022-09-13 07:14:37 -06:00
parent 80bc844fd6
commit 8cbea1c7ef
5 changed files with 23 additions and 13 deletions

View File

@@ -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.

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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;
} }