Index: modules/cache/cache_storage.c =================================================================== --- modules/cache/cache_storage.c (revision 891604) +++ modules/cache/cache_storage.c (working copy) @@ -503,21 +503,53 @@ /* * Check if the identifier is in the querystring and cut it out. */ - if (querystring - && (param = strstr(querystring, *identifier)) - && (*(param + len) == '=') - ) { - char *amp; - - if (querystring != param) { - querystring = apr_pstrndup(p, querystring, - param - querystring); + if (querystring) { + /* + * First check if the identifier is at the beginning of the + * querystring and followed by a '=' + */ + if (!strncmp(querystring, *identifier, len) + && (*(querystring + len) == '=')) { + param = querystring; } else { - querystring = ""; + char *complete; + + /* + * In order to avoid subkey matching (PR 48401) prepend + * identifier with a '&' and append a '=' + */ + complete = apr_pstrcat(p, "&", *identifier, "=", NULL); + param = strstr(querystring, complete); + /* If we found something we are sitting on the '&' */ + if (param) { + param++; + } } - if ((amp = strchr(param + len + 1, '&'))) { - querystring = apr_pstrcat(p, querystring, amp + 1, NULL); + if (param) { + char *amp; + + + if (querystring != param) { + querystring = apr_pstrndup(p, querystring, + param - querystring); + } + else { + querystring = ""; + } + if ((amp = strchr(param + len + 1, '&'))) { + querystring = apr_pstrcat(p, querystring, amp + 1, NULL); + } + /* Check for a trailing '&' and remove it */ + else { + int qs_len_idx; + + qs_len_idx = strlen(querystring) - 1; + if ((*querystring) + && (querystring[qs_len_idx] == '&')) { + querystring[qs_len_idx] = '\0'; + } + } } break; }