]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
res_geolocation: Fix segfault when there's an empty element
authorGeorge Joseph <gjoseph@digium.com>
Tue, 13 Sep 2022 13:14:37 +0000 (07:14 -0600)
committerGeorge Joseph <gjoseph@digium.com>
Tue, 13 Sep 2022 14:50:38 +0000 (09:50 -0500)
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

include/asterisk/strings.h
main/config.c
main/utils.c
res/res_geolocation/geoloc_eprofile.c
tests/test_config.c

index d0a4cbb02afa4078117a3dd50d6f7f74b945d5f8..f8ad4140d8fea4d3eca0c5a08f68f05100514c5d 100644 (file)
@@ -265,6 +265,7 @@ enum ast_strsep_flags {
   \param sep A single character delimiter.
   \param flags Controls post-processing of 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
   to trim again after the strip.  Just OR both the TRIM and STRIP flags.
   AST_STRSEP_UNESCAPE unescapes '\' sequences.
index 0e27d766407e21ca0962dd219e3f1646dfd2bc19..1074407967a9b62eaf49a2b608f0a05224063b40 100644 (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 *curr;
+       struct ast_variable *sh = search_hint;
        ast_assert(head != NULL);
 
        if (!*head) {
                *head = newvar;
        } else {
-               if (search_hint == NULL) {
-                       search_hint = *head;
+               if (sh == NULL) {
+                       sh = *head;
                }
-               for (curr = search_hint; curr->next; curr = curr->next);
+               for (curr = sh; curr->next; curr = curr->next);
                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);
-               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) {
                        ast_variables_destroy(new_list);
                        return NULL;
index 3ab6dc1e704a28982792268808ea28af218310f4..6111b86dda98a87de87790cfa4fcd4453f5e5c50 100644 (file)
@@ -1849,7 +1849,10 @@ char *ast_strsep(char **iss, const char sep, uint32_t flags)
        }
 
        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) {
@@ -1910,7 +1913,10 @@ char *ast_strsep_quoted(char **iss, const char sep, const char quote, uint32_t f
        }
 
        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) {
index 864dd23b244919a749f4694dd2d17d08649a5662..09a06c614163b46d1c77dac252b7571b8af14f6b 100644 (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)
 {
        struct ast_variable *list = NULL;
+       struct ast_variable *locinfo_list = NULL;
        struct ast_xml_node *container;
        struct ast_variable *var = NULL;
        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_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)) {
                struct ast_str *buf = NULL;
index 166879a820d2b5a4c814ea03605b3d876f46775f..1d44e5d5baf464a2f5d2d0035dc0381bcd880b28 100644 (file)
@@ -1961,13 +1961,13 @@ AST_TEST_DEFINE(variable_list_from_string)
                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, ",", "=", "'");
        ast_test_validate(test, list != NULL);
        str = ast_variable_list_join(list, "|", "^", "@", NULL);
 
        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;
 }