cookie: cleanups and improvements
No binary (build failed)
—
(log yok)
| @@ -441,85 +441,79 @@ parse_cookie_header(struct Curl_easy *data, | |
| origin */ | |
| { | |
| /* This line was read off an HTTP-header */ | |
| - | time_t now; |
| + | time_t now = 0; |
| size_t linelength = strlen(ptr); | |
| - | CURLcode result; |
| - | struct Curl_str cookie[COOKIE_PIECES] = { 0 }; |
| + | CURLcode result = CURLE_OK; |
| + | struct Curl_str cookie[COOKIE_PIECES]; |
| *okay = FALSE; | |
| if(linelength > MAX_COOKIE_LINE) | |
| /* discard overly long lines at once */ | |
| return CURLE_OK; | |
| - | now = time(NULL); |
| + | /* memset instead of initializer because gcc 4.8.1 is silly */ |
| + | memset(cookie, 0, sizeof(cookie)); |
| do { | |
| struct Curl_str name; | |
| struct Curl_str val; | |
| /* we have a <name>=<value> pair or a stand-alone word here */ | |
| if(!curlx_str_cspn(&ptr, &name, ";\t\r\n=")) { | |
| - | bool done = FALSE; |
| bool sep = FALSE; | |
| curlx_str_trimblanks(&name); | |
| if(!curlx_str_single(&ptr, '=')) { | |
| sep = TRUE; /* a '=' was used */ | |
| - | if(!curlx_str_cspn(&ptr, &val, ";\r\n")) { |
| + | if(!curlx_str_cspn(&ptr, &val, ";\r\n")) |
| curlx_str_trimblanks(&val); | |
| - | |
| - | /* Reject cookies with a TAB inside the value */ |
| - | if(memchr(curlx_str(&val), '\t', curlx_strlen(&val))) { |
| - | infof(data, "cookie contains TAB, dropping"); |
| - | return CURLE_OK; |
| - | } |
| - | } |
| } | |
| - | else { |
| + | else |
| curlx_str_init(&val); | |
| - | } |
| - | |
| - | /* |
| - | * Check for too long individual name or contents, or too long |
| - | * combination of name + contents. Chrome and Firefox support 4095 or |
| - | * 4096 bytes combo |
| - | */ |
| - | if(curlx_strlen(&name) >= (MAX_NAME - 1) || |
| - | curlx_strlen(&val) >= (MAX_NAME - 1) || |
| - | ((curlx_strlen(&name) + curlx_strlen(&val)) > MAX_NAME)) { |
| - | infof(data, "oversized cookie dropped, name/val %zu + %zu bytes", |
| - | curlx_strlen(&name), curlx_strlen(&val)); |
| - | return CURLE_OK; |
| - | } |
| - | |
| - | /* |
| - | * Check if we have a reserved prefix set before anything else, as we |
| - | * otherwise have to test for the prefix in both the cookie name and |
| - | * "the rest". Prefixes must start with '__' and end with a '-', so |
| - | * only test for names where that can possibly be true. |
| - | */ |
| - | if(!strncmp("__Secure-", curlx_str(&name), 9)) |
| - | co->prefix_secure = TRUE; |
| - | else if(!strncmp("__Host-", curlx_str(&name), 7)) |
| - | co->prefix_host = TRUE; |
| if(!curlx_strlen(&cookie[COOKIE_NAME])) { | |
| /* The first name/value pair is the actual cookie name */ | |
| if(!sep || | |
| /* Bad name/value pair. */ | |
| invalid_octets(curlx_str(&name), curlx_strlen(&name)) || | |
| - | invalid_octets(curlx_str(&val), curlx_strlen(&val))) { |
| + | invalid_octets(curlx_str(&val), curlx_strlen(&val)) || |
| + | !curlx_strlen(&name)) { |
| infof(data, "invalid octets in name/value, cookie dropped"); | |
| return CURLE_OK; | |
| } | |
| + | |
| + | /* |
| + | * Check for too long individual name or contents, or too long |
| + | * combination of name + contents. Chrome and Firefox support 4095 or |
| + | * 4096 bytes combo |
| + | */ |
| + | if(curlx_strlen(&name) >= (MAX_NAME - 1) || |
| + | curlx_strlen(&val) >= (MAX_NAME - 1) || |
| + | ((curlx_strlen(&name) + curlx_strlen(&val)) > MAX_NAME)) { |
| + | infof(data, "oversized cookie dropped, name/val %zu + %zu bytes", |
| + | curlx_strlen(&name), curlx_strlen(&val)); |
| + | return CURLE_OK; |
| + | } |
| + | |
| + | /* Reject cookies with a TAB inside the value */ |
| + | if(curlx_strlen(&val) && |
| + | memchr(curlx_str(&val), '\t', curlx_strlen(&val))) { |
| + | infof(data, "cookie contains TAB, dropping"); |
| + | return CURLE_OK; |
| + | } |
| + | |
| + | /* Check if we have a reserved prefix set. */ |
| + | if(!strncmp("__Secure-", curlx_str(&name), 9)) |
| + | co->prefix_secure = TRUE; |
| + | else if(!strncmp("__Host-", curlx_str(&name), 7)) |
| + | co->prefix_host = TRUE; |
| + | |
| cookie[COOKIE_NAME] = name; | |
| cookie[COOKIE_VALUE] = val; | |
| - | done = TRUE; |
| } | |
| - | else if(!curlx_strlen(&val)) { |
| + | else if(!sep) { |
| /* | |
| - | * this was a "<name>=" with no content, and we must allow |
| - | * 'secure' and 'httponly' specified this weirdly |
| + | * this is a "<name>" with no content |
| */ | |
| - | done = TRUE; |
| + | |
| /* | |
| * secure cookies are only allowed to be set when the connection is | |
| * using a secure protocol, or when the cookie is being set by | |
| @@ -529,18 +523,13 @@ parse_cookie_header(struct Curl_easy *data, | |
| if(secure || !ci->running) | |
| co->secure = TRUE; | |
| else { | |
| - | infof(data, "skipped cookie %s because not 'secure'", co->name); |
| + | infof(data, "skipped cookie because not 'secure'"); |
| return CURLE_OK; | |
| } | |
| } | |
| else if(curlx_str_casecompare(&name, "httponly")) | |
| co->httponly = TRUE; | |
| - | else if(sep) |
| - | /* there was a '=' so we are not done parsing this field */ |
| - | done = FALSE; |
| } | |
| - | if(done) |
| - | ; |
| else if(curlx_str_casecompare(&name, "path")) { | |
| cookie[COOKIE_PATH] = val; | |
| } | |
| @@ -588,9 +577,6 @@ parse_cookie_header(struct Curl_easy *data, | |
| return CURLE_OK; | |
| } | |
| } | |
| - | else if(curlx_str_casecompare(&name, "version")) { |
| - | /* just ignore */ |
| - | } |
| else if(curlx_str_casecompare(&name, "max-age") && curlx_strlen(&val)) { | |
| /* | |
| * Defined in RFC2109: | |
| @@ -606,6 +592,8 @@ parse_cookie_header(struct Curl_easy *data, | |
| if(*maxage == '\"') | |
| maxage++; | |
| rc = curlx_str_number(&maxage, &co->expires, CURL_OFF_T_MAX); | |
| + | if(!now) |
| + | now = time(NULL); |
| switch(rc) { | |
| case STRE_OVERFLOW: | |
| /* overflow, used max value */ | |
| @@ -627,46 +615,38 @@ parse_cookie_header(struct Curl_easy *data, | |
| } | |
| cap_expires(now, co); | |
| } | |
| - | else if(curlx_str_casecompare(&name, "expires") && curlx_strlen(&val)) { |
| - | if(!co->expires && (curlx_strlen(&val) < MAX_DATE_LENGTH)) { |
| - | /* |
| - | * Let max-age have priority. |
| - | * |
| - | * If the date cannot get parsed for whatever reason, the cookie |
| - | * will be treated as a session cookie |
| - | */ |
| - | char dbuf[MAX_DATE_LENGTH + 1]; |
| - | time_t date = 0; |
| - | memcpy(dbuf, curlx_str(&val), curlx_strlen(&val)); |
| - | dbuf[curlx_strlen(&val)] = 0; |
| - | if(!Curl_getdate_capped(dbuf, &date)) { |
| - | if(!date) |
| - | date++; |
| - | co->expires = (curl_off_t)date; |
| - | } |
| - | else |
| - | co->expires = 0; |
| - | cap_expires(now, co); |
| + | else if(curlx_str_casecompare(&name, "expires") && curlx_strlen(&val) && |
| + | !co->expires && (curlx_strlen(&val) < MAX_DATE_LENGTH)) { |
| + | /* |
| + | * Let max-age have priority. |
| + | * |
| + | * If the date cannot get parsed for whatever reason, the cookie |
| + | * will be treated as a session cookie |
| + | */ |
| + | char dbuf[MAX_DATE_LENGTH + 1]; |
| + | time_t date = 0; |
| + | memcpy(dbuf, curlx_str(&val), curlx_strlen(&val)); |
| + | dbuf[curlx_strlen(&val)] = 0; |
| + | if(!Curl_getdate_capped(dbuf, &date)) { |
| + | if(!date) |
| + | date++; |
| + | co->expires = (curl_off_t)date; |
| } | |
| + | else |
| + | co->expires = 0; |
| + | if(!now) |
| + | now = time(NULL); |
| + | cap_expires(now, co); |
| } | |
| - | |
| - | /* |
| - | * Else, this is the second (or more) name we do not know about! |
| - | */ |
| } | |
| + | } while(!curlx_str_single(&ptr, ';')); |
| - | if(curlx_str_single(&ptr, ';')) |
| - | break; |
| - | } while(1); |
| - | |
| - | if(!curlx_strlen(&cookie[COOKIE_NAME])) |
| - | /* If we did not get a cookie name, or a bad one, bail out. */ |
| - | return CURLE_OK; |
| - | |
| - | /* the header was fine, now store the data */ |
| - | result = storecookie(co, &cookie[0], path, domain); |
| - | if(!result) |
| - | *okay = TRUE; |
| + | if(curlx_strlen(&cookie[COOKIE_NAME])) { |
| + | /* the header was fine, now store the data */ |
| + | result = storecookie(co, &cookie[0], path, domain); |
| + | if(!result) |
| + | *okay = TRUE; |
| + | } |
| return result; | |
| } | |
| @@ -14,7 +14,7 @@ cookies | |
| HTTP/1.1 200 OK | |
| Date: Tue, 09 Nov 2010 14:49:00 GMT | |
| Content-Length: 0 | |
| - | Set-Cookie: ____________%hex[%ff]hex%= ;%repeat[117 x %20]%%hex[%ff]hex%%repeat[2602 x %20]%%repeat[434 x z]%%hex[%86%85%85%80]hex%%repeat[49 x z]%%hex[%fa]hex%%repeat[540 x z]%%hex[%f3%a0%81%96]hex%zzzzzzzzzzzz~%repeat[82 x z]%%hex[%b6]hex%%repeat[364 x z]% |
| + | Set-Cookie: %repeat[4000 x n]%=%repeat[4096 x v]% |
| </data> | |
| </reply> | |
| @@ -18,6 +18,8 @@ Server: test-server/fake%CR | |
| Content-Length: 4%CR | |
| Content-Type: text/html%CR | |
| Funny-head: yesyes%CR | |
| + | Set-Cookie: |
| + | Set-Cookie: ; |
| Set-Cookie: blankdomain=sure; domain=; path=/ | |
| Set-Cookie: foobar=name; domain=anything.com; path=/ ; secure%CR | |
| Set-Cookie:ismatch=this ; domain=test31.curl; path=/silly/%CR | |
| @@ -25,27 +27,27 @@ Set-Cookie:ISMATCH=this ; domain=test31.curl; path=/silly/%CR | |
| Set-Cookie: overwrite=this ; domain=test31.curl; path=/overwrite/%CR | |
| Set-Cookie: overwrite=this2 ; domain=test31.curl; path=/overwrite%CR | |
| Set-Cookie: sec1value=secure1 ; domain=test31.curl; path=/secure1/ ; secure%CR | |
| - | Set-Cookie: sec2value=secure2 ; domain=test31.curl; path=/secure2/ ; secure=%CR |
| - | Set-Cookie: sec3value=secure3 ; domain=test31.curl; path=/secure3/ ; secure=%CR |
| - | Set-Cookie: sec4value=secure4 ; secure=; domain=test31.curl; path=/secure4/ ; %CR |
| + | Set-Cookie: sec2value=secure2 ; domain=test31.curl; path=/secure2/ ; secure%CR |
| + | Set-Cookie: sec3value=secure3 ; domain=test31.curl; path=/secure3/ ; secure%CR |
| + | Set-Cookie: sec4value=secure4 ; secure; domain=test31.curl; path=/secure4/ ; %CR |
| Set-Cookie: sec5value=secure5 ; secure; domain=test31.curl; path=/secure5/ ; %CR | |
| Set-Cookie: sec6value=secure6 ; secure ; domain=test31.curl; path=/secure6/ ; %CR | |
| Set-Cookie: sec7value=secure7 ; secure ; domain=test31.curl; path=/secure7/ ; %CR | |
| - | Set-Cookie: sec8value=secure8 ; secure= ; domain=test31.curl; path=/secure8/ ; %CR |
| - | Set-Cookie: secure=very1 ; secure=; domain=test31.curl; path=/secure9/; %CR |
| + | Set-Cookie: sec8value=secure8 ; secure ; domain=test31.curl; path=/secure8/ ; %CR |
| + | Set-Cookie: secure=very1 ; secure; domain=test31.curl; path=/secure9/; %CR |
| Set-Cookie: httpo1=value1 ; domain=test31.curl; path=/p1/; httponly%CR | |
| - | Set-Cookie: httpo2=value2 ; domain=test31.curl; path=/p2/; httponly=%CR |
| + | Set-Cookie: httpo2=value2 ; domain=test31.curl; path=/p2/; httponly%CR |
| Set-Cookie: httpo3=value3 ; httponly; domain=test31.curl; path=/p3/;%CR | |
| - | Set-Cookie: httpo4=value4 ; httponly=; domain=test31.curl; path=/p4/; %CR |
| + | Set-Cookie: httpo4=value4 ; httponly; domain=test31.curl; path=/p4/; %CR |
| Set-Cookie: httponly=myvalue1 ; domain=test31.curl; path=/p4/; httponly%CR | |
| Set-Cookie: httpandsec=myvalue2 ; domain=test31.curl; path=/p4/; httponly; secure%CR | |
| - | Set-Cookie: httpandsec2=myvalue3; domain=test31.curl; path=/p4/; httponly=; secure%CR |
| - | Set-Cookie: httpandsec3=myvalue4 ; domain=test31.curl; path=/p4/; httponly; secure=%CR |
| - | Set-Cookie: httpandsec4=myvalue5 ; domain=test31.curl; path=/p4/; httponly=; secure=%CR |
| - | Set-Cookie: httpandsec5=myvalue6 ; domain=test31.curl; path=/p4/; secure; httponly=%CR |
| - | Set-Cookie: httpandsec6=myvalue7 ; domain=test31.curl; path=/p4/; secure=; httponly=%CR |
| + | Set-Cookie: httpandsec2=myvalue3; domain=test31.curl; path=/p4/; httponly; secure%CR |
| + | Set-Cookie: httpandsec3=myvalue4 ; domain=test31.curl; path=/p4/; httponly; secure%CR |
| + | Set-Cookie: httpandsec4=myvalue5 ; domain=test31.curl; path=/p4/; httponly; secure%CR |
| + | Set-Cookie: httpandsec5=myvalue6 ; domain=test31.curl; path=/p4/; secure; httponly%CR |
| + | Set-Cookie: httpandsec6=myvalue7 ; domain=test31.curl; path=/p4/; secure; httponly%CR |
| Set-Cookie: httpandsec7=myvalue8 ; domain=test31.curl; path=/p4/; secure; httponly%CR | |
| - | Set-Cookie: httpandsec8=myvalue9; domain=test31.curl; path=/p4/; secure=; httponly%CR |
| + | Set-Cookie: httpandsec8=myvalue9; domain=test31.curl; path=/p4/; secure; httponly%CR |
| Set-Cookie: partmatch=present; domain=test31.curl ; path=/;%CR | |
| Set-Cookie:eat=this; domain=moo.foo.moo;%CR | |
| Set-Cookie: eat=this-too; domain=.foo.moo;%CR | |
| @@ -67,7 +69,7 @@ Set-Cookie: partialip=nono; domain=.0.0.1;%CR | |
| Set-Cookie: withspaces= yes within and around ;%CR | |
| Set-Cookie: withspaces2 =before equals;%CR | |
| Set-Cookie: prespace= yes before;%CR | |
| - | Set-Cookie: securewithspace=after ; secure =%CR |
| + | Set-Cookie: securewithspace=after ; secure %CR |
| Set-Cookie: %hex[%c3%82%c2%b3%c3%83%5c%78%39%32%c3%83%5c%78%39%61%c3%83%5c%78%38%64%c3%83%5c%78%39%37]hex%=%96%A6g%9Ay%B0%A5g%A7tm%7C%95%9A | |
| %CR | |
| boo | |