From 8c285a76ee3afcd493c7827049bdc43a9fd9a97f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 15 Sep 2023 09:17:34 +0200 Subject: [PATCH] cookie: do not store the expire or max-age strings Convert it to an expire time at once and save memory. Closes #11862 --- lib/cookie.c | 101 +++++++++++++++++++++++---------------------------- lib/cookie.h | 2 - 2 files changed, 45 insertions(+), 58 deletions(-) diff --git a/lib/cookie.c b/lib/cookie.c index e39c89a94a..4bbbf4471a 100644 --- a/lib/cookie.c +++ b/lib/cookie.c @@ -112,13 +112,11 @@ static void strstore(char **str, const char *newstr, size_t len); static void freecookie(struct Cookie *co) { - free(co->expirestr); free(co->domain); free(co->path); free(co->spath); free(co->name); free(co->value); - free(co->maxage); free(co); } @@ -729,17 +727,55 @@ Curl_cookie_add(struct Curl_easy *data, * client should discard the cookie. A value of zero means the * cookie should be discarded immediately. */ - strstore(&co->maxage, valuep, vlen); - if(!co->maxage) { - badcookie = TRUE; + CURLofft offt; + const char *maxage = valuep; + offt = curlx_strtoofft((*maxage == '\"')? + &maxage[1]:&maxage[0], NULL, 10, + &co->expires); + switch(offt) { + case CURL_OFFT_FLOW: + /* overflow, used max value */ + co->expires = CURL_OFF_T_MAX; + break; + case CURL_OFFT_INVAL: + /* negative or otherwise bad, expire */ + co->expires = 1; + break; + case CURL_OFFT_OK: + if(!co->expires) + /* already expired */ + co->expires = 1; + else if(CURL_OFF_T_MAX - now < co->expires) + /* would overflow */ + co->expires = CURL_OFF_T_MAX; + else + co->expires += now; break; } } else if((nlen == 7) && strncasecompare("expires", namep, 7)) { - strstore(&co->expirestr, valuep, vlen); - if(!co->expirestr) { - badcookie = TRUE; - break; + char date[128]; + if(!co->expires && (vlen < sizeof(date))) { + /* copy the date so that it can be null terminated */ + memcpy(date, valuep, vlen); + date[vlen] = 0; + /* + * Let max-age have priority. + * + * If the date cannot get parsed for whatever reason, the cookie + * will be treated as a session cookie + */ + co->expires = Curl_getdate_capped(date); + + /* + * Session cookies have expires set to 0 so if we get that back + * from the date parser let's add a second to make it a + * non-session cookie + */ + if(co->expires == 0) + co->expires = 1; + else if(co->expires < 0) + co->expires = 0; } } @@ -759,49 +795,6 @@ Curl_cookie_add(struct Curl_easy *data, break; } while(1); - if(co->maxage) { - CURLofft offt; - offt = curlx_strtoofft((*co->maxage == '\"')? - &co->maxage[1]:&co->maxage[0], NULL, 10, - &co->expires); - switch(offt) { - case CURL_OFFT_FLOW: - /* overflow, used max value */ - co->expires = CURL_OFF_T_MAX; - break; - case CURL_OFFT_INVAL: - /* negative or otherwise bad, expire */ - co->expires = 1; - break; - case CURL_OFFT_OK: - if(!co->expires) - /* already expired */ - co->expires = 1; - else if(CURL_OFF_T_MAX - now < co->expires) - /* would overflow */ - co->expires = CURL_OFF_T_MAX; - else - co->expires += now; - break; - } - } - else if(co->expirestr) { - /* - * Note that if the date couldn't get parsed for whatever reason, the - * cookie will be treated as a session cookie - */ - co->expires = Curl_getdate_capped(co->expirestr); - - /* - * Session cookies have expires set to 0 so if we get that back from the - * date parser let's add a second to make it a non-session cookie - */ - if(co->expires == 0) - co->expires = 1; - else if(co->expires < 0) - co->expires = 0; - } - if(!badcookie && !co->domain) { if(domain) { /* no domain was given in the header line, set the default */ @@ -1154,8 +1147,6 @@ Curl_cookie_add(struct Curl_easy *data, free(clist->domain); free(clist->path); free(clist->spath); - free(clist->expirestr); - free(clist->maxage); *clist = *co; /* then store all the new data */ @@ -1362,13 +1353,11 @@ static struct Cookie *dup_cookie(struct Cookie *src) { struct Cookie *d = calloc(sizeof(struct Cookie), 1); if(d) { - CLONE(expirestr); CLONE(domain); CLONE(path); CLONE(spath); CLONE(name); CLONE(value); - CLONE(maxage); d->expires = src->expires; d->tailmatch = src->tailmatch; d->secure = src->secure; diff --git a/lib/cookie.h b/lib/cookie.h index 41e9e7a691..240c054f5d 100644 --- a/lib/cookie.h +++ b/lib/cookie.h @@ -35,8 +35,6 @@ struct Cookie { char *spath; /* sanitized cookie path */ char *domain; /* domain = */ curl_off_t expires; /* expires = */ - char *expirestr; /* the plain text version */ - char *maxage; /* Max-Age = */ bool tailmatch; /* whether we do tail-matching of the domain name */ bool secure; /* whether the 'secure' keyword was used */ bool livecookie; /* updated from a server, not a stored file */