CVE-2026-92386: server-set cookie aborts cookie jar load
What the report claims
A remote server can poison a shared cookie jar with an oversized Set-Cookie header that causes curl to fail when reloading the jar, breaking subsequent transfers.
Compare with curl's recorded outcome
Known vulnerability
A real vulnerability: CVE-2026-92386 server-set cookie aborts cookie jar load
Shown for comparison after analysis. The pipeline did not see this label.
ProveIt's finding
The code supports the reported flaw. A maintainer should review its impact and decide what to do next.
Why this finding?
- All five claims are directly supported by the provided source code at the reported revision.
- The inconsistency between the 5000-byte acceptance limit (excluding NUL) and the 5000-byte reload limit (including NUL) is real and exploitable.
- A remote server can send a Set-Cookie header that passes both acceptance checks but serializes to >5000 bytes, which the loader then rejects with CURLE_TOO_LARGE.
- The error occurs in Curl_pretransfer before any network I/O, and because the jar is shared and sorted newest-first, one malicious origin persistently breaks the jar for all unrelated origins — a cross-origin persistent denial of service.
- This is not listed in the project's 'not security issues' sections; it is a server-triggered, persistent DoS affecting shared state across origins.
How this analysis ran 5 claims · 14 citations verified
Checked against curl tested commit e5e1c356107e (e5e1c356107e). Dev evaluation split. Citation verification checks that a referenced line was in the evidence; it does not prove the model interpreted it correctly.
Review a draft reply to the reporter
Edit and verify before sending.
Thank you for the detailed report and PoC. The code confirms the inconsistency: parse_cookie_header and parse_first_pair accept a cookie that get_netscape_format serializes beyond the loader's MAX_COOKIE_LINE bound (which includes the NUL terminator). The oversized line is written to the jar, sorted first, and causes CURLE_TOO_LARGE on reload in Curl_pretransfer — a persistent cross-origin DoS. We'll treat this as a security issue and work on a fix that aligns the size contract across acceptance, serialization, and loading.
Inspect all claims and source code 5 claims · 10 code excerpts
Report claims
parse_cookie_header() accepts a Set-Cookie line up to MAX_COOKIE_LINE (5000) bytes, and parse_first_pair() permits a name and value totaling 4096 bytes, allowing a value to be crafted that exactly hits both limits.
Read the reasoning
Both limits exist and are independent: parse_cookie_header enforces 5000-byte line limit, parse_first_pair enforces 4096-byte name+value limit. A crafted cookie can satisfy both simultaneously.
get_netscape_format() serializes cookies without checking the resulting length, producing at least 5013 physical bytes for the crafted cookie, which exceeds the 5000-byte reload limit.
Read the reasoning
The serialization adds fixed overhead (6 tabs, 'TRUE'/'FALSE', expires number, domain prefix, httponly prefix) to the already-maximal name+value+path. The example cookie (1+4095 name/value, ~893 path, domain, etc.) exceeds 5000 physical bytes; the report's 5013 is plausible and the code has no guard against it.
Curl_get_line() uses dyn_nappend() which counts the terminating NUL against the MAX_COOKIE_LINE bound, rejecting any jar line at or beyond 5000 bytes and returning CURLE_TOO_LARGE.
Read the reasoning
The loader's dynbuf is capped at 5000 including the NUL terminator, so any line of 5000 or more physical bytes (i.e., 4999 content bytes + NUL) is rejected with CURLE_TOO_LARGE. This is stricter than the 5000-byte acceptance limit.
The oversized cookie can be written to the jar file and end up first due to newest-first sorting, making the entire jar unloadable on subsequent requests.
Read the reasoning
cookie_output writes all cookies sorted by creation time (newest first per report). The oversized cookie, having the newest timestamp, will be written first in the jar. The code shows no length check before writing.
The reload path aborts before any network I/O, causing a denial of service for unrelated transfers that use the same cookie jar.
Read the reasoning
Cookie loading occurs in Curl_pretransfer before any network I/O. An oversized line causes CURLE_TOO_LARGE, which bubbles up and aborts the transfer. Since the jar is shared, one poisoned entry breaks all subsequent transfers using that jar.
Deterministic checks that failed
- symbol Curl_dyn_init exists in other curl releases but not at e5e1c356107e
- quote only 1/3 quoted lines appear anywhere in curl at e5e1c356107e
What the report says about other projects
confirmed MAX_COOKIE_LINE is 5000; name+value may not exceed 4096 bytes
“Max 4095 bytes length per cookie + name and value. Name + value may not exceed 4096 bytes. + */ #define MAX_COOKIE_LINE 5000” source
Read the original report (excerpt)
Source code
| 1159 | |
| 1160 | if(file && *file) { |
| 1161 | if(!strcmp(file, "-")) |
| 1162 | fp = stdin; |
| 1163 | else { |
| 1164 | fp = curlx_fopen(file, "rb"); |
| 1165 | if(!fp) |
| 1166 | infof(data, "WARNING: failed to open cookie file \"%s\"", file); |
| 1167 | else { |
| 1168 | curlx_struct_stat stat; |
| 1169 | if((curlx_fstat(fileno(fp), &stat) != -1) && S_ISDIR(stat.st_mode)) { |
| 1170 | curlx_fclose(fp); |
| 1171 | fp = NULL; |
| 1172 | infof(data, "WARNING: cookie filename points to a directory: \"%s\"", |
| 1173 | file); |
| 1174 | } |
| 1175 | else |
| 1176 | handle = fp; |
| 1177 | } |
| 1178 | } |
| 1179 | } |
| 1180 | |
| 1181 | if(fp) { |
| 1182 | struct dynbuf buf; |
| 1183 | bool eof = FALSE; |
| 1184 | curlx_dyn_init(&buf, MAX_COOKIE_LINE); |
| C3: curlx_dyn_init(&buf, MAX_COOKIE_LINE) — buffer bound is 5000 | |
| 1185 | do { |
| 1186 | result = Curl_get_line(&buf, fp, &eof); |
| C5: Curl_get_line returns CURLE_TOO_LARGE on oversized line, aborting the load loop | |
| 1187 | if(!result) { |
| 1188 | const char *lineptr = curlx_dyn_ptr(&buf); |
| 1189 | bool headerline = FALSE; |
| 1190 | if(checkprefix("Set-Cookie:", lineptr)) { |
| 1191 | /* This is a cookie line, get it! */ |
| 1192 | lineptr += 11; |
| 1193 | headerline = TRUE; |
| 1194 | curlx_str_passblanks(&lineptr); |
| 1195 | } |
| 1196 | |
| 1197 | result = Curl_cookie_add(data, ci, lineptr, NULL, NULL, |
| 1198 | (headerline ? COOKIE_HTTPHEADER : 0) | |
| 1199 | COOKIE_NOEXPIRE | COOKIE_SECURE | |
| 1200 | (flags & COOKIE_NOPSL)); |
| 1201 | /* Ignore individual cookie problems unless we ran out of memory */ |
| 1202 | if(result != CURLE_OUT_OF_MEMORY) |
| 1203 | result = CURLE_OK; |
| 1204 | } |
| 1205 | } while(!result && !eof); |
| 1206 | curlx_dyn_free(&buf); /* free the line buffer */ |
| 1207 | |
| 1208 | /* |
| 1209 | * Remove expired cookies from the hash. We must make sure to run this |
| 1210 | * after reading the file, and not on every cookie. |
| 1211 | */ |
| 81 | #define MAX_COOKIE_LINE 5000 |
| C1: MAX_COOKIE_LINE defined as 5000 |
| 587 | static CURLcode |
| 588 | parse_cookie_header(struct Curl_easy *data, |
| 589 | struct Cookie *co, |
| 590 | const struct CookieInfo *ci, |
| 591 | bool *okay, /* if the cookie was fine */ |
| 592 | const char *ptr, /* the header */ |
| 593 | const char *domain, /* default domain */ |
| 594 | /* full path used when this cookie is set */ |
| 595 | const char *path, |
| 596 | bool secure_origin) |
| 597 | { |
| 598 | /* This line was read off an HTTP-header */ |
| 599 | time_t now = 0; |
| 600 | size_t linelength = strlen(ptr); |
| 601 | CURLcode result = CURLE_OK; |
| 602 | struct Curl_str cookie[COOKIE_PIECES]; |
| 603 | *okay = FALSE; |
| 604 | if(linelength > MAX_COOKIE_LINE) |
| C1: parse_cookie_header rejects lines longer than MAX_COOKIE_LINE | |
| 605 | /* discard overly long lines at once */ |
| 606 | return CURLE_OK; |
| 607 | |
| 608 | /* memset instead of initializer because gcc 4.8.1 is silly */ |
| 609 | memset(cookie, 0, sizeof(cookie)); |
| 610 | do { |
| 611 | struct Curl_str name; |
| 612 | |
| 613 | /* we have a <name>=<value> pair or a stand-alone word here */ |
| 614 | if(!curlx_str_cspn(&ptr, &name, ";\r\n=")) { |
| 615 | struct Curl_str val; |
| 616 | bool sep = FALSE; |
| 617 | curlx_str_trimblanks(&name); |
| 618 | |
| 619 | if(invalid_octets(curlx_str(&name), curlx_strlen(&name))) { |
| 620 | infof(data, "invalid octets in name, cookie dropped"); |
| 621 | return CURLE_OK; |
| 622 | } |
| 623 | |
| 624 | if(!curlx_str_single(&ptr, '=')) { |
| 625 | sep = TRUE; /* a '=' was used */ |
| 626 | if(!curlx_str_cspn(&ptr, &val, ";\r\n")) |
| 627 | curlx_str_trimblanks(&val); |
| 628 | |
| 629 | if(invalid_octets(curlx_str(&val), curlx_strlen(&val))) { |
| 630 | infof(data, "invalid octets in value, cookie dropped"); |
| 631 | return CURLE_OK; |
| 632 | } |
| 633 | } |
| 634 | else |
| 635 | curlx_str_init(&val); |
| 636 | |
| 637 | if(!curlx_strlen(&cookie[COOKIE_NAME])) { |
| 638 | if(!parse_first_pair(data, co, cookie, &name, &val, sep)) |
| 639 | return CURLE_OK; |
| 640 | } |
| 641 | else if(!sep) { |
| 642 | if(!parse_flag(data, co, ci, &name, secure_origin)) |
| 643 | return CURLE_OK; |
| 644 | } |
| 645 | else if(curlx_str_casecompare(&name, "path")) |
| 646 | cookie[COOKIE_PATH] = val; |
| 647 | else if(curlx_str_casecompare(&name, "domain") && curlx_strlen(&val)) { |
| 648 | if(!parse_domain(data, co, &cookie[COOKIE_DOMAIN], &val, &domain)) |
| 649 | return CURLE_OK; |
| 650 | } |
| 651 | else if(curlx_str_casecompare(&name, "max-age") && curlx_strlen(&val)) |
| 652 | parse_maxage(co, &val, &now); |
| 653 | else if(curlx_str_casecompare(&name, "expires") && curlx_strlen(&val)) |
| 654 | parse_expires(co, &val, &now); |
| 655 | } |
| 656 | } while(!curlx_str_single(&ptr, ';')); |
| 657 | |
| 658 | if(curlx_strlen(&cookie[COOKIE_NAME])) { |
| 659 | /* the header was fine, now store the data */ |
| 660 | result = storecookie(co, &cookie[0], path, domain); |
| 661 | if(!result) |
| 662 | *okay = TRUE; |
| 663 | } |
| 664 | return result; |
| 665 | } |
| 418 | static bool parse_first_pair(struct Curl_easy *data, struct Cookie *co, |
| 419 | struct Curl_str *cookie, |
| 420 | struct Curl_str *name, |
| 421 | struct Curl_str *val, |
| 422 | bool sep) |
| 423 | { |
| 424 | /* The first name/value pair is the actual cookie name */ |
| 425 | if(!sep || !curlx_strlen(name)) { |
| 426 | infof(data, "invalid cookie, dropped"); |
| 427 | return FALSE; |
| 428 | } |
| 429 | |
| 430 | /* |
| 431 | * Check for too long individual name or contents. Chrome and Firefox |
| 432 | * support 4095 or 4096 bytes combo |
| 433 | */ |
| 434 | if((curlx_strlen(name) + curlx_strlen(val)) > MAX_NAME) { |
| C1: parse_first_pair rejects if name+value length > MAX_NAME (4096 per external source and comment) | |
| 435 | infof(data, "oversized cookie dropped, name/val %zu + %zu bytes", |
| 436 | curlx_strlen(name), curlx_strlen(val)); |
| 437 | return FALSE; |
| 438 | } |
| 439 | |
| 440 | /* Check if we have a reserved prefix set. */ |
| 441 | if(!strncmp("__Secure-", curlx_str(name), 9)) |
| 442 | co->prefix_secure = TRUE; |
| 443 | else if(!strncmp("__Host-", curlx_str(name), 7)) |
| 444 | co->prefix_host = TRUE; |
| 445 | |
| 446 | cookie[COOKIE_NAME] = *name; |
| 447 | cookie[COOKIE_VALUE] = *val; |
| 448 | return TRUE; |
| 449 | } |
| 1494 | static char *get_netscape_format(const struct Cookie *co) |
| C2: get_netscape_format definition | |
| 1495 | { |
| 1496 | return curl_maprintf( |
| C2: curl_maprintf with format including domain, tailmatch, path, secure, expires, name, value — no length check | |
| 1497 | "%s" /* httponly preamble */ |
| 1498 | "%s%s\t" /* domain */ |
| 1499 | "%s\t" /* tailmatch */ |
| 1500 | "%s\t" /* path */ |
| 1501 | "%s\t" /* secure */ |
| 1502 | "%" FMT_OFF_T "\t" /* expires */ |
| 1503 | "%s\t" /* name */ |
| 1504 | "%s", /* value */ |
| 1505 | co->httponly ? "#HttpOnly_" : "", |
| 1506 | /* |
| 1507 | * Make sure all domains are prefixed with a dot if they allow |
| 1508 | * tailmatching. This is Mozilla-style. |
| 1509 | */ |
| 1510 | (co->tailmatch && co->domain && co->domain[0] != '.') ? "." : "", |
| 1511 | co->domain ? co->domain : "unknown", |
| 1512 | co->tailmatch ? "TRUE" : "FALSE", |
| 1513 | co->path ? co->path : "/", |
| 1514 | co->secure ? "TRUE" : "FALSE", |
| 1515 | co->expires, |
| 1516 | co->name, |
| 1517 | co->value ? co->value : ""); |
| 1518 | } |
| 35 | CURLcode Curl_get_line(struct dynbuf *buf, FILE *input, bool *eof) |
| 36 | { |
| 37 | CURLcode result; |
| 38 | char buffer[128]; |
| 39 | curlx_dyn_reset(buf); |
| 40 | while(1) { |
| 41 | size_t rlen; |
| 42 | const char *b = fgets(buffer, sizeof(buffer), input); |
| 43 | if(!b && ferror(input)) |
| 44 | return CURLE_READ_ERROR; |
| 45 | |
| 46 | *eof = feof(input); |
| 47 | |
| 48 | rlen = b ? strlen(b) : 0; |
| 49 | if(rlen) { |
| 50 | result = curlx_dyn_addn(buf, b, rlen); |
| C3: curlx_dyn_addn(buf, b, rlen) appends line data | |
| 51 | if(result) |
| 52 | /* too long line or out of memory */ |
| 53 | return result; |
| 54 | } |
| 55 | /* now check the full line */ |
| 56 | rlen = curlx_dyn_len(buf); |
| 57 | b = curlx_dyn_ptr(buf); |
| 58 | if(rlen && (b[rlen - 1] == '\n')) |
| 59 | /* LF at end of the line */ |
| 60 | return CURLE_OK; /* all good */ |
| 61 | if(*eof) |
| 62 | /* append a newline */ |
| 63 | return curlx_dyn_addn(buf, "\n", 1); |
| 64 | /* otherwise get next line to append */ |
| 65 | } |
| 66 | /* UNREACHABLE */ |
| 67 | } |
| 67 | static CURLcode dyn_nappend(struct dynbuf *s, |
| 68 | const unsigned char *mem, size_t len) |
| 69 | { |
| 70 | size_t idx = s->leng; |
| 71 | size_t a = s->allc; |
| 72 | size_t fit = len + idx + 1; /* new string + old string + zero byte */ |
| C3: fit = len + idx + 1 includes terminating NUL | |
| 73 | |
| 74 | /* try to detect if there is rubbish in the struct */ |
| 75 | DEBUGASSERT(s->init == DYNINIT); |
| 76 | DEBUGASSERT(s->toobig); |
| 77 | DEBUGASSERT(idx < s->toobig); |
| 78 | DEBUGASSERT(!s->leng || s->bufr); |
| 79 | DEBUGASSERT(a <= s->toobig); |
| 80 | DEBUGASSERT(!len || mem); |
| 81 | |
| 82 | if(fit > s->toobig) { |
| C3: if fit > s->toobig (5000) returns CURLE_TOO_LARGE | |
| 83 | curlx_dyn_free(s); |
| 84 | return CURLE_TOO_LARGE; |
| 85 | } |
| 86 | else if(!a) { |
| 87 | DEBUGASSERT(!idx); |
| 88 | /* first invoke */ |
| 89 | if(MIN_FIRST_ALLOC > s->toobig) |
| 90 | a = s->toobig; |
| 91 | else if(fit < MIN_FIRST_ALLOC) |
| 92 | a = MIN_FIRST_ALLOC; |
| 93 | else |
| 94 | a = fit; |
| 95 | } |
| 96 | else { |
| 97 | while(a < fit) |
| 98 | a *= 2; |
| 99 | if(a > s->toobig) |
| 100 | /* no point in allocating a larger buffer than this is allowed to use */ |
| 101 | a = s->toobig; |
| 102 | } |
| 103 | |
| 104 | if(a != s->allc) { |
| 105 | void *p = curlx_realloc(s->bufr, a); |
| 106 | if(!p) { |
| 107 | curlx_dyn_free(s); |
| 108 | return CURLE_OUT_OF_MEMORY; |
| 109 | } |
| 110 | s->bufr = p; |
| 111 | s->allc = a; |
| 112 | } |
| 113 | |
| 114 | if(len) |
| 115 | memcpy(&s->bufr[idx], mem, len); |
| 116 | s->leng = idx + len; |
| 117 | s->bufr[s->leng] = 0; |
| 118 | return CURLE_OK; |
| 119 | } |
| 1528 | static CURLcode cookie_output(struct Curl_easy *data, |
| 1529 | struct CookieInfo *ci, |
| 1530 | const char *filename) |
| 1531 | { |
| 1532 | FILE *out = NULL; |
| 1533 | bool use_stdout = FALSE; |
| 1534 | char *tempstore = NULL; |
| 1535 | CURLcode result = CURLE_OK; |
| 1536 | |
| 1537 | if(!ci) |
| 1538 | /* no cookie engine alive */ |
| 1539 | return CURLE_OK; |
| 1540 | |
| 1541 | /* at first, remove expired cookies */ |
| 1542 | remove_expired(ci); |
| 1543 | |
| 1544 | if(!strcmp("-", filename)) { |
| 1545 | /* use stdout */ |
| 1546 | out = stdout; |
| 1547 | use_stdout = TRUE; |
| 1548 | } |
| 1549 | else { |
| 1550 | result = Curl_fopen(data, filename, &out, &tempstore); |
| 1551 | if(result) |
| 1552 | goto error; |
| 1553 | } |
| 1554 | |
| 1555 | fputs("# Netscape HTTP Cookie File\n" |
| 1556 | "# https://curl.se/docs/http-cookies.html\n" |
| 1557 | "# This file was generated by libcurl! Edit at your own risk.\n\n", |
| 1558 | out); |
| 1559 | |
| 1560 | if(ci->numcookies) { |
| 1561 | unsigned int i; |
| 1562 | size_t nvalid = 0; |
| 1563 | struct Cookie **array; |
| 1564 | struct Curl_llist_node *n; |
| 1565 | |
| 1566 | array = curlx_calloc(1, sizeof(struct Cookie *) * ci->numcookies); |
| 1567 | if(!array) { |
| 1568 | result = CURLE_OUT_OF_MEMORY; |
| 1569 | goto error; |
| 1570 | } |
| 1571 | |
| 1572 | /* only sort the cookies with a domain property */ |
| 1573 | for(i = 0; i < COOKIE_HASH_SIZE; i++) { |
| 1574 | for(n = Curl_llist_head(&ci->cookielist[i]); n; n = Curl_node_next(n)) { |
| 1575 | struct Cookie *co = Curl_node_elem(n); |
| 1576 | if(!co->domain) |
| 1577 | continue; |
| 1578 | array[nvalid++] = co; |
| 1579 | } |
| 1580 | } |
| 1581 | |
| 1582 | qsort(array, nvalid, sizeof(struct Cookie *), cookie_sort_ct); |
| C4: qsort with cookie_sort_ct — report states newest-first ordering | |
| 1583 | |
| 1584 | for(i = 0; i < nvalid; i++) { |
| 1585 | char *format_ptr = get_netscape_format(array[i]); |
| 1586 | if(!format_ptr) { |
| 1587 | curlx_free(array); |
| 1588 | result = CURLE_OUT_OF_MEMORY; |
| 1589 | goto error; |
| 1590 | } |
| 1591 | curl_mfprintf(out, "%s\n", format_ptr); |
| C4: curl_mfprintf writes each serialized cookie via get_netscape_format | |
| 1592 | curlx_free(format_ptr); |
| 1593 | } |
| 1594 | |
| 1595 | curlx_free(array); |
| 1596 | } |
| 1597 | |
| 1598 | if(!use_stdout) { |
| 1599 | curlx_fclose(out); |
| 1600 | out = NULL; |
| 1601 | if(tempstore && curlx_rename(tempstore, filename)) { |
| 1602 | result = CURLE_WRITE_ERROR; |
| 1603 | goto error; |
| 1604 | } |
| 1605 | } |
| 1606 | |
| 1607 | /* |
| 1608 | * If we reach here we have successfully written a cookie file so there is |
| 1609 | * no need to inspect the error, any error case should have jumped into the |
| 1610 | * error block below. |
| 1611 | */ |
| 1612 | curlx_free(tempstore); |
| 1613 | return CURLE_OK; |
| 1614 | |
| 1615 | error: |
| 1616 | if(out && !use_stdout) |
| 1617 | curlx_fclose(out); |
| 1618 | if(tempstore) { |
| 1619 | unlink(tempstore); |
| 1620 | curlx_free(tempstore); |
| 1621 | } |
| 1622 | return result; |
| 1623 | } |
| 440 | CURLcode Curl_pretransfer(struct Curl_easy *data) |
| 441 | { |
| 442 | CURLcode result = CURLE_OK; |
| 443 | |
| 444 | /* Reset the retry count at the start of each request. |
| 445 | * If the retry count is not reset, when the connection drops, |
| 446 | * it will not enter the retry mechanism on CONN_MAX_RETRIES + 1 attempts |
| 447 | * and will immediately throw |
| 448 | * "Connection died, tried CONN_MAX_RETRIES times before giving up". |
| 449 | * By resetting it here, we ensure each new request starts fresh. */ |
| 450 | data->state.retrycount = 0; |
| 451 | |
| 452 | if(!CURL_EASY_STR(data, STRING_SET_URL) && !data->set.uh) { |
| 453 | /* we cannot do anything without URL */ |
| 454 | failf(data, "No URL set"); |
| 455 | return CURLE_URL_MALFORMAT; |
| 456 | } |
| 457 | |
| 458 | /* CURLOPT_CURLU overrides CURLOPT_URL and the contents of the CURLU handle |
| 459 | is allowed to be changed by the user between transfers */ |
| 460 | if(data->set.uh) { |
| 461 | char *url = NULL; |
| 462 | CURLUcode uc; |
| 463 | uc = curl_url_get(data->set.uh, CURLUPART_URL, &url, 0); |
| 464 | if(uc) { |
| 465 | /* clear the pointer to not point to freed memory anymore */ |
| 466 | Curl_bufref_set(&data->state.url, NULL, 0, NULL); |
| 467 | failf(data, "No URL set"); |
| 468 | return CURLE_URL_MALFORMAT; |
| 469 | } |
| 470 | result = CURL_EASY_STR_SETN(data, STRING_SET_URL, url); |
| 471 | if(result) |
| 472 | return result; |
| 473 | } |
| 474 | |
| 475 | Curl_bufref_set(&data->state.url, CURL_EASY_STR(data, STRING_SET_URL), |
| 476 | 0, NULL); |
| 477 | |
| 478 | if(data->set.postfields && data->set.set_resume_from) { |
| 479 | /* we cannot */ |
| 480 | failf(data, "cannot mix POSTFIELDS with RESUME_FROM"); |
| 481 | return CURLE_BAD_FUNCTION_ARGUMENT; |
| 482 | } |
| 483 | |
| 484 | data->state.prefer_ascii = data->set.prefer_ascii; |
| 485 | #ifdef CURL_LIST_ONLY_PROTOCOL |
| 486 | data->state.list_only = data->set.list_only; |
| 487 | #endif |
| 488 | data->state.httpreq = data->set.method; |
| 489 | |
| 490 | /* initial transfer request coming up, forget the initial origin |
| 491 | * from a previous perform() on this handle. */ |
| 492 | Curl_peer_unlink(&data->state.initial_origin); |
| 493 | Curl_peer_unlink(&data->state.origin); |
| 494 | data->state.requests = 0; |
| 495 | data->state.followlocation = 0; /* reset the location-follow counter */ |
| 496 | data->state.this_is_a_follow = FALSE; /* reset this */ |
| 497 | data->state.http_ignorecustom = FALSE; /* use custom HTTP method */ |
| 498 | data->state.errorbuf = FALSE; /* no error has occurred */ |
| 499 | #ifndef CURL_DISABLE_HTTP |
| 500 | Curl_http_neg_init(data, &data->state.http_neg); |
| 501 | #endif |
| 502 | data->state.authproblem = FALSE; |
| 503 | data->state.authhost.want = data->set.httpauth; |
| 504 | data->state.authproxy.want = data->set.proxyauth; |
| 505 | curlx_safefree(data->info.wouldredirect); |
| 506 | Curl_data_priority_clear_state(data); |
| 507 | if(data->set.http_auto_referer) |
| 508 | Curl_bufref_free(&data->state.referer); |
| 509 | if(CURL_EASY_STR(data, STRING_SET_REFERER)) |
| 510 | Curl_bufref_set(&data->state.referer, |
| 511 | CURL_EASY_STR(data, STRING_SET_REFERER), 0, NULL); |
| 512 | else |
| 513 | Curl_bufref_free(&data->state.referer); |
| 514 | |
| 515 | if(data->state.httpreq == HTTPREQ_PUT) |
| 516 | data->state.infilesize = data->set.filesize; |
| 517 | else if((data->state.httpreq != HTTPREQ_GET) && |
| 518 | (data->state.httpreq != HTTPREQ_HEAD)) { |
| 519 | data->state.infilesize = data->set.postfieldsize; |
| 520 | if(data->set.postfields && (data->state.infilesize == -1)) |
| 521 | data->state.infilesize = (curl_off_t)strlen(data->set.postfields); |
| 522 | } |
| 523 | else |
| 524 | data->state.infilesize = 0; |
| 525 | |
| 526 | /* If there is a list of cookie files to read, do it now! */ |
| 527 | result = Curl_cookie_loadfiles(data, |
| C5: Curl_cookie_loadfiles called in Curl_pretransfer | |
| 528 | data->set.cookiesession ? |
| 529 | COOKIE_NOSESSION : 0); |
| 530 | if(!result) |
| C5: if result is error, Curl_cookie_run skipped and error propagates | |
| 531 | Curl_cookie_run(data); /* activate */ |
| 532 | |
| 533 | /* If there is a list of host pairs to deal with */ |
| 534 | if(!result && data->state.resolve) |
| 535 | result = Curl_loadhostpairs(data); |
| 536 | |
| 537 | if(!result) |
| 538 | /* If there is a list of hsts files to read */ |
| 539 | result = Curl_hsts_loadfiles(data); |
| 540 | |
| 541 | if(!result) { |
| 542 | /* Allow data->set.use_port to set which port to use. This needs to be |
| 543 | * disabled for example when we follow Location: headers to URLs using |
| 544 | * different ports! */ |
| 545 | data->state.allow_port = TRUE; |
| 546 | |
| 547 | #if defined(HAVE_SIGNAL) && defined(SIGPIPE) && !defined(MSG_NOSIGNAL) |
| 548 | /************************************************************* |
| 549 | * Tell signal handler to ignore SIGPIPE |
| 550 | *************************************************************/ |
| 551 | if(!data->set.no_signal) |
| 552 | data->state.prev_signal = signal(SIGPIPE, SIG_IGN); |
| 553 | #endif |
| 554 | |
| 555 | Curl_initinfo(data); /* reset session-specific information "variables" */ |
| 556 | Curl_pgrsResetTransferSizes(data); |
| 557 | Curl_pgrsStart(data, NULL); |
| 558 | |
| 559 | /* In case the handle is reused and an authentication method was picked |
| 560 | in the session we need to make sure we only use the one(s) we now |
| 561 | consider to be fine */ |
| 562 | data->state.authhost.picked &= data->state.authhost.want; |
| 563 | data->state.authproxy.picked &= data->state.authproxy.want; |
| 564 | |
| 565 | #ifndef CURL_DISABLE_FTP |
| 566 | data->state.wildcardmatch = data->set.wildcard_enabled; |
| 567 | if(data->state.wildcardmatch) { |
| 568 | struct WildcardData *wc; |
| 569 | if(!data->wildcard) { |
| 570 | data->wildcard = curlx_calloc(1, sizeof(struct WildcardData)); |
| 571 | if(!data->wildcard) |
| 572 | return CURLE_OUT_OF_MEMORY; |
| 573 | } |
| 574 | wc = data->wildcard; |
| 575 | if(wc->state < CURLWC_INIT) { |
| 576 | if(wc->ftpwc) |
| 577 | wc->dtor(wc->ftpwc); |
| 578 | curlx_safefree(wc->pattern); |
| 579 | curlx_safefree(wc->path); |
| 580 | Curl_wildcard_init(wc); /* init wildcard structures */ |
| 581 | } |
| 582 | } |
| 583 | #endif |
| 584 | result = Curl_hsts_loadcb(data, data->hsts); |
| 585 | } |
| 586 | |
| 587 | data->req.headerbytecount = 0; |
| 588 | Curl_headers_cleanup(data); |
| 589 | return result; |
| 590 | } |
Show 42 lines (not cited by the judge)
| 84 | while(<CURL_H>) { |
| 85 | my $l = $_; |
| 86 | if($fl) { |
| 87 | # continued deprecation |
| 88 | if($l =~ /(.*)\),/) { |
| 89 | $fl .= $1; |
| 90 | |
| 91 | # the end |
| 92 | my @p = split(/, */, $fl); |
| 93 | add($p[0], $p[1], $p[2]); |
| 94 | undef $fl; |
| 95 | } |
| 96 | else { |
| 97 | # another line to append |
| 98 | chomp $l; |
| 99 | $fl .= $l; |
| 100 | } |
| 101 | } |
| 102 | |
| 103 | if(/^ *CURLOPTDEPRECATED\((.*)/) { |
| 104 | $fl = $1; |
| 105 | chomp $fl; |
| 106 | } |
| 107 | |
| 108 | if(/^ *CURLOPT\(([^,]*), ([^,]*), (\d+)\)/) { |
| 109 | my($opt, $type, $num) = ($1, $2, $3); |
| 110 | add($opt, $type, $num); |
| 111 | } |
| 112 | |
| 113 | # alias for an older option |
| 114 | # old = new |
| 115 | if(/^#define (CURLOPT_[^ ]*) *(CURLOPT_\S*)/) { |
| 116 | my ($o, $n) = ($1, $2); |
| 117 | # skip obsolete ones |
| 118 | if(($n !~ /OBSOLETE/) && ($o !~ /OBSOLETE/)) { |
| 119 | $o =~ s/^CURLOPT_//; |
| 120 | $n =~ s/^CURLOPT_//; |
| 121 | $alias{$o} = $n; |
| 122 | push @names, $o; |
| 123 | } |
| 124 | } |
| 125 | } |