mirror of
https://github.com/curl/curl.git
synced 2026-07-31 07:58:04 +03:00
Merge 365d1408ad into 7d5398f764
This commit is contained in:
commit
4d25e56d20
8 changed files with 219 additions and 27 deletions
50
lib/setopt.c
50
lib/setopt.c
|
|
@ -1334,11 +1334,33 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option,
|
|||
return CURLE_UNKNOWN_OPTION;
|
||||
}
|
||||
|
||||
static bool str_has_crlf(const char *p)
|
||||
{
|
||||
while(p && *p) {
|
||||
if(ISNEWLINE(*p))
|
||||
return TRUE;
|
||||
p++;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static bool list_has_crlf(const struct curl_slist *slist)
|
||||
{
|
||||
while(slist) {
|
||||
if(str_has_crlf(slist->data))
|
||||
return TRUE;
|
||||
slist = slist->next;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static CURLcode setopt_slist(struct Curl_easy *data, CURLoption option,
|
||||
struct curl_slist *slist)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct UserDefined *s = &data->set;
|
||||
struct curl_slist **slist_set = NULL;
|
||||
struct curl_slist **slist_set2 = NULL;
|
||||
switch(option) {
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
case CURLOPT_PROXYHEADER:
|
||||
|
|
@ -1352,7 +1374,7 @@ static CURLcode setopt_slist(struct Curl_easy *data, CURLoption option,
|
|||
*
|
||||
* Set this option to NULL to restore the previous behavior.
|
||||
*/
|
||||
s->proxyheaders = slist;
|
||||
slist_set = &s->proxyheaders;
|
||||
break;
|
||||
#endif
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
|
|
@ -1360,7 +1382,7 @@ static CURLcode setopt_slist(struct Curl_easy *data, CURLoption option,
|
|||
/*
|
||||
* Set a list of aliases for HTTP 200 in response header
|
||||
*/
|
||||
s->http200aliases = slist;
|
||||
slist_set = &s->http200aliases;
|
||||
break;
|
||||
#endif
|
||||
#if !defined(CURL_DISABLE_FTP) || defined(USE_SSH)
|
||||
|
|
@ -1368,19 +1390,19 @@ static CURLcode setopt_slist(struct Curl_easy *data, CURLoption option,
|
|||
/*
|
||||
* List of RAW FTP commands to use after a transfer
|
||||
*/
|
||||
s->postquote = slist;
|
||||
slist_set = &s->postquote;
|
||||
break;
|
||||
case CURLOPT_PREQUOTE:
|
||||
/*
|
||||
* List of RAW FTP commands to use prior to RETR (Wesley Laxton)
|
||||
*/
|
||||
s->prequote = slist;
|
||||
slist_set = &s->prequote;
|
||||
break;
|
||||
case CURLOPT_QUOTE:
|
||||
/*
|
||||
* List of RAW FTP commands to use before a transfer
|
||||
*/
|
||||
s->quote = slist;
|
||||
slist_set = &s->quote;
|
||||
break;
|
||||
#endif
|
||||
case CURLOPT_RESOLVE:
|
||||
|
|
@ -1397,15 +1419,15 @@ static CURLcode setopt_slist(struct Curl_easy *data, CURLoption option,
|
|||
* This API can remove any entry from the DNS cache, but only entries
|
||||
* that are not actually in use right now will be pruned immediately.
|
||||
*/
|
||||
s->resolve = slist;
|
||||
data->state.resolve = s->resolve;
|
||||
slist_set = &s->resolve;
|
||||
slist_set2 = &data->state.resolve;
|
||||
break;
|
||||
#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_MIME)
|
||||
case CURLOPT_HTTPHEADER:
|
||||
/*
|
||||
* Set a list with HTTP headers to use (or replace internals with)
|
||||
*/
|
||||
s->headers = slist;
|
||||
slist_set = &s->headers;
|
||||
break;
|
||||
#endif
|
||||
#ifndef CURL_DISABLE_TELNET
|
||||
|
|
@ -1413,21 +1435,27 @@ static CURLcode setopt_slist(struct Curl_easy *data, CURLoption option,
|
|||
/*
|
||||
* Set a linked list of telnet options
|
||||
*/
|
||||
s->telnet_options = slist;
|
||||
slist_set = &s->telnet_options;
|
||||
break;
|
||||
#endif
|
||||
#ifndef CURL_DISABLE_SMTP
|
||||
case CURLOPT_MAIL_RCPT:
|
||||
/* Set the list of mail recipients */
|
||||
s->mail_rcpt = slist;
|
||||
slist_set = &s->mail_rcpt;
|
||||
break;
|
||||
#endif
|
||||
case CURLOPT_CONNECT_TO:
|
||||
s->connect_to = slist;
|
||||
slist_set = &s->connect_to;
|
||||
break;
|
||||
default:
|
||||
return CURLE_UNKNOWN_OPTION;
|
||||
}
|
||||
if(list_has_crlf(slist))
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
/* assign once the list has been confirmed to be decent */
|
||||
*slist_set = slist;
|
||||
if(slist_set2)
|
||||
*slist_set2 = slist;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -948,7 +948,14 @@ static CURLcode credentials_and_headers_setopts(struct OperationConfig *config,
|
|||
if(config->authtype)
|
||||
my_setopt_bitmask(curl, CURLOPT_HTTPAUTH, config->authtype);
|
||||
|
||||
my_setopt_slist(curl, CURLOPT_HTTPHEADER, config->headers);
|
||||
result = my_setopt_slist(curl, CURLOPT_HTTPHEADER, config->headers);
|
||||
if(result == CURLE_BAD_FUNCTION_ARGUMENT) {
|
||||
errorf("Illegal CR/LF in --header data");
|
||||
config->synthetic_error = TRUE;
|
||||
return result;
|
||||
}
|
||||
if(setopt_bad(result))
|
||||
return result;
|
||||
|
||||
if(proto_http || proto_rtsp) {
|
||||
MY_SETOPT_STR(curl, CURLOPT_REFERER, config->referer);
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ test1979 test1980 test1981 test1982 test1983 test1984 \
|
|||
\
|
||||
test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 \
|
||||
test2008 test2009 test2010 test2011 test2012 test2013 test2014 test2015 \
|
||||
\
|
||||
test2016 test2017 \
|
||||
test2023 \
|
||||
test2024 test2025 test2026 test2027 test2028 test2029 test2030 test2031 \
|
||||
test2032 test2033 test2034 test2035 test2036 test2037 test2038 test2039 \
|
||||
|
|
|
|||
32
tests/data/test2016
Normal file
32
tests/data/test2016
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="US-ASCII"?>
|
||||
<testcase>
|
||||
<info>
|
||||
<keywords>
|
||||
HTTP
|
||||
</keywords>
|
||||
</info>
|
||||
|
||||
# Server-side
|
||||
<reply>
|
||||
</reply>
|
||||
|
||||
# Client-side
|
||||
<client>
|
||||
<server>
|
||||
http
|
||||
</server>
|
||||
<name>
|
||||
Attempt sending a carriage return in a HTTP header
|
||||
</name>
|
||||
<command>
|
||||
http://%HOSTIP:%HTTPPORT/%TESTNUMBER -H 'A: %CR'
|
||||
</command>
|
||||
</client>
|
||||
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<errorcode>
|
||||
43
|
||||
</errorcode>
|
||||
</verify>
|
||||
</testcase>
|
||||
34
tests/data/test2017
Normal file
34
tests/data/test2017
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0" encoding="US-ASCII"?>
|
||||
<testcase>
|
||||
<info>
|
||||
<keywords>
|
||||
HTTP
|
||||
curl_easy_setopt
|
||||
</keywords>
|
||||
</info>
|
||||
|
||||
# Server-side
|
||||
<reply>
|
||||
</reply>
|
||||
|
||||
# Client-side
|
||||
<client>
|
||||
<server>
|
||||
http
|
||||
</server>
|
||||
<name>
|
||||
Pass and reject CR and LF in setopt slist options
|
||||
</name>
|
||||
<command>
|
||||
http://%HOSTIP:%HTTPPORT/%TESTNUMBER
|
||||
</command>
|
||||
<tool>
|
||||
lib%TESTNUMBER
|
||||
</tool>
|
||||
|
||||
</client>
|
||||
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
</verify>
|
||||
</testcase>
|
||||
|
|
@ -236,20 +236,6 @@ class TestBasic:
|
|||
else:
|
||||
r.check_exit_code(100) # CURLE_TOO_LARGE
|
||||
|
||||
# http: invalid request headers, GET, issue #16998
|
||||
@pytest.mark.parametrize("proto", Env.http_protos())
|
||||
def test_01_16_inv_req_get(self, env: Env, httpd, nghttpx, proto):
|
||||
curl = CurlClient(env=env)
|
||||
url = f'https://{env.authority_for(env.domain1, proto)}/curltest/echo'
|
||||
r = curl.http_get(url=url, alpn_proto=proto, extra_args=[
|
||||
'-H', "a: a\x0ab"
|
||||
])
|
||||
# on h1, request is sent, h2/h3 reject
|
||||
if proto == 'http/1.1':
|
||||
r.check_exit_code(0)
|
||||
else:
|
||||
r.check_exit_code(43)
|
||||
|
||||
# http: special handling of TE request header
|
||||
@pytest.mark.parametrize("te_in, te_out", [
|
||||
pytest.param('trailers', 'trailers', id='trailers'),
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@ TESTS_C = \
|
|||
lib1955.c lib1956.c lib1957.c lib1958.c lib1959.c lib1960.c \
|
||||
lib1964.c lib1965.c lib1967.c lib1970.c \
|
||||
lib1971.c lib1972.c lib1973.c lib1974.c lib1975.c lib1977.c lib1978.c \
|
||||
lib2017.c \
|
||||
lib2023.c lib2032.c lib2082.c \
|
||||
lib2301.c lib2302.c lib2304.c lib2306.c lib2308.c lib2309.c \
|
||||
lib2402.c lib2404.c lib2405.c \
|
||||
|
|
|
|||
104
tests/libtest/lib2017.c
Normal file
104
tests/libtest/lib2017.c
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
#include "first.h"
|
||||
#include "testtrace.h"
|
||||
|
||||
static CURLcode test_lib2017(const char *URL)
|
||||
{
|
||||
CURLcode result;
|
||||
CURL *curl;
|
||||
int errors = 0;
|
||||
|
||||
struct curl_slist crlist = {
|
||||
CURL_UNCONST("data and a \x0d in there"), NULL
|
||||
};
|
||||
struct curl_slist lflist = {
|
||||
CURL_UNCONST("data and a \x0a in there"), NULL
|
||||
};
|
||||
struct curl_slist bothlist[] = {
|
||||
{ CURL_UNCONST("nothing harmful"), NULL },
|
||||
{ CURL_UNCONST("both a \x0a and a \x0d embedded"), NULL}
|
||||
};
|
||||
|
||||
/* all slist options should reject these lists */
|
||||
CURLoption opts[] = {
|
||||
CURLOPT_PROXYHEADER,
|
||||
CURLOPT_HTTP200ALIASES,
|
||||
CURLOPT_POSTQUOTE,
|
||||
CURLOPT_PREQUOTE,
|
||||
CURLOPT_QUOTE,
|
||||
CURLOPT_RESOLVE,
|
||||
CURLOPT_HTTPHEADER,
|
||||
CURLOPT_TELNETOPTIONS,
|
||||
CURLOPT_MAIL_RCPT,
|
||||
CURLOPT_CONNECT_TO,
|
||||
CURLOPT_LASTENTRY /* end of list */
|
||||
};
|
||||
|
||||
int i;
|
||||
|
||||
bothlist[0].next = &bothlist[1];
|
||||
|
||||
if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
|
||||
curl_mfprintf(stderr, "curl_global_init() failed\n");
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(!curl) {
|
||||
curl_mfprintf(stderr, "curl_easy_init() failed\n");
|
||||
curl_global_cleanup();
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
easy_setopt(curl, CURLOPT_URL, URL);
|
||||
|
||||
for(i = 0; opts[i] != CURLOPT_LASTENTRY; i++) {
|
||||
CURLcode result1;
|
||||
CURLcode result2;
|
||||
CURLcode result3;
|
||||
CURLoption o = opts[i];
|
||||
result1 = curl_easy_setopt(curl, o, &lflist);
|
||||
if(!result1)
|
||||
curl_mfprintf(stderr, "Option %d unexpectedly OK for LF", (int)o);
|
||||
|
||||
result2 = curl_easy_setopt(curl, opts[i], &crlist);
|
||||
if(!result2)
|
||||
curl_mfprintf(stderr, "Option %d unexpectedly OK for CR", (int)o);
|
||||
|
||||
result3 = curl_easy_setopt(curl, opts[i], bothlist);
|
||||
if(!result3)
|
||||
curl_mfprintf(stderr, "Option %d unexpectedly OK for CR+LF", (int)o);
|
||||
|
||||
if(!result1 || !result2 || !result3)
|
||||
errors++;
|
||||
}
|
||||
|
||||
test_cleanup:
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
|
||||
return errors ? CURLE_BAD_FUNCTION_ARGUMENT : result;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue