mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-21 22:19:29 +00:00
feat(real-world-vfc-slice): add labeled OpenSSL/Firefox/Chromium/curl pair corpus
Harvest 176 isolated vuln-vs-fix functions (109 CVEs, 352 training rows) into benchmarks/pairs/vfc with provenance and a JSONL training manifest. Score the slice as an honesty dashboard (ousast pairs --slice vfc); keep the pair gate on the local fixtures only.
This commit is contained in:
@@ -0,0 +1,186 @@
|
||||
/* Provenance: curl/curl tool_header_cb (fixed).
|
||||
* repo: curl/curl
|
||||
* commit: 8236aba58542c5f89f1d41ca09d84579efb05e22
|
||||
* parent: 26d2755d7c3181e90e46014778941bff53d2309f
|
||||
* commit_url: https://github.com/curl/curl/commit/8236aba58542c5f89f1d41ca09d84579efb05e22
|
||||
* cve: CVE-2020-8177
|
||||
* license: curl
|
||||
* function: tool_header_cb
|
||||
* relpath: src/tool_cb_hdr.c
|
||||
*/
|
||||
|
||||
size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata)
|
||||
{
|
||||
struct per_transfer *per = userdata;
|
||||
struct HdrCbData *hdrcbdata = &per->hdrcbdata;
|
||||
struct OutStruct *outs = &per->outs;
|
||||
struct OutStruct *heads = &per->heads;
|
||||
struct OutStruct *etag_save = &per->etag_save;
|
||||
const char *str = ptr;
|
||||
const size_t cb = size * nmemb;
|
||||
const char *end = (char *)ptr + cb;
|
||||
long protocol = 0;
|
||||
|
||||
/*
|
||||
* Once that libcurl has called back tool_header_cb() the returned value
|
||||
* is checked against the amount that was intended to be written, if
|
||||
* it does not match then it fails with CURLE_WRITE_ERROR. So at this
|
||||
* point returning a value different from sz*nmemb indicates failure.
|
||||
*/
|
||||
size_t failure = (size && nmemb) ? 0 : 1;
|
||||
|
||||
if(!per->config)
|
||||
return failure;
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
if(size * nmemb > (size_t)CURL_MAX_HTTP_HEADER) {
|
||||
warnf(per->config->global, "Header data exceeds single call write "
|
||||
"limit!\n");
|
||||
return failure;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Write header data when curl option --dump-header (-D) is given.
|
||||
*/
|
||||
|
||||
if(per->config->headerfile && heads->stream) {
|
||||
size_t rc = fwrite(ptr, size, nmemb, heads->stream);
|
||||
if(rc != cb)
|
||||
return rc;
|
||||
/* flush the stream to send off what we got earlier */
|
||||
(void)fflush(heads->stream);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write etag to file when --etag-save option is given.
|
||||
* etag string that we want is enveloped in double quotes
|
||||
*/
|
||||
if(per->config->etag_save_file && etag_save->stream) {
|
||||
/* match only header that start with etag (case insensitive) */
|
||||
if(curl_strnequal(str, "etag:", 5)) {
|
||||
char *etag_h = NULL;
|
||||
char *first = NULL;
|
||||
char *last = NULL;
|
||||
size_t etag_length = 0;
|
||||
|
||||
etag_h = ptr;
|
||||
/* point to first occurrence of double quote */
|
||||
first = memchr(etag_h, '\"', cb);
|
||||
|
||||
/*
|
||||
* if server side messed with the etag header and doesn't include
|
||||
* double quotes around the etag, kindly exit with a warning
|
||||
*/
|
||||
|
||||
if(!first) {
|
||||
warnf(per->config->global,
|
||||
"\nReceived header etag is missing double quote/s\n");
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
/* discard first double quote */
|
||||
first++;
|
||||
}
|
||||
|
||||
/* point to last occurrence of double quote */
|
||||
last = memchr(first, '\"', cb);
|
||||
|
||||
if(!last) {
|
||||
warnf(per->config->global,
|
||||
"\nReceived header etag is missing double quote/s\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* get length of desired etag */
|
||||
etag_length = (size_t)last - (size_t)first;
|
||||
|
||||
fwrite(first, size, etag_length, etag_save->stream);
|
||||
/* terminate with new line */
|
||||
fputc('\n', etag_save->stream);
|
||||
}
|
||||
|
||||
(void)fflush(etag_save->stream);
|
||||
}
|
||||
|
||||
/*
|
||||
* This callback sets the filename where output shall be written when
|
||||
* curl options --remote-name (-O) and --remote-header-name (-J) have
|
||||
* been simultaneously given and additionally server returns an HTTP
|
||||
* Content-Disposition header specifying a filename property.
|
||||
*/
|
||||
|
||||
curl_easy_getinfo(per->curl, CURLINFO_PROTOCOL, &protocol);
|
||||
if(hdrcbdata->honor_cd_filename &&
|
||||
(cb > 20) && checkprefix("Content-disposition:", str) &&
|
||||
(protocol & (CURLPROTO_HTTPS|CURLPROTO_HTTP))) {
|
||||
const char *p = str + 20;
|
||||
|
||||
/* look for the 'filename=' parameter
|
||||
(encoded filenames (*=) are not supported) */
|
||||
for(;;) {
|
||||
char *filename;
|
||||
size_t len;
|
||||
|
||||
while(*p && (p < end) && !ISALPHA(*p))
|
||||
p++;
|
||||
if(p > end - 9)
|
||||
break;
|
||||
|
||||
if(memcmp(p, "filename=", 9)) {
|
||||
/* no match, find next parameter */
|
||||
while((p < end) && (*p != ';'))
|
||||
p++;
|
||||
continue;
|
||||
}
|
||||
p += 9;
|
||||
|
||||
/* this expression below typecasts 'cb' only to avoid
|
||||
warning: signed and unsigned type in conditional expression
|
||||
*/
|
||||
len = (ssize_t)cb - (p - str);
|
||||
filename = parse_filename(p, len);
|
||||
if(filename) {
|
||||
if(outs->stream) {
|
||||
/* indication of problem, get out! */
|
||||
free(filename);
|
||||
return failure;
|
||||
}
|
||||
|
||||
outs->is_cd_filename = TRUE;
|
||||
outs->s_isreg = TRUE;
|
||||
outs->fopened = FALSE;
|
||||
outs->filename = filename;
|
||||
outs->alloc_filename = TRUE;
|
||||
hdrcbdata->honor_cd_filename = FALSE; /* done now! */
|
||||
if(!tool_create_output_file(outs, per->config))
|
||||
return failure;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(!outs->stream && !tool_create_output_file(outs, per->config))
|
||||
return failure;
|
||||
}
|
||||
|
||||
if(hdrcbdata->config->show_headers &&
|
||||
(protocol &
|
||||
(CURLPROTO_HTTP|CURLPROTO_HTTPS|CURLPROTO_RTSP|CURLPROTO_FILE))) {
|
||||
/* bold headers only for selected protocols */
|
||||
char *value = NULL;
|
||||
|
||||
if(!outs->stream && !tool_create_output_file(outs, per->config))
|
||||
return failure;
|
||||
|
||||
if(hdrcbdata->global->isatty && hdrcbdata->global->styled_output)
|
||||
value = memchr(ptr, ':', cb);
|
||||
if(value) {
|
||||
size_t namelen = value - ptr;
|
||||
fprintf(outs->stream, BOLD "%.*s" BOLDOFF ":", namelen, ptr);
|
||||
fwrite(&value[1], cb - namelen - 1, 1, outs->stream);
|
||||
}
|
||||
else
|
||||
/* not "handled", just show it */
|
||||
fwrite(ptr, cb, 1, outs->stream);
|
||||
}
|
||||
return cb;
|
||||
}
|
||||
Reference in New Issue
Block a user