Instead of keeping both versions around.
Closes #19864
{
curlx_free(co->domain);
curlx_free(co->path);
- curlx_free(co->spath);
curlx_free(co->name);
curlx_free(co->value);
if(maintoo)
/*
* cookie path sanitize
*/
-static char *sanitize_cookie_path(const char *cookie_path)
+static char *sanitize_cookie_path(const char *cookie_path, size_t len)
{
- size_t len = strlen(cookie_path);
-
/* some sites send path attribute within '"'. */
- if(cookie_path[0] == '\"') {
+ if(len && (cookie_path[0] == '\"')) {
cookie_path++;
len--;
+
+ if(len && (cookie_path[len - 1] == '\"'))
+ len--;
}
- if(len && (cookie_path[len - 1] == '\"'))
- len--;
/* RFC6265 5.2.4 The Path Attribute */
- if(cookie_path[0] != '/')
+ if(!len || (cookie_path[0] != '/'))
/* Let cookie-path be the default-path. */
return curlx_strdup("/");
result = strstore(&co->value, curlx_str(&cp[COOKIE_VALUE]),
curlx_strlen(&cp[COOKIE_VALUE]));
if(!result) {
- if(curlx_strlen(&cp[COOKIE_PATH]))
- result = strstore(&co->path, curlx_str(&cp[COOKIE_PATH]),
- curlx_strlen(&cp[COOKIE_PATH]));
+ size_t plen = 0;
+ if(curlx_strlen(&cp[COOKIE_PATH])) {
+ path = curlx_str(&cp[COOKIE_PATH]);
+ plen = curlx_strlen(&cp[COOKIE_PATH]);
+ }
else if(path) {
/* No path was given in the header line, set the default */
const char *endslash = strrchr(path, '/');
- if(endslash) {
- size_t pathlen = (endslash - path + 1); /* include end slash */
- co->path = Curl_memdup0(path, pathlen);
- if(!co->path)
- result = CURLE_OUT_OF_MEMORY;
- }
+ if(endslash)
+ plen = (endslash - path + 1); /* include end slash */
+ else
+ plen = strlen(path);
}
- if(!result && co->path) {
- co->spath = sanitize_cookie_path(co->path);
- if(!co->spath)
+ if(path) {
+ co->path = sanitize_cookie_path(path, plen);
+ if(!co->path)
result = CURLE_OUT_OF_MEMORY;
}
}
/* The file format allows the path field to remain not filled in */
if(strncmp("TRUE", ptr, len) && strncmp("FALSE", ptr, len)) {
/* only if the path does not look like a boolean option! */
- co->path = Curl_memdup0(ptr, len);
+ co->path = sanitize_cookie_path(ptr, len);
if(!co->path)
return CURLE_OUT_OF_MEMORY;
- else {
- co->spath = sanitize_cookie_path(co->path);
- if(!co->spath)
- return CURLE_OUT_OF_MEMORY;
- }
break;
}
- /* this does not look like a path, make one up! */
- co->path = curlx_strdup("/");
- if(!co->path)
- return CURLE_OUT_OF_MEMORY;
- co->spath = curlx_strdup("/");
- if(!co->spath)
- return CURLE_OUT_OF_MEMORY;
+ else {
+ /* this does not look like a path, make one up! */
+ co->path = curlx_strdup("/");
+ if(!co->path)
+ return CURLE_OUT_OF_MEMORY;
+ }
fields++; /* add a field and fall down to secure */
FALLTHROUGH();
case 3:
matching_domains = TRUE;
if(matching_domains && /* the domains were identical */
- clist->spath && co->spath && /* both have paths */
+ clist->path && co->path && /* both have paths */
clist->secure && !co->secure && !secure) {
size_t cllen;
const char *sep = NULL;
* "/loginhelper" is ok.
*/
- DEBUGASSERT(clist->spath[0]);
- if(clist->spath[0])
- sep = strchr(clist->spath + 1, '/');
+ DEBUGASSERT(clist->path[0]);
+ if(clist->path[0])
+ sep = strchr(clist->path + 1, '/');
if(sep)
- cllen = sep - clist->spath;
+ cllen = sep - clist->path;
else
- cllen = strlen(clist->spath);
+ cllen = strlen(clist->path);
- if(curl_strnequal(clist->spath, co->spath, cllen)) {
+ if(curl_strnequal(clist->path, co->path, cllen)) {
infof(data, "cookie '%s' for domain '%s' dropped, would "
"overlay an existing cookie", co->name, co->domain);
return FALSE;
if(replace_old) {
/* the domains were identical */
- if(clist->spath && co->spath &&
- !curl_strequal(clist->spath, co->spath))
+ if(clist->path && co->path &&
+ !curl_strequal(clist->path, co->path))
replace_old = FALSE;
- else if(!clist->spath != !co->spath)
+ else if(!clist->path != !co->path)
replace_old = FALSE;
}
* The __Host- prefix requires the cookie to be secure, have a "/" path
* and not have a domain set.
*/
- if(co->secure && co->path && strcmp(co->path, "/") == 0 && !co->tailmatch)
+ if(co->secure && co->path && !strcmp(co->path, "/") && !co->tailmatch)
;
else
goto fail;
* now check the left part of the path with the cookies path
* requirement
*/
- if(!co->spath || pathmatch(co->spath, path)) {
+ if(!co->path || pathmatch(co->path, path)) {
/*
* This is a match and we add it to the return-linked-list
struct Curl_llist_node getnode; /* for getlist */
char *name; /* <this> = value */
char *value; /* name = <this> */
- char *path; /* path = <this> which is in Set-Cookie: */
- char *spath; /* sanitized cookie path */
+ char *path; /* canonical path */
char *domain; /* domain = <this> */
curl_off_t expires; /* expires = <this> */
unsigned int creationtime; /* time when the cookie was written */
# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
-127.0.0.1 FALSE "/silly/" FALSE 0 mismatch this
-127.0.0.1 FALSE /we/want/ FALSE 0 foobar name
+127.0.0.1 FALSE /silly FALSE 0 mismatch this
+127.0.0.1 FALSE /we/want FALSE 0 foobar name
</file>
</verify>
</testcase>
www.example.com FALSE / TRUE 0 __Host-SID 12346
.example.com TRUE / TRUE 0 supersupersuper secret
.example.com TRUE / TRUE 0 __SecURE-SID 12346
-.example.com TRUE /%TESTNUMBER/login/ TRUE 0 supersuper secret
+.example.com TRUE /%TESTNUMBER/login TRUE 0 supersuper secret
.example.com TRUE /1561 TRUE 0 super secret
</file>
# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
-%HOSTIP FALSE /we/want/ FALSE 0 foobar name
-%HOSTIP FALSE /we/want/ FALSE 0 secondcookie present
+%HOSTIP FALSE /we/want FALSE 0 foobar name
+%HOSTIP FALSE /we/want FALSE 0 secondcookie present
</file>
</verify>
</testcase>
# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
-%HOSTIP FALSE /we/want/ FALSE 0 secondcookie present
-%HOSTIP FALSE /we/want/ FALSE 0 foobar name
+%HOSTIP FALSE /we/want FALSE 0 secondcookie present
+%HOSTIP FALSE /we/want FALSE 0 foobar name
</file>
</verify>
</testcase>
# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
-test31.curl FALSE /we/want/ FALSE 0 %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
-test31.curl FALSE /we/want/ FALSE 0 prespace yes before
-test31.curl FALSE /we/want/ FALSE 0 withspaces2 before equals
-test31.curl FALSE /we/want/ FALSE 0 withspaces yes within and around
-.test31.curl TRUE /we/want/ FALSE 0 blexp yesyes
-#HttpOnly_test31.curl FALSE /silly/ FALSE 0 magic yessir
-test31.curl FALSE /we/want/ FALSE %days[400] nodomain value
+test31.curl FALSE /we/want FALSE 0 %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
+test31.curl FALSE /we/want FALSE 0 prespace yes before
+test31.curl FALSE /we/want FALSE 0 withspaces2 before equals
+test31.curl FALSE /we/want FALSE 0 withspaces yes within and around
+.test31.curl TRUE /we/want FALSE 0 blexp yesyes
+#HttpOnly_test31.curl FALSE /silly FALSE 0 magic yessir
+test31.curl FALSE /we/want FALSE %days[400] nodomain value
.test31.curl TRUE / FALSE 0 partmatch present
-#HttpOnly_.test31.curl TRUE /p4/ FALSE 0 httponly myvalue1
-#HttpOnly_.test31.curl TRUE /p4/ FALSE 0 httpo4 value4
-#HttpOnly_.test31.curl TRUE /p3/ FALSE 0 httpo3 value3
-#HttpOnly_.test31.curl TRUE /p2/ FALSE 0 httpo2 value2
-#HttpOnly_.test31.curl TRUE /p1/ FALSE 0 httpo1 value1
+#HttpOnly_.test31.curl TRUE /p4 FALSE 0 httponly myvalue1
+#HttpOnly_.test31.curl TRUE /p4 FALSE 0 httpo4 value4
+#HttpOnly_.test31.curl TRUE /p3 FALSE 0 httpo3 value3
+#HttpOnly_.test31.curl TRUE /p2 FALSE 0 httpo2 value2
+#HttpOnly_.test31.curl TRUE /p1 FALSE 0 httpo1 value1
.test31.curl TRUE /overwrite FALSE 0 overwrite this2
-.test31.curl TRUE /silly/ FALSE 0 ISMATCH this
-.test31.curl TRUE /silly/ FALSE 0 ismatch this
+.test31.curl TRUE /silly FALSE 0 ISMATCH this
+.test31.curl TRUE /silly FALSE 0 ismatch this
test31.curl FALSE / FALSE 0 blankdomain sure
</file>
</verify>
#HttpOnly_%HOSTIP FALSE /func_test FALSE 21709598616 mycookie5 990
#HttpOnly_%HOSTIP FALSE /func_test FALSE 21709598616 mycookie4 950
#HttpOnly_%HOSTIP FALSE /func_test FALSE 21709598616 mycookie3 900
-#HttpOnly_%HOSTIP FALSE /func_test/ FALSE 21709598616 mycookie2 5900
+#HttpOnly_%HOSTIP FALSE /func_test FALSE 21709598616 mycookie2 5900
#HttpOnly_%HOSTIP FALSE / FALSE 21709598616 mycookie1 4900
-#HttpOnly_%HOSTIP FALSE /func_test/ FALSE 0 mycookie 1200
+#HttpOnly_%HOSTIP FALSE /func_test FALSE 0 mycookie 1200
</file>
<features>
cookies
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
-Cookie: mycookie2=5900; mycookie=1200; mycookie3=900; mycookie4=950; mycookie5=990; mycookie6=991; mycookie1=4900
+Cookie: mycookie2=5900; mycookie3=900; mycookie4=950; mycookie5=990; mycookie6=991; mycookie=1200; mycookie1=4900
</protocol>
<file name="%LOGDIR/save%TESTNUMBER" mode="text">
# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
-#HttpOnly_127.0.0.1 FALSE /func_test/ FALSE 21709598616 mycookie2 5900
+#HttpOnly_127.0.0.1 FALSE /func_test FALSE 21709598616 mycookie2 5900
</file>
</verify>
</testcase>
# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
-attack.invalid FALSE /a/b/ FALSE 0 cookie-50 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-49 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-48 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-47 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-46 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-45 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-44 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-43 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-42 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-41 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-40 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-39 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-38 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-37 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-36 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-35 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-34 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-33 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-32 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-31 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-30 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-29 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-28 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-27 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-26 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-25 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-24 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-23 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-22 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-21 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-20 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-19 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-18 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-17 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-16 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-15 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-14 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-13 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-12 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-11 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-10 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-9 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-8 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-7 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-6 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-5 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-4 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-3 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-2 yes
-attack.invalid FALSE /a/b/ FALSE 0 cookie-1 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-50 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-49 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-48 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-47 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-46 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-45 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-44 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-43 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-42 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-41 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-40 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-39 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-38 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-37 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-36 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-35 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-34 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-33 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-32 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-31 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-30 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-29 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-28 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-27 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-26 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-25 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-24 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-23 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-22 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-21 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-20 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-19 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-18 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-17 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-16 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-15 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-14 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-13 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-12 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-11 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-10 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-9 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-8 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-7 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-6 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-5 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-4 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-3 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-2 yes
+attack.invalid FALSE /a/b FALSE 0 cookie-1 yes
</file>
</verify>
</testcase>
# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
-domain..tld FALSE /want/ FALSE 0 simplyhuge %repeat[3998 x z]%
+domain..tld FALSE /want FALSE 0 simplyhuge %repeat[3998 x z]%
domain..tld FALSE / FALSE 0 justaname%TAB
domain..tld FALSE / FALSE 0 ASPSESSIONIDQGGQQSJJ GKNBDIFAAOFDPDAIEAKDIBKE
domain..tld FALSE / FALSE 0 ckySession temporary
# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
-.host.foo.com TRUE /we/want/ FALSE %days[400] test2 yes
-#HttpOnly_.foo.com TRUE /we/want/ FALSE %days[400] test yes
+.host.foo.com TRUE /we/want FALSE %days[400] test2 yes
+#HttpOnly_.foo.com TRUE /we/want FALSE %days[400] test yes
</file>
</verify>
</testcase>