On 02/12/2011 02:08 PM, [email protected] wrote:
> Author: minfrin
> Date: Sat Feb 12 13:08:57 2011
> New Revision: 1070075
>
> URL: http://svn.apache.org/viewvc?rev=1070075&view=rev
> Log:
> mod_cache: We must ignore quoted-string values that appear in a
> Cache-Control header. PR 50199.
>
> Modified:
> httpd/httpd/trunk/CHANGES
> httpd/httpd/trunk/modules/cache/cache_util.c
>
> Modified: httpd/httpd/trunk/modules/cache/cache_util.c
> URL:
> http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/cache/cache_util.c?rev=1070075&r1=1070074&r2=1070075&view=diff
> ==============================================================================
> --- httpd/httpd/trunk/modules/cache/cache_util.c (original)
> +++ httpd/httpd/trunk/modules/cache/cache_util.c Sat Feb 12 13:08:57 2011
> @@ -1022,6 +1024,74 @@ CACHE_DECLARE(apr_table_t *)ap_cache_cac
> }
>
> /**
> + * String tokenizer that ignores separator characters within quoted strings
> + * and escaped characters, as per RFC2616 section 2.2.
> + */
> +static char *cache_strqtok(char *str, const char *sep, char **last)
> +{
> + char *token;
> + int quoted = 0;
> +
> + if (!str) { /* subsequent call */
> + str = *last; /* start where we left off */
> + }
> +
> + /* skip characters in sep (will terminate at '\0') */
> + while (*str && strchr(sep, *str)) {
> + ++str;
> + }
> +
> + if (!*str) { /* no more tokens */
> + return NULL;
> + }
> +
> + token = str;
> +
> + /* skip valid token characters to terminate token and
> + * prepare for the next call (will terminate at '\0)
> + * on the way, ignore all quoted strings, and within
> + * quoted strings, escaped characters.
> + */
> + *last = token + 1;
What happens if str is supplied as "a, b"?
I mean why token + 1 and not token?
> + while (**last) {
> + if (!quoted) {
> + if (**last == '\"') {
> + quoted = 1;
> + ++*last;
> + }
> + else if (!strchr(sep, **last)) {
> + ++*last;
> + }
> + else {
> + break;
> + }
> + }
> + else {
> + if (**last == '\"') {
> + quoted = 0;
> + ++*last;
> + }
> + else if (**last == '\\') {
> + ++*last;
> + if (**last) {
> + ++*last;
> + }
> + }
> + else {
> + ++*last;
> + }
> + }
> + }
> +
> + if (**last) {
> + **last = '\0';
> + ++*last;
> + }
> +
> + return token;
> +}
> +
> +/**
> * Parse the Cache-Control and Pragma headers in one go, marking
> * which tokens appear within the header. Populate the structure
> * passed in.