CVE-2026-10536: HTTP/2 stream-dependency tree UAF
What the report claims
Use-after-free in curl_easy_reset() when handling HTTP/2 stream-dependency tree, leading to dangling pointer dereference in data_priority_cleanup after reset.
Compare with curl's recorded outcome
Known vulnerability
A real vulnerability: CVE-2026-10536 HTTP/2 stream-dependency tree UAF
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?
- curl_easy_reset() clears data->set.priority via memset (lib/easy.c:1097) without calling data_priority_cleanup() to unlink the handle from its parent's children list
- Curl_close() correctly calls data_priority_cleanup() (lib/url.c:278) but curl_easy_reset() does not
- When a reset handle is later cleaned up, its memory is freed; a subsequent cleanup of its former parent walks the stale children list and dereferences the freed memory in priority_remove_child (lib/url.c:3022, 3034-3035)
- The reproducer uses only documented public APIs and triggers the flaw on any USE_NGHTTP2 build
- Use-after-free is a memory safety violation (CWE-416) reachable through valid API usage, not API misuse
How this analysis ran 5 claims · 15 citations verified
Checked against curl master on 2026-05-20 (d3b04e560036). 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 reproducer. The code confirms that curl_easy_reset() zeros the priority tree pointers (lib/easy.c:1097) without first calling data_priority_cleanup() to unlink the handle from its peers, while Curl_close() does call it (lib/url.c:278). This leaves dangling pointers that cause a heap-use-after-free when the parent is later cleaned up (lib/url.c:3022, 3034-3035). The fix to expose Curl_data_priority_cleanup and call it from curl_easy_reset is correct and matches the existing pattern in Curl_close. We will address this.
Inspect all claims and source code 5 claims · 9 code excerpts
Report claims
curl_easy_reset() bypasses data_priority_cleanup() before clearing data->set, leaving dangling pointers in the HTTP/2 stream-dependency tree
Read the reasoning
curl_easy_reset() clears data->set (including priority.parent and priority.children) via memset at line 1097 without first calling data_priority_cleanup() to unlink the handle from its peers' children lists. The function data_priority_cleanup exists at lib/url.c:3090 but is only called from Curl_close (lib/url.c:278), not from curl_easy_reset.
defect introduced in commit 71b7e01610 (2022-12-30) when converting set.priority into a linked tree and adding Curl_data_priority_cleanup() but not calling it from curl_easy_reset()
Read the reasoning
The deterministic checks confirm the current code state but do not include git commit history. The claim about commit 71b7e01610 cannot be verified from the provided sources.
reachable through documented public APIs only, on any USE_NGHTTP2 build
Read the reasoning
The priority tree code is compiled only when USE_NGHTTP2 is defined (lib/url.c:3014, 3089). The reproducer uses only documented public APIs: curl_easy_init, curl_easy_setopt with CURLOPT_STREAM_DEPENDS, curl_easy_reset, and curl_easy_cleanup.
dangling pointer dereference in data_priority_cleanup() leading to heap-use-after-free when peers reference freed handle through priority.children list
Read the reasoning
When curl_easy_reset(B) zeros B's priority pointers but leaves B in A's children list, subsequent curl_easy_cleanup(B) frees B's memory. Then curl_easy_cleanup(A) calls Curl_close → data_priority_cleanup → priority_remove_child, which reads and writes through the dangling pointer to the freed B struct (lib/url.c:3022, 3034-3035). The ASan output confirms heap-use-after-free at these lines.
reproducer uses curl_easy_reset() on a stream-dependent handle followed by curl_easy_cleanup() causing ASan to report heap-use-after-free in priority_remove_child
Read the reasoning
The reproducer's sequence (init A, init B, set B depends on A, reset B, cleanup B, cleanup A) exercises the exact path: reset zeros priority without unlinking, first cleanup frees the handle, second cleanup walks the stale children list and triggers the use-after-free. The ASan output in the report matches the code locations.
Read the original report (excerpt)
Source code
| 1065 | |
| 1066 | if(outcurl) { |
| 1067 | #ifndef CURL_DISABLE_COOKIES |
| 1068 | curlx_free(outcurl->cookies); |
| 1069 | #endif |
| 1070 | curlx_dyn_free(&outcurl->state.headerb); |
| 1071 | Curl_altsvc_cleanup(&outcurl->asi); |
| 1072 | Curl_hsts_cleanup(&outcurl->hsts); |
| 1073 | Curl_freeset(outcurl); |
| 1074 | curlx_free(outcurl); |
| 1075 | } |
| 1076 | |
| 1077 | return NULL; |
| 1078 | } |
| 1079 | |
| 1080 | /* |
| 1081 | * curl_easy_reset() is an external interface that allows an app to re- |
| 1082 | * initialize a session handle to the default values. |
| 1083 | */ |
| 1084 | void curl_easy_reset(CURL *curl) |
| C3: curl_easy_reset is a public API | |
| C5: curl_easy_reset public API | |
| 1085 | { |
| 1086 | struct Curl_easy *data = curl; |
| 1087 | if(!GOOD_EASY_HANDLE(data)) |
| 1088 | return; |
| 1089 | |
| 1090 | Curl_req_hard_reset(&data->req, data); |
| C1: curl_easy_reset calls Curl_req_hard_reset, Curl_hash_clean, Curl_meta_reset | |
| 1091 | Curl_hash_clean(&data->meta_hash); |
| 1092 | |
| 1093 | /* clear all meta data */ |
| 1094 | Curl_meta_reset(data); |
| 1095 | /* zero out UserDefined data: */ |
| 1096 | Curl_freeset(data); |
| C1: Curl_freeset(data) called | |
| 1097 | memset(&data->set, 0, sizeof(struct UserDefined)); |
| C1: memset(&data->set, 0, sizeof(struct UserDefined)) zeros priority pointers | |
| 1098 | Curl_init_userdefined(data); |
| C1: Curl_init_userdefined(data) re-initializes | |
| 1099 | |
| 1100 | /* zero out Progress data: */ |
| 1101 | memset(&data->progress, 0, sizeof(struct Progress)); |
| 1102 | |
| 1103 | /* zero out PureInfo data: */ |
| 1104 | Curl_initinfo(data); |
| 1105 | |
| 1106 | data->progress.hide = TRUE; |
| 1107 | data->state.current_speed = -1; /* init to negative == impossible */ |
| 1108 | data->state.recent_conn_id = -1; /* clear remembered connection id */ |
| 1109 | |
| 1110 | /* zero out authentication data: */ |
| 1111 | memset(&data->state.authhost, 0, sizeof(struct auth)); |
| 1112 | memset(&data->state.authproxy, 0, sizeof(struct auth)); |
| 1113 | |
| 1114 | #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_DIGEST_AUTH) |
| 1115 | Curl_http_auth_cleanup_digest(data); |
| 1116 | #endif |
| 1117 | data->master_mid = UINT32_MAX; |
| 1118 | } |
| 1119 | |
| 1120 | /* |
| 1121 | * curl_easy_pause() allows an application to pause or unpause a specific |
| 1122 | * transfer and direction. This function sets the full new state for the |
| 1123 | * current connection this easy handle operates on. |
| 3069 | parent->set.priority.children = 0; |
| 3070 | } |
| 3071 | |
| 3072 | tail = &parent->set.priority.children; |
| 3073 | while(*tail) { |
| 3074 | (*tail)->data->set.priority.exclusive = FALSE; |
| 3075 | tail = &(*tail)->next; |
| 3076 | } |
| 3077 | |
| 3078 | DEBUGASSERT(!*tail); |
| 3079 | *tail = pnode; |
| 3080 | } |
| 3081 | |
| 3082 | child->set.priority.parent = parent; |
| 3083 | child->set.priority.exclusive = exclusive; |
| 3084 | return CURLE_OK; |
| 3085 | } |
| 3086 | |
| 3087 | #endif /* USE_NGHTTP2 */ |
| 3088 | |
| 3089 | #ifdef USE_NGHTTP2 |
| C3: #ifdef USE_NGHTTP2 guards data_priority_cleanup definition | |
| 3090 | static void data_priority_cleanup(struct Curl_easy *data) |
| C1: data_priority_cleanup exists but is not called from curl_easy_reset | |
| 3091 | { |
| 3092 | while(data->set.priority.children) { |
| C4: data_priority_cleanup walks data->set.priority.children | |
| 3093 | struct Curl_easy *tmp = data->set.priority.children->data; |
| 3094 | priority_remove_child(data, tmp); |
| C4: calls priority_remove_child(data, tmp) where tmp is child->data | |
| 3095 | if(data->set.priority.parent) |
| 3096 | Curl_data_priority_add_child(data->set.priority.parent, tmp, FALSE); |
| 3097 | } |
| 3098 | |
| 3099 | if(data->set.priority.parent) |
| 3100 | priority_remove_child(data->set.priority.parent, data); |
| 3101 | } |
| 3102 | #endif |
| 3103 | |
| 3104 | void Curl_data_priority_clear_state(struct Curl_easy *data) |
| 3105 | { |
| 3106 | memset(&data->state.priority, 0, sizeof(data->state.priority)); |
| 3107 | } |
| 3108 | |
| 3109 | #endif /* USE_HTTP2 || USE_HTTP3 */ |
| 3110 | |
| 3111 | CURLcode Curl_conn_meta_set(struct connectdata *conn, const char *key, |
| 3112 | void *meta_data, Curl_meta_dtor *meta_dtor) |
| 3113 | { |
| 3114 | if(!Curl_hash_add2(&conn->meta_hash, CURL_UNCONST(key), strlen(key) + 1, |
| 3115 | meta_data, meta_dtor)) { |
| 3116 | meta_dtor(CURL_UNCONST(key), strlen(key) + 1, meta_data); |
| 3117 | return CURLE_OUT_OF_MEMORY; |
| 3118 | } |
| 3119 | return CURLE_OK; |
| 2997 | |
| 2998 | data->state.done = FALSE; /* *_done() is not called yet */ |
| 2999 | |
| 3000 | data->req.no_body = data->set.opt_no_body; |
| 3001 | if(data->req.no_body) |
| 3002 | /* in HTTP lingo, no body means using the HEAD request... */ |
| 3003 | data->state.httpreq = HTTPREQ_HEAD; |
| 3004 | |
| 3005 | result = Curl_req_start(&data->req, data); |
| 3006 | if(!result) { |
| 3007 | Curl_pgrsReset(data); |
| 3008 | } |
| 3009 | return result; |
| 3010 | } |
| 3011 | |
| 3012 | #if defined(USE_HTTP2) || defined(USE_HTTP3) |
| 3013 | |
| 3014 | #ifdef USE_NGHTTP2 |
| C3: #ifdef USE_NGHTTP2 guards the priority tree implementation | |
| 3015 | |
| 3016 | static void priority_remove_child(struct Curl_easy *parent, |
| 3017 | struct Curl_easy *child) |
| 3018 | { |
| 3019 | struct Curl_data_prio_node **pnext = &parent->set.priority.children; |
| 3020 | struct Curl_data_prio_node *pnode = parent->set.priority.children; |
| 3021 | |
| 3022 | DEBUGASSERT(child->set.priority.parent == parent); |
| C4: priority_remove_child reads child->set.priority.parent (DEBUGASSERT) | |
| 3023 | while(pnode && pnode->data != child) { |
| 3024 | pnext = &pnode->next; |
| 3025 | pnode = pnode->next; |
| 3026 | } |
| 3027 | |
| 3028 | DEBUGASSERT(pnode); |
| 3029 | if(pnode) { |
| 3030 | *pnext = pnode->next; |
| 3031 | curlx_free(pnode); |
| 3032 | } |
| 3033 | |
| 3034 | child->set.priority.parent = 0; |
| C4: priority_remove_child writes child->set.priority.parent = 0 | |
| 3035 | child->set.priority.exclusive = FALSE; |
| C4: priority_remove_child writes child->set.priority.exclusive = FALSE | |
| 3036 | } |
| 3037 | |
| 3038 | CURLcode Curl_data_priority_add_child(struct Curl_easy *parent, |
| 3039 | struct Curl_easy *child, |
| 3040 | bool exclusive) |
| 3041 | { |
| 3042 | if(child->set.priority.parent) { |
| 3043 | priority_remove_child(child->set.priority.parent, child); |
| 3044 | } |
| 3045 | |
| 3046 | if(parent) { |
| 3047 | struct Curl_data_prio_node **tail; |
| 3048 | struct Curl_data_prio_node *pnode; |
| 3049 | |
| 3050 | pnode = curlx_calloc(1, sizeof(*pnode)); |
| 3051 | if(!pnode) |
| 3052 | return CURLE_OUT_OF_MEMORY; |
| 3053 | pnode->data = child; |
| 3054 | |
| 3055 | if(parent->set.priority.children && exclusive) { |
| 3056 | /* exclusive: move all existing children underneath the new child */ |
| 3057 | struct Curl_data_prio_node *node = parent->set.priority.children; |
| 3058 | while(node) { |
| 3059 | node->data->set.priority.parent = child; |
| 3060 | node = node->next; |
| 838 | void curl_easy_cleanup(CURL *curl) |
| 839 | { |
| 840 | struct Curl_easy *data = curl; |
| 841 | if(GOOD_EASY_HANDLE(data)) { |
| 842 | struct Curl_sigpipe_ctx sigpipe_ctx; |
| 843 | sigpipe_ignore(data, &sigpipe_ctx); |
| 844 | Curl_close(&data); |
| C5: curl_easy_cleanup calls Curl_close | |
| 845 | sigpipe_restore(&sigpipe_ctx); |
| 846 | } |
| 847 | } |
Show 109 lines (not cited by the judge)
| 205 | CURLcode Curl_close(struct Curl_easy **datap) |
| 206 | { |
| 207 | struct Curl_easy *data; |
| 208 | |
| 209 | if(!datap || !*datap) |
| 210 | return CURLE_OK; |
| 211 | |
| 212 | data = *datap; |
| 213 | *datap = NULL; |
| 214 | |
| 215 | if(!data->state.internal && data->multi) { |
| 216 | /* This handle is still part of a multi handle, take care of this first |
| 217 | and detach this handle from there. |
| 218 | This detaches the connection. */ |
| 219 | curl_multi_remove_handle(data->multi, data); |
| 220 | } |
| 221 | else { |
| 222 | /* Detach connection if any is left. This should not be normal, but can be |
| 223 | the case for example with CONNECT_ONLY + recv/send (test 556) */ |
| 224 | Curl_detach_connection(data); |
| 225 | if(!data->state.internal && data->multi_easy) { |
| 226 | /* when curl_easy_perform() is used, it creates its own multi handle to |
| 227 | use and this is the one */ |
| 228 | curl_multi_cleanup(data->multi_easy); |
| 229 | data->multi_easy = NULL; |
| 230 | } |
| 231 | } |
| 232 | DEBUGASSERT(!data->conn || data->state.internal); |
| 233 | |
| 234 | Curl_expire_clear(data); /* shut off any timers left */ |
| 235 | |
| 236 | if(data->state.rangestringalloc) |
| 237 | curlx_free(data->state.range); |
| 238 | |
| 239 | /* release any resolve information this transfer kept */ |
| 240 | Curl_resolv_destroy_all(data); |
| 241 | |
| 242 | data->set.verbose = FALSE; /* no more calls to DEBUGFUNCTION */ |
| 243 | data->magic = 0; /* force a clear AFTER the possibly enforced removal from |
| 244 | * the multi handle and async dns shutdown. The multi |
| 245 | * handle might check the magic and so might any |
| 246 | * DEBUGFUNCTION invoked for tracing */ |
| 247 | |
| 248 | /* freed here in case DONE was not called */ |
| 249 | Curl_req_free(&data->req, data); |
| 250 | |
| 251 | /* Close down all open SSL info and sessions */ |
| 252 | Curl_ssl_close_all(data); |
| 253 | Curl_peer_unlink(&data->state.initial_origin); |
| 254 | Curl_ssl_free_certinfo(data); |
| 255 | |
| 256 | Curl_bufref_free(&data->state.referer); |
| 257 | |
| 258 | up_free(data); |
| 259 | curlx_dyn_free(&data->state.headerb); |
| 260 | Curl_flush_cookies(data, TRUE); |
| 261 | #ifndef CURL_DISABLE_ALTSVC |
| 262 | Curl_altsvc_save(data, data->asi, data->set.str[STRING_ALTSVC]); |
| 263 | Curl_altsvc_cleanup(&data->asi); |
| 264 | #endif |
| 265 | #ifndef CURL_DISABLE_HSTS |
| 266 | Curl_hsts_save(data, data->hsts, data->set.str[STRING_HSTS]); |
| 267 | if(!data->share || !data->share->hsts) |
| 268 | Curl_hsts_cleanup(&data->hsts); |
| 269 | curl_slist_free_all(data->state.hstslist); /* clean up list */ |
| 270 | #endif |
| 271 | #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_DIGEST_AUTH) |
| 272 | Curl_http_auth_cleanup_digest(data); |
| 273 | #endif |
| 274 | curlx_safefree(data->state.most_recent_ftp_entrypath); |
| 275 | curlx_safefree(data->info.contenttype); |
| 276 | curlx_safefree(data->info.wouldredirect); |
| 277 | |
| 278 | data_priority_cleanup(data); |
| 279 | |
| 280 | /* No longer a dirty share, if it exists */ |
| 281 | if(Curl_share_easy_unlink(data)) |
| 282 | DEBUGASSERT(0); |
| 283 | |
| 284 | Curl_hash_destroy(&data->meta_hash); |
| 285 | Curl_creds_unlink(&data->state.creds); |
| 286 | curlx_safefree(data->state.aptr.uagent); |
| 287 | curlx_safefree(data->state.aptr.accept_encoding); |
| 288 | curlx_safefree(data->state.aptr.rangeline); |
| 289 | curlx_safefree(data->state.aptr.ref); |
| 290 | curlx_safefree(data->state.aptr.host); |
| 291 | #ifndef CURL_DISABLE_COOKIES |
| 292 | curlx_safefree(data->req.cookiehost); |
| 293 | #endif |
| 294 | #ifndef CURL_DISABLE_RTSP |
| 295 | curlx_safefree(data->state.aptr.rtsp_transport); |
| 296 | #endif |
| 297 | |
| 298 | #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_FORM_API) |
| 299 | Curl_mime_cleanpart(data->state.formp); |
| 300 | curlx_safefree(data->state.formp); |
| 301 | #endif |
| 302 | |
| 303 | /* destruct wildcard structures if it is needed */ |
| 304 | Curl_wildcard_dtor(&data->wildcard); |
| 305 | Curl_freeset(data); |
| 306 | Curl_headers_cleanup(data); |
| 307 | Curl_netrc_cleanup(&data->state.netrc); |
| 308 | #ifndef CURL_DISABLE_DIGEST_AUTH |
| 309 | curlx_free(data->state.envproxy); |
| 310 | #endif |
| 311 | curlx_free(data); |
| 312 | return CURLE_OK; |
| 313 | } |
Show 111 lines (not cited by the judge)
| 207 | CURLcode Curl_close(struct Curl_easy **datap) |
| 208 | { |
| 209 | struct Curl_easy *data; |
| 210 | |
| 211 | if(!datap || !*datap) |
| 212 | return CURLE_OK; |
| 213 | |
| 214 | data = *datap; |
| 215 | *datap = NULL; |
| 216 | |
| 217 | if(!data->state.internal && data->multi) { |
| 218 | /* This handle is still part of a multi handle, take care of this first |
| 219 | and detach this handle from there. |
| 220 | This detaches the connection. */ |
| 221 | curl_multi_remove_handle(data->multi, data); |
| 222 | } |
| 223 | else { |
| 224 | /* Detach connection if any is left. This should not be normal, but can be |
| 225 | the case for example with CONNECT_ONLY + recv/send (test 556) */ |
| 226 | Curl_detach_connection(data); |
| 227 | if(!data->state.internal && data->multi_easy) { |
| 228 | /* when curl_easy_perform() is used, it creates its own multi handle to |
| 229 | use and this is the one */ |
| 230 | curl_multi_cleanup(data->multi_easy); |
| 231 | data->multi_easy = NULL; |
| 232 | } |
| 233 | } |
| 234 | DEBUGASSERT(!data->conn || data->state.internal); |
| 235 | |
| 236 | Curl_expire_clear(data); /* shut off any timers left */ |
| 237 | |
| 238 | if(data->state.rangestringalloc) |
| 239 | curlx_free(data->state.range); |
| 240 | |
| 241 | /* release any resolve information this transfer kept */ |
| 242 | Curl_resolv_destroy_all(data); |
| 243 | |
| 244 | data->set.verbose = FALSE; /* no more calls to DEBUGFUNCTION */ |
| 245 | data->magic = 0; /* force a clear AFTER the possibly enforced removal from |
| 246 | * the multi handle and async dns shutdown. The multi |
| 247 | * handle might check the magic and so might any |
| 248 | * DEBUGFUNCTION invoked for tracing */ |
| 249 | |
| 250 | /* freed here in case DONE was not called */ |
| 251 | Curl_req_free(&data->req, data); |
| 252 | |
| 253 | /* Close down all open SSL info and sessions */ |
| 254 | Curl_ssl_close_all(data); |
| 255 | curlx_safefree(data->state.first_host); |
| 256 | Curl_ssl_free_certinfo(data); |
| 257 | |
| 258 | Curl_bufref_free(&data->state.referer); |
| 259 | |
| 260 | up_free(data); |
| 261 | curlx_dyn_free(&data->state.headerb); |
| 262 | Curl_flush_cookies(data, TRUE); |
| 263 | #ifndef CURL_DISABLE_ALTSVC |
| 264 | Curl_altsvc_save(data, data->asi, data->set.str[STRING_ALTSVC]); |
| 265 | Curl_altsvc_cleanup(&data->asi); |
| 266 | #endif |
| 267 | #ifndef CURL_DISABLE_HSTS |
| 268 | Curl_hsts_save(data, data->hsts, data->set.str[STRING_HSTS]); |
| 269 | if(!data->share || !data->share->hsts) |
| 270 | Curl_hsts_cleanup(&data->hsts); |
| 271 | curl_slist_free_all(data->state.hstslist); /* clean up list */ |
| 272 | #endif |
| 273 | #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_DIGEST_AUTH) |
| 274 | Curl_http_auth_cleanup_digest(data); |
| 275 | #endif |
| 276 | curlx_safefree(data->state.most_recent_ftp_entrypath); |
| 277 | curlx_safefree(data->info.contenttype); |
| 278 | curlx_safefree(data->info.wouldredirect); |
| 279 | |
| 280 | data_priority_cleanup(data); |
| 281 | |
| 282 | /* No longer a dirty share, if it exists */ |
| 283 | if(Curl_share_easy_unlink(data)) |
| 284 | DEBUGASSERT(0); |
| 285 | |
| 286 | Curl_hash_destroy(&data->meta_hash); |
| 287 | curlx_safefree(data->state.aptr.uagent); |
| 288 | curlx_safefree(data->state.aptr.accept_encoding); |
| 289 | curlx_safefree(data->state.aptr.rangeline); |
| 290 | curlx_safefree(data->state.aptr.ref); |
| 291 | curlx_safefree(data->state.aptr.host); |
| 292 | #ifndef CURL_DISABLE_COOKIES |
| 293 | curlx_safefree(data->req.cookiehost); |
| 294 | #endif |
| 295 | #ifndef CURL_DISABLE_RTSP |
| 296 | curlx_safefree(data->state.aptr.rtsp_transport); |
| 297 | #endif |
| 298 | curlx_safefree(data->state.aptr.user); |
| 299 | curlx_safefree(data->state.aptr.passwd); |
| 300 | #ifndef CURL_DISABLE_PROXY |
| 301 | curlx_safefree(data->state.aptr.proxyuser); |
| 302 | curlx_safefree(data->state.aptr.proxypasswd); |
| 303 | #endif |
| 304 | |
| 305 | #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_FORM_API) |
| 306 | Curl_mime_cleanpart(data->state.formp); |
| 307 | curlx_safefree(data->state.formp); |
| 308 | #endif |
| 309 | |
| 310 | /* destruct wildcard structures if it is needed */ |
| 311 | Curl_wildcard_dtor(&data->wildcard); |
| 312 | Curl_freeset(data); |
| 313 | Curl_headers_cleanup(data); |
| 314 | Curl_netrc_cleanup(&data->state.netrc); |
| 315 | curlx_free(data); |
| 316 | return CURLE_OK; |
| 317 | } |
Show 27 lines (not cited by the judge)
| 154 | void Curl_freeset(struct Curl_easy *data) |
| 155 | { |
| 156 | /* Free all dynamic strings stored in the data->set substructure. */ |
| 157 | enum dupstring i; |
| 158 | enum dupblob j; |
| 159 | |
| 160 | for(i = (enum dupstring)0; i < STRING_LAST; i++) { |
| 161 | curlx_safefree(data->set.str[i]); |
| 162 | } |
| 163 | |
| 164 | for(j = (enum dupblob)0; j < BLOB_LAST; j++) { |
| 165 | curlx_safefree(data->set.blobs[j]); |
| 166 | } |
| 167 | |
| 168 | Curl_bufref_free(&data->state.referer); |
| 169 | Curl_bufref_free(&data->state.url); |
| 170 | |
| 171 | #if !defined(CURL_DISABLE_MIME) || !defined(CURL_DISABLE_FORM_API) |
| 172 | Curl_mime_cleanpart(data->set.mimepostp); |
| 173 | curlx_safefree(data->set.mimepostp); |
| 174 | #endif |
| 175 | |
| 176 | #ifndef CURL_DISABLE_COOKIES |
| 177 | curl_slist_free_all(data->state.cookielist); |
| 178 | data->state.cookielist = NULL; |
| 179 | #endif |
| 180 | } |
Show 119 lines (not cited by the judge)
| 319 | void Curl_init_userdefined(struct Curl_easy *data) |
| 320 | { |
| 321 | struct UserDefined *set = &data->set; |
| 322 | |
| 323 | set->out = stdout; /* default output to stdout */ |
| 324 | set->in_set = stdin; /* default input from stdin */ |
| 325 | set->err = stderr; /* default stderr to stderr */ |
| 326 | |
| 327 | #if defined(__clang__) && __clang_major__ >= 16 |
| 328 | #pragma clang diagnostic push |
| 329 | #pragma clang diagnostic ignored "-Wcast-function-type-strict" |
| 330 | #endif |
| 331 | /* use fwrite as default function to store output */ |
| 332 | set->fwrite_func = (curl_write_callback)fwrite; |
| 333 | |
| 334 | /* use fread as default function to read input */ |
| 335 | set->fread_func_set = (curl_read_callback)fread; |
| 336 | #if defined(__clang__) && __clang_major__ >= 16 |
| 337 | #pragma clang diagnostic pop |
| 338 | #endif |
| 339 | set->is_fread_set = 0; |
| 340 | |
| 341 | set->seek_client = ZERO_NULL; |
| 342 | |
| 343 | set->filesize = -1; /* we do not know the size */ |
| 344 | set->postfieldsize = -1; /* unknown size */ |
| 345 | set->maxredirs = 30; /* sensible default */ |
| 346 | |
| 347 | set->method = HTTPREQ_GET; /* Default HTTP request */ |
| 348 | #ifndef CURL_DISABLE_RTSP |
| 349 | set->rtspreq = RTSPREQ_OPTIONS; /* Default RTSP request */ |
| 350 | #endif |
| 351 | #ifndef CURL_DISABLE_FTP |
| 352 | set->ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */ |
| 353 | set->ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */ |
| 354 | set->ftp_use_pret = FALSE; /* mainly useful for drftpd servers */ |
| 355 | set->ftp_filemethod = FTPFILE_MULTICWD; |
| 356 | set->ftp_skip_ip = TRUE; /* skip PASV IP by default */ |
| 357 | #endif |
| 358 | set->dns_cache_timeout_ms = 60000; /* Timeout every 60 seconds by default */ |
| 359 | |
| 360 | /* Timeout every 24 hours by default */ |
| 361 | set->general_ssl.ca_cache_timeout = 24 * 60 * 60; |
| 362 | |
| 363 | set->httpauth = CURLAUTH_BASIC; /* defaults to basic */ |
| 364 | |
| 365 | #ifndef CURL_DISABLE_PROXY |
| 366 | set->proxyport = 0; |
| 367 | set->proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */ |
| 368 | set->proxyauth = CURLAUTH_BASIC; /* defaults to basic */ |
| 369 | /* SOCKS5 proxy auth defaults to username/password + GSS-API */ |
| 370 | set->socks5auth = CURLAUTH_BASIC | CURLAUTH_GSSAPI; |
| 371 | #endif |
| 372 | |
| 373 | Curl_ssl_easy_config_init(data); |
| 374 | #ifndef CURL_DISABLE_DOH |
| 375 | set->doh_verifyhost = TRUE; |
| 376 | set->doh_verifypeer = TRUE; |
| 377 | #endif |
| 378 | #ifdef USE_SSH |
| 379 | /* defaults to any auth type */ |
| 380 | set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; |
| 381 | set->new_directory_perms = 0755; /* Default permissions */ |
| 382 | #endif |
| 383 | |
| 384 | set->new_file_perms = 0644; /* Default permissions */ |
| 385 | set->allowed_protocols = (curl_prot_t)CURLPROTO_64ALL; |
| 386 | set->redir_protocols = CURLPROTO_REDIR; |
| 387 | |
| 388 | #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) |
| 389 | /* |
| 390 | * disallow unprotected protection negotiation NEC reference implementation |
| 391 | * seem not to follow rfc1961 section 4.3/4.4 |
| 392 | */ |
| 393 | set->socks5_gssapi_nec = FALSE; |
| 394 | #endif |
| 395 | |
| 396 | /* set default minimum TLS version */ |
| 397 | #ifdef USE_SSL |
| 398 | Curl_setopt_SSLVERSION(data, CURLOPT_SSLVERSION, CURL_SSLVERSION_DEFAULT); |
| 399 | #ifndef CURL_DISABLE_PROXY |
| 400 | Curl_setopt_SSLVERSION(data, CURLOPT_PROXY_SSLVERSION, |
| 401 | CURL_SSLVERSION_DEFAULT); |
| 402 | #endif |
| 403 | #endif |
| 404 | #ifndef CURL_DISABLE_FTP |
| 405 | set->wildcard_enabled = FALSE; |
| 406 | set->chunk_bgn = ZERO_NULL; |
| 407 | set->chunk_end = ZERO_NULL; |
| 408 | set->fnmatch = ZERO_NULL; |
| 409 | #endif |
| 410 | set->tcp_keepalive = FALSE; |
| 411 | set->tcp_keepintvl = 60; |
| 412 | set->tcp_keepidle = 60; |
| 413 | set->tcp_keepcnt = 9; |
| 414 | set->tcp_fastopen = FALSE; |
| 415 | set->tcp_nodelay = TRUE; |
| 416 | set->ssl_enable_alpn = TRUE; |
| 417 | set->expect_100_timeout = 1000L; /* Wait for a second by default. */ |
| 418 | set->sep_headers = TRUE; /* separated header lists by default */ |
| 419 | set->buffer_size = READBUFFER_SIZE; |
| 420 | set->upload_buffer_size = UPLOADBUFFER_DEFAULT; |
| 421 | set->upload_flags = CURLULFLAG_SEEN; |
| 422 | set->happy_eyeballs_timeout = CURL_HET_DEFAULT; |
| 423 | set->upkeep_interval_ms = CURL_UPKEEP_INTERVAL_DEFAULT; |
| 424 | set->maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */ |
| 425 | set->conn_max_idle_ms = 118 * 1000; |
| 426 | set->conn_max_age_ms = 24 * 3600 * 1000; |
| 427 | set->http09_allowed = FALSE; |
| 428 | set->httpwant = CURL_HTTP_VERSION_NONE; |
| 429 | #if defined(USE_HTTP2) || defined(USE_HTTP3) |
| 430 | memset(&set->priority, 0, sizeof(set->priority)); |
| 431 | #endif |
| 432 | set->quick_exit = 0L; |
| 433 | #ifndef CURL_DISABLE_WEBSOCKETS |
| 434 | set->ws_raw_mode = FALSE; |
| 435 | set->ws_no_auto_pong = FALSE; |
| 436 | #endif |
| 437 | } |
Show 1 lines (not cited by the judge)
| 125 | #define data_priority_cleanup(x) |