]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: var_get_key() didn't handle %{long_variables} correctly
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Tue, 2 Aug 2016 10:38:25 +0000 (13:38 +0300)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Thu, 4 Aug 2016 15:16:45 +0000 (18:16 +0300)
This also fixes var_has_key()'s long_key handling.

src/lib/test-var-expand.c
src/lib/var-expand.c
src/lib/var-expand.h

index d3f248a9ed415408f26dbc400306308ddf8eacf4..33ed0f3ed3ee87960e098b0aaa2003dbc5f72329 100644 (file)
@@ -151,10 +151,31 @@ static void test_var_expand_with_funcs(void)
        test_end();
 }
 
+static void test_var_get_key(void)
+{
+       static struct {
+               const char *str;
+               char key;
+       } tests[] = {
+               { "x", 'x' },
+               { "2.5Mx", 'x' },
+               { "200MDx", 'x' },
+               { "200MD{foo}", '{' },
+               { "{foo}", '{' },
+               { "", '\0' },
+       };
+
+       test_begin("var_get_key");
+       for (unsigned int i = 0; i < N_ELEMENTS(tests); i++)
+               test_assert_idx(var_get_key(tests[i].str) == tests[i].key, i);
+       test_end();
+}
+
 void test_var_expand(void)
 {
        test_var_expand_ranges();
        test_var_expand_builtin();
        test_var_get_key_range();
        test_var_expand_with_funcs();
+       test_var_get_key();
 }
index 5d06cebee05854e35f97492a2132386f8c82d0ec..922864c2b427fc2fa919986e6a25facb85fdd2a0 100644 (file)
@@ -388,15 +388,8 @@ void var_expand(string_t *dest, const char *str,
        var_expand_with_funcs(dest, str, table, NULL, NULL);
 }
 
-char var_get_key(const char *str)
-{
-       unsigned int idx, size;
-
-       var_get_key_range(str, &idx, &size);
-       return str[idx];
-}
-
-void var_get_key_range(const char *str, unsigned int *idx_r,
+static bool
+var_get_key_range_full(const char *str, unsigned int *idx_r,
                       unsigned int *size_r)
 {
        const struct var_expand_modifier *m;
@@ -425,6 +418,7 @@ void var_get_key_range(const char *str, unsigned int *idx_r,
                /* short key */
                *idx_r = i;
                *size_r = str[i] == '\0' ? 0 : 1;
+               return FALSE;
        } else {
                /* long key */
                *idx_r = ++i;
@@ -433,9 +427,25 @@ void var_get_key_range(const char *str, unsigned int *idx_r,
                                break;
                }
                *size_r = i - *idx_r;
+               return TRUE;
        }
 }
 
+char var_get_key(const char *str)
+{
+       unsigned int idx, size;
+
+       if (var_get_key_range_full(str, &idx, &size))
+               return '{';
+       return str[idx];
+}
+
+void var_get_key_range(const char *str, unsigned int *idx_r,
+                      unsigned int *size_r)
+{
+       (void)var_get_key_range_full(str, idx_r, size_r);
+}
+
 static bool var_has_long_key(const char **str, const char *long_key)
 {
        const char *start, *end;
index d36bb2cebdf195a10ea5a9c3a89531e8684c4d8a..ac554ff15cde6ec10bb90c45ae6dc20b7379a1d1 100644 (file)
@@ -25,7 +25,8 @@ void var_expand_with_funcs(string_t *dest, const char *str,
                           void *func_context) ATTR_NULL(3, 4, 5);
 
 /* Returns the actual key character for given string, ie. skip any modifiers
-   that are before it. The string should be the data after the '%' character. */
+   that are before it. The string should be the data after the '%' character.
+   For %{long_variable}, '{' is returned. */
 char var_get_key(const char *str) ATTR_PURE;
 /* Similar to var_get_key(), but works for long keys as well. For single char
    keys size=1, while for e.g. %{key} size=3 and idx points to 'k'. */