static void test_var_get_key_range(void) { static const struct var_get_key_range_test tests[] = { { "", 0, 0 }, { "{", 1, 0 }, { "k", 0, 1 }, { "{key}", 1, 3 }, { "5.5Rk", 4, 1 }, { "5.5R{key}", 5, 3 }, { "{key", 1, 3 }, { "{if;%{if;%{value};eq;value;t;f};eq;t;t;f}", 1, 39 }, }; unsigned int i, idx, size; test_begin("var_get_key_range"); for (i = 0; i < N_ELEMENTS(tests); i++) { var_get_key_range(tests[i].in, &idx, &size); test_assert_idx(tests[i].idx == idx, i); test_assert_idx(tests[i].size == size, i); if (tests[i].size == 1) test_assert_idx(tests[i].in[idx] == var_get_key(tests[i].in), i); } test_end(); }
char *auth_cache_parse_key(pool_t pool, const char *query) { string_t *str; bool key_seen[AUTH_REQUEST_VAR_TAB_COUNT]; const char *extra_vars; unsigned int i, idx, size, tab_idx; memset(key_seen, 0, sizeof(key_seen)); str = t_str_new(32); for (; *query != '\0'; ) { if (*query != '%') { query++; continue; } var_get_key_range(++query, &idx, &size); if (size == 0) { /* broken %variable ending too early */ break; } query += idx; if (!auth_request_var_expand_tab_find(query, size, &tab_idx)) { /* just add the key. it would be nice to prevent duplicates here as well, but that's just too much trouble and probably very rare. */ auth_cache_key_add_var(str, query, size); } else { i_assert(tab_idx < N_ELEMENTS(key_seen)); key_seen[tab_idx] = TRUE; } query += size; } if (key_seen[AUTH_REQUEST_VAR_TAB_USERNAME_IDX] && key_seen[AUTH_REQUEST_VAR_TAB_DOMAIN_IDX]) { /* %n and %d both used -> replace with %u */ key_seen[AUTH_REQUEST_VAR_TAB_USER_IDX] = TRUE; key_seen[AUTH_REQUEST_VAR_TAB_USERNAME_IDX] = FALSE; key_seen[AUTH_REQUEST_VAR_TAB_DOMAIN_IDX] = FALSE; } /* we rely on these being at the beginning */ i_assert(AUTH_REQUEST_VAR_TAB_USER_IDX == 0); i_assert(AUTH_REQUEST_VAR_TAB_USERNAME_IDX == 1); i_assert(AUTH_REQUEST_VAR_TAB_DOMAIN_IDX == 2); extra_vars = t_strdup(str_c(str)); str_truncate(str, 0); for (i = 0; i < N_ELEMENTS(key_seen); i++) { if (key_seen[i]) auth_cache_key_add_tab_idx(str, i); } if (*extra_vars != '\0') { if (str_len(str) > 0) str_append_c(str, '\t'); str_append(str, extra_vars); } return p_strdup(pool, str_c(str)); }