You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
668 lines
24 KiB
668 lines
24 KiB
6 years ago
|
From 9f163418fabbe6219ab04cfe9bf81d2f33bd54d7 Mon Sep 17 00:00:00 2001
|
||
|
From: Richy Kim <richy@fb.com>
|
||
|
Date: Tue, 20 Dec 2016 05:48:15 -0500
|
||
|
Subject: [PATCH 1/7] CURLOPT_BUFFERSIZE: support enlarging receive buffer
|
||
|
|
||
|
Replace use of fixed macro BUFSIZE to define the size of the receive
|
||
|
buffer. Reappropriate CURLOPT_BUFFERSIZE to include enlarging receive
|
||
|
buffer size. Upon setting, resize buffer if larger than the current
|
||
|
default size up to a MAX_BUFSIZE (512KB). This can benefit protocols
|
||
|
like SFTP.
|
||
|
|
||
|
Closes #1222
|
||
|
|
||
|
Upstream-commit: 6b7616690e5370c21e3a760321af6bf4edbabfb6
|
||
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
||
|
---
|
||
|
docs/libcurl/curl_easy_setopt.3 | 12 ++++++------
|
||
|
docs/libcurl/symbols-in-versions | 1 +
|
||
|
include/curl/curl.h | 5 +++++
|
||
|
lib/easy.c | 6 ++++++
|
||
|
lib/file.c | 2 +-
|
||
|
lib/ftp.c | 4 ++--
|
||
|
lib/http.c | 3 ++-
|
||
|
lib/telnet.c | 5 +++--
|
||
|
lib/url.c | 28 +++++++++++++++++++++++-----
|
||
|
lib/urldata.h | 5 ++++-
|
||
|
10 files changed, 53 insertions(+), 18 deletions(-)
|
||
|
|
||
|
diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3
|
||
|
index cbebfba..17b632f 100644
|
||
|
--- a/docs/libcurl/curl_easy_setopt.3
|
||
|
+++ b/docs/libcurl/curl_easy_setopt.3
|
||
|
@@ -938,12 +938,12 @@ to using the share interface instead! See \fICURLOPT_SHARE\fP and
|
||
|
.IP CURLOPT_BUFFERSIZE
|
||
|
Pass a long specifying your preferred size (in bytes) for the receive buffer
|
||
|
in libcurl. The main point of this would be that the write callback gets
|
||
|
-called more often and with smaller chunks. This is just treated as a request,
|
||
|
-not an order. You cannot be guaranteed to actually get the given size. (Added
|
||
|
-in 7.10)
|
||
|
-
|
||
|
-This size is by default set as big as possible (CURL_MAX_WRITE_SIZE), so it
|
||
|
-only makes sense to use this option if you want it smaller.
|
||
|
+called more often and with smaller chunks. Secondly, for some protocols,
|
||
|
+there's a benefit of having a larger buffer for performance. This is just
|
||
|
+treated as a request, not an order. You cannot be guaranteed to actually get
|
||
|
+the given size. This buffer size is by default \fICURL_MAX_WRITE_SIZE\fP
|
||
|
+(16kB). The maximum buffer size allowed to set is \fICURL_MAX_READ_SIZE\fP
|
||
|
+(512kB). (Added in 7.10)
|
||
|
.IP CURLOPT_PORT
|
||
|
Pass a long specifying what remote port number to connect to, instead of the
|
||
|
one specified in the URL or the default port for the used protocol.
|
||
|
diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions
|
||
|
index b0b6232..e2cce4c 100644
|
||
|
--- a/docs/libcurl/symbols-in-versions
|
||
|
+++ b/docs/libcurl/symbols-in-versions
|
||
|
@@ -639,6 +639,7 @@ CURL_LOCK_TYPE_DNS 7.10 - 7.10.2
|
||
|
CURL_LOCK_TYPE_NONE 7.10 - 7.10.2
|
||
|
CURL_LOCK_TYPE_SSL_SESSION 7.10 - 7.10.2
|
||
|
CURL_MAX_HTTP_HEADER 7.19.7
|
||
|
+CURL_MAX_READ_SIZE 7.53.0
|
||
|
CURL_MAX_WRITE_SIZE 7.9.7
|
||
|
CURL_NETRC_IGNORED 7.9.8
|
||
|
CURL_NETRC_OPTIONAL 7.9.8
|
||
|
diff --git a/include/curl/curl.h b/include/curl/curl.h
|
||
|
index 0375a64..8b639fa 100644
|
||
|
--- a/include/curl/curl.h
|
||
|
+++ b/include/curl/curl.h
|
||
|
@@ -170,6 +170,11 @@ typedef int (*curl_progress_callback)(void *clientp,
|
||
|
double ultotal,
|
||
|
double ulnow);
|
||
|
|
||
|
+#ifndef CURL_MAX_READ_SIZE
|
||
|
+ /* The maximum receive buffer size configurable via CURLOPT_BUFFERSIZE. */
|
||
|
+#define CURL_MAX_READ_SIZE 524288
|
||
|
+#endif
|
||
|
+
|
||
|
#ifndef CURL_MAX_WRITE_SIZE
|
||
|
/* Tests have proven that 20K is a very bad buffer size for uploads on
|
||
|
Windows, while 16K for some odd reason performed a lot better.
|
||
|
diff --git a/lib/easy.c b/lib/easy.c
|
||
|
index 0e9ba18..5d4d5ae 100644
|
||
|
--- a/lib/easy.c
|
||
|
+++ b/lib/easy.c
|
||
|
@@ -563,6 +563,11 @@ CURL *curl_easy_duphandle(CURL *incurl)
|
||
|
* get setup on-demand in the code, as that would probably decrease
|
||
|
* the likeliness of us forgetting to init a buffer here in the future.
|
||
|
*/
|
||
|
+ outcurl->set.buffer_size = data->set.buffer_size;
|
||
|
+ outcurl->state.buffer = malloc(CURL_BUFSIZE(outcurl->set.buffer_size) + 1);
|
||
|
+ if(!outcurl->state.buffer)
|
||
|
+ goto fail;
|
||
|
+
|
||
|
outcurl->state.headerbuff = malloc(HEADERSIZE);
|
||
|
if(!outcurl->state.headerbuff)
|
||
|
goto fail;
|
||
|
@@ -633,6 +638,7 @@ CURL *curl_easy_duphandle(CURL *incurl)
|
||
|
if(outcurl) {
|
||
|
curl_slist_free_all(outcurl->change.cookielist);
|
||
|
outcurl->change.cookielist = NULL;
|
||
|
+ Curl_safefree(outcurl->state.buffer);
|
||
|
Curl_safefree(outcurl->state.headerbuff);
|
||
|
Curl_safefree(outcurl->change.url);
|
||
|
Curl_safefree(outcurl->change.referer);
|
||
|
diff --git a/lib/file.c b/lib/file.c
|
||
|
index 038bf42..1ad4758 100644
|
||
|
--- a/lib/file.c
|
||
|
+++ b/lib/file.c
|
||
|
@@ -473,7 +473,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
|
||
|
date. */
|
||
|
if(data->set.opt_no_body && data->set.include_header && fstated) {
|
||
|
CURLcode result;
|
||
|
- snprintf(buf, sizeof(data->state.buffer),
|
||
|
+ snprintf(buf, CURL_BUFSIZE(data->set.buffer_size),
|
||
|
"Content-Length: %" FORMAT_OFF_T "\r\n", expected_size);
|
||
|
result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
|
||
|
if(result)
|
||
|
diff --git a/lib/ftp.c b/lib/ftp.c
|
||
|
index a9826ce..730b695 100644
|
||
|
--- a/lib/ftp.c
|
||
|
+++ b/lib/ftp.c
|
||
|
@@ -2136,7 +2136,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
|
||
|
/* we have a time, reformat it */
|
||
|
time_t secs=time(NULL);
|
||
|
/* using the good old yacc/bison yuck */
|
||
|
- snprintf(buf, sizeof(conn->data->state.buffer),
|
||
|
+ snprintf(buf, CURL_BUFSIZE(conn->data->set.buffer_size),
|
||
|
"%04d%02d%02d %02d:%02d:%02d GMT",
|
||
|
year, month, day, hour, minute, second);
|
||
|
/* now, convert this into a time() value: */
|
||
|
@@ -2347,7 +2347,7 @@ static CURLcode ftp_state_size_resp(struct connectdata *conn,
|
||
|
if(instate == FTP_SIZE) {
|
||
|
#ifdef CURL_FTP_HTTPSTYLE_HEAD
|
||
|
if(-1 != filesize) {
|
||
|
- snprintf(buf, sizeof(data->state.buffer),
|
||
|
+ snprintf(buf, CURL_BUFSIZE(data->set.buffer_size),
|
||
|
"Content-Length: %" FORMAT_OFF_T "\r\n", filesize);
|
||
|
result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
|
||
|
if(result)
|
||
|
diff --git a/lib/http.c b/lib/http.c
|
||
|
index 1487fb2..f4368c4 100644
|
||
|
--- a/lib/http.c
|
||
|
+++ b/lib/http.c
|
||
|
@@ -247,7 +247,8 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
|
||
|
pwd = conn->passwd;
|
||
|
}
|
||
|
|
||
|
- snprintf(data->state.buffer, sizeof(data->state.buffer), "%s:%s", user, pwd);
|
||
|
+ snprintf(data->state.buffer, CURL_BUFSIZE(data->set.buffer_size),
|
||
|
+ "%s:%s", user, pwd);
|
||
|
|
||
|
error = Curl_base64_encode(data,
|
||
|
data->state.buffer, strlen(data->state.buffer),
|
||
|
diff --git a/lib/telnet.c b/lib/telnet.c
|
||
|
index 77d8b7b..89452dd 100644
|
||
|
--- a/lib/telnet.c
|
||
|
+++ b/lib/telnet.c
|
||
|
@@ -1421,6 +1421,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
|
||
|
|
||
|
/* Keep on listening and act on events */
|
||
|
while(keepon) {
|
||
|
+ const size_t buf_size = CURL_BUFSIZE(data->set.buffer_size);
|
||
|
waitret = WaitForMultipleObjects(obj_count, objs, FALSE, wait_timeout);
|
||
|
switch(waitret) {
|
||
|
case WAIT_TIMEOUT:
|
||
|
@@ -1455,7 +1456,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
|
||
|
if(!readfile_read)
|
||
|
break;
|
||
|
|
||
|
- if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),
|
||
|
+ if(!ReadFile(stdin_handle, buf, buf_size,
|
||
|
&readfile_read, NULL)) {
|
||
|
keepon = FALSE;
|
||
|
code = CURLE_READ_ERROR;
|
||
|
@@ -1474,7 +1475,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
|
||
|
|
||
|
case WAIT_OBJECT_0 + 1:
|
||
|
{
|
||
|
- if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),
|
||
|
+ if(!ReadFile(stdin_handle, buf, buf_size,
|
||
|
&readfile_read, NULL)) {
|
||
|
keepon = FALSE;
|
||
|
code = CURLE_READ_ERROR;
|
||
|
diff --git a/lib/url.c b/lib/url.c
|
||
|
index 89958a7..32e7e2e 100644
|
||
|
--- a/lib/url.c
|
||
|
+++ b/lib/url.c
|
||
|
@@ -441,6 +441,7 @@ CURLcode Curl_close(struct SessionHandle *data)
|
||
|
}
|
||
|
data->change.url = NULL;
|
||
|
|
||
|
+ Curl_safefree(data->state.buffer);
|
||
|
Curl_safefree(data->state.headerbuff);
|
||
|
|
||
|
Curl_flush_cookies(data, 1);
|
||
|
@@ -612,6 +613,12 @@ CURLcode Curl_open(struct SessionHandle **curl)
|
||
|
|
||
|
/* We do some initial setup here, all those fields that can't be just 0 */
|
||
|
|
||
|
+ data->state.buffer = malloc(BUFSIZE + 1);
|
||
|
+ if(!data->state.buffer) {
|
||
|
+ DEBUGF(fprintf(stderr, "Error: malloc of buffer failed\n"));
|
||
|
+ res = CURLE_OUT_OF_MEMORY;
|
||
|
+ }
|
||
|
+
|
||
|
data->state.headerbuff = malloc(HEADERSIZE);
|
||
|
if(!data->state.headerbuff) {
|
||
|
DEBUGF(fprintf(stderr, "Error: malloc of headerbuff failed\n"));
|
||
|
@@ -642,8 +649,8 @@ CURLcode Curl_open(struct SessionHandle **curl)
|
||
|
|
||
|
if(res) {
|
||
|
Curl_resolver_cleanup(data->state.resolver);
|
||
|
- if(data->state.headerbuff)
|
||
|
- free(data->state.headerbuff);
|
||
|
+ free(data->state.buffer);
|
||
|
+ free(data->state.headerbuff);
|
||
|
Curl_freeset(data);
|
||
|
free(data);
|
||
|
data = NULL;
|
||
|
@@ -1960,9 +1967,20 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
||
|
*/
|
||
|
data->set.buffer_size = va_arg(param, long);
|
||
|
|
||
|
- if((data->set.buffer_size> (BUFSIZE -1 )) ||
|
||
|
- (data->set.buffer_size < 1))
|
||
|
- data->set.buffer_size = 0; /* huge internal default */
|
||
|
+ if(data->set.buffer_size > MAX_BUFSIZE)
|
||
|
+ data->set.buffer_size = MAX_BUFSIZE; /* huge internal default */
|
||
|
+ else if(data->set.buffer_size < 1)
|
||
|
+ data->set.buffer_size = BUFSIZE;
|
||
|
+
|
||
|
+ /* Resize only if larger than default buffer size. */
|
||
|
+ if(data->set.buffer_size > BUFSIZE) {
|
||
|
+ data->state.buffer = realloc(data->state.buffer,
|
||
|
+ data->set.buffer_size + 1);
|
||
|
+ if(!data->state.buffer) {
|
||
|
+ DEBUGF(fprintf(stderr, "Error: realloc of buffer failed\n"));
|
||
|
+ result = CURLE_OUT_OF_MEMORY;
|
||
|
+ }
|
||
|
+ }
|
||
|
|
||
|
break;
|
||
|
|
||
|
diff --git a/lib/urldata.h b/lib/urldata.h
|
||
|
index 7431825..a7807cf 100644
|
||
|
--- a/lib/urldata.h
|
||
|
+++ b/lib/urldata.h
|
||
|
@@ -196,6 +196,9 @@
|
||
|
/* Download buffer size, keep it fairly big for speed reasons */
|
||
|
#undef BUFSIZE
|
||
|
#define BUFSIZE CURL_MAX_WRITE_SIZE
|
||
|
+#undef MAX_BUFSIZE
|
||
|
+#define MAX_BUFSIZE CURL_MAX_READ_SIZE
|
||
|
+#define CURL_BUFSIZE(x) ((x)?(x):(BUFSIZE))
|
||
|
|
||
|
/* Initial size of the buffer to store headers in, it'll be enlarged in case
|
||
|
of need. */
|
||
|
@@ -1174,7 +1177,7 @@ struct UrlState {
|
||
|
char *headerbuff; /* allocated buffer to store headers in */
|
||
|
size_t headersize; /* size of the allocation */
|
||
|
|
||
|
- char buffer[BUFSIZE+1]; /* download buffer */
|
||
|
+ char *buffer; /* download buffer */
|
||
|
char uploadbuffer[BUFSIZE+1]; /* upload buffer */
|
||
|
curl_off_t current_speed; /* the ProgressShow() funcion sets this,
|
||
|
bytes / second */
|
||
|
--
|
||
|
2.14.3
|
||
|
|
||
|
|
||
|
From f175a713c964d351012baaf8c78c1b468cc6aba0 Mon Sep 17 00:00:00 2001
|
||
|
From: Daniel Stenberg <daniel@haxx.se>
|
||
|
Date: Mon, 24 Apr 2017 15:33:57 +0200
|
||
|
Subject: [PATCH 2/7] http: use private user:password output buffer
|
||
|
|
||
|
Don't clobber the receive buffer.
|
||
|
|
||
|
Upstream-commit: 94460878cc634b590a7282e3fe60ceafb62d141a
|
||
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
||
|
---
|
||
|
lib/http.c | 32 +++++++++++++++++++-------------
|
||
|
1 file changed, 19 insertions(+), 13 deletions(-)
|
||
|
|
||
|
diff --git a/lib/http.c b/lib/http.c
|
||
|
index f4368c4..12e7dc3 100644
|
||
|
--- a/lib/http.c
|
||
|
+++ b/lib/http.c
|
||
|
@@ -234,7 +234,8 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
|
||
|
char **userp;
|
||
|
const char *user;
|
||
|
const char *pwd;
|
||
|
- CURLcode error;
|
||
|
+ CURLcode result;
|
||
|
+ char *out;
|
||
|
|
||
|
if(proxy) {
|
||
|
userp = &conn->allocptr.proxyuserpwd;
|
||
|
@@ -247,27 +248,32 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
|
||
|
pwd = conn->passwd;
|
||
|
}
|
||
|
|
||
|
- snprintf(data->state.buffer, CURL_BUFSIZE(data->set.buffer_size),
|
||
|
- "%s:%s", user, pwd);
|
||
|
+ out = aprintf("%s:%s", user, pwd);
|
||
|
+ if(!out)
|
||
|
+ return CURLE_OUT_OF_MEMORY;
|
||
|
|
||
|
- error = Curl_base64_encode(data,
|
||
|
- data->state.buffer, strlen(data->state.buffer),
|
||
|
- &authorization, &size);
|
||
|
- if(error)
|
||
|
- return error;
|
||
|
+ result = Curl_base64_encode(data, out, strlen(out), &authorization, &size);
|
||
|
+ if(result)
|
||
|
+ goto fail;
|
||
|
|
||
|
- if(!authorization)
|
||
|
- return CURLE_REMOTE_ACCESS_DENIED;
|
||
|
+ if(!authorization) {
|
||
|
+ result = CURLE_REMOTE_ACCESS_DENIED;
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
|
||
|
Curl_safefree(*userp);
|
||
|
*userp = aprintf("%sAuthorization: Basic %s\r\n",
|
||
|
proxy?"Proxy-":"",
|
||
|
authorization);
|
||
|
free(authorization);
|
||
|
- if(!*userp)
|
||
|
- return CURLE_OUT_OF_MEMORY;
|
||
|
+ if(!*userp) {
|
||
|
+ result = CURLE_OUT_OF_MEMORY;
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
|
||
|
- return CURLE_OK;
|
||
|
+ fail:
|
||
|
+ free(out);
|
||
|
+ return result;
|
||
|
}
|
||
|
|
||
|
/* pickoneauth() selects the most favourable authentication method from the
|
||
|
--
|
||
|
2.14.3
|
||
|
|
||
|
|
||
|
From 6ff175806c338223a2a9a69f6ae8ae2b91dc2b56 Mon Sep 17 00:00:00 2001
|
||
|
From: Daniel Stenberg <daniel@haxx.se>
|
||
|
Date: Mon, 24 Apr 2017 16:05:46 +0200
|
||
|
Subject: [PATCH 3/7] ftp: use private buffer for temp storage, not receive
|
||
|
buffer
|
||
|
|
||
|
Upstream-commit: 349789e645a306a6ee467ef90a57f6cc306ca92e
|
||
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
||
|
---
|
||
|
lib/ftp.c | 22 ++++++++++++----------
|
||
|
1 file changed, 12 insertions(+), 10 deletions(-)
|
||
|
|
||
|
diff --git a/lib/ftp.c b/lib/ftp.c
|
||
|
index 730b695..10a21ce 100644
|
||
|
--- a/lib/ftp.c
|
||
|
+++ b/lib/ftp.c
|
||
|
@@ -2130,17 +2130,17 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
|
||
|
/* we got a time. Format should be: "YYYYMMDDHHMMSS[.sss]" where the
|
||
|
last .sss part is optional and means fractions of a second */
|
||
|
int year, month, day, hour, minute, second;
|
||
|
- char *buf = data->state.buffer;
|
||
|
- if(6 == sscanf(buf+4, "%04d%02d%02d%02d%02d%02d",
|
||
|
+ if(6 == sscanf(&data->state.buffer[4], "%04d%02d%02d%02d%02d%02d",
|
||
|
&year, &month, &day, &hour, &minute, &second)) {
|
||
|
/* we have a time, reformat it */
|
||
|
+ char timebuf[24];
|
||
|
time_t secs=time(NULL);
|
||
|
- /* using the good old yacc/bison yuck */
|
||
|
- snprintf(buf, CURL_BUFSIZE(conn->data->set.buffer_size),
|
||
|
+
|
||
|
+ snprintf(timebuf, sizeof(timebuf),
|
||
|
"%04d%02d%02d %02d:%02d:%02d GMT",
|
||
|
year, month, day, hour, minute, second);
|
||
|
/* now, convert this into a time() value: */
|
||
|
- data->info.filetime = (long)curl_getdate(buf, &secs);
|
||
|
+ data->info.filetime = (long)curl_getdate(timebuf, &secs);
|
||
|
}
|
||
|
|
||
|
#ifdef CURL_FTP_HTTPSTYLE_HEAD
|
||
|
@@ -2151,6 +2151,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
|
||
|
ftpc->file &&
|
||
|
data->set.get_filetime &&
|
||
|
(data->info.filetime>=0) ) {
|
||
|
+ char headerbuf[128];
|
||
|
time_t filetime = (time_t)data->info.filetime;
|
||
|
struct tm buffer;
|
||
|
const struct tm *tm = &buffer;
|
||
|
@@ -2160,7 +2161,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
|
||
|
return result;
|
||
|
|
||
|
/* format: "Tue, 15 Nov 1994 12:45:26" */
|
||
|
- snprintf(buf, BUFSIZE-1,
|
||
|
+ snprintf(headerbuf, sizeof(headerbuf),
|
||
|
"Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
|
||
|
Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
|
||
|
tm->tm_mday,
|
||
|
@@ -2169,7 +2170,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
|
||
|
tm->tm_hour,
|
||
|
tm->tm_min,
|
||
|
tm->tm_sec);
|
||
|
- result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
|
||
|
+ result = Curl_client_write(conn, CLIENTWRITE_BOTH, headerbuf, 0);
|
||
|
if(result)
|
||
|
return result;
|
||
|
} /* end of a ridiculous amount of conditionals */
|
||
|
@@ -2347,9 +2348,10 @@ static CURLcode ftp_state_size_resp(struct connectdata *conn,
|
||
|
if(instate == FTP_SIZE) {
|
||
|
#ifdef CURL_FTP_HTTPSTYLE_HEAD
|
||
|
if(-1 != filesize) {
|
||
|
- snprintf(buf, CURL_BUFSIZE(data->set.buffer_size),
|
||
|
+ char clbuf[128];
|
||
|
+ snprintf(clbuf, sizeof(clbuf),
|
||
|
"Content-Length: %" FORMAT_OFF_T "\r\n", filesize);
|
||
|
- result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
|
||
|
+ result = Curl_client_write(conn, CLIENTWRITE_BOTH, clbuf, 0);
|
||
|
if(result)
|
||
|
return result;
|
||
|
}
|
||
|
@@ -2450,7 +2452,6 @@ static CURLcode ftp_state_get_resp(struct connectdata *conn,
|
||
|
CURLcode result = CURLE_OK;
|
||
|
struct SessionHandle *data = conn->data;
|
||
|
struct FTP *ftp = data->state.proto.ftp;
|
||
|
- char *buf = data->state.buffer;
|
||
|
|
||
|
if((ftpcode == 150) || (ftpcode == 125)) {
|
||
|
|
||
|
@@ -2494,6 +2495,7 @@ static CURLcode ftp_state_get_resp(struct connectdata *conn,
|
||
|
*
|
||
|
* Example D above makes this parsing a little tricky */
|
||
|
char *bytes;
|
||
|
+ char *buf = data->state.buffer;
|
||
|
bytes=strstr(buf, " bytes");
|
||
|
if(bytes--) {
|
||
|
long in=(long)(bytes-buf);
|
||
|
--
|
||
|
2.14.3
|
||
|
|
||
|
|
||
|
From b67324919089fc4f9bb7a38a6a31174883a4bc24 Mon Sep 17 00:00:00 2001
|
||
|
From: Daniel Stenberg <daniel@haxx.se>
|
||
|
Date: Tue, 25 Apr 2017 00:09:22 +0200
|
||
|
Subject: [PATCH 4/7] CURLOPT_BUFFERSIZE: 1024 bytes is now the minimum size
|
||
|
|
||
|
The buffer is needed to receive FTP, HTTP CONNECT responses etc so
|
||
|
already at this size things risk breaking and smaller is certainly not
|
||
|
wise.
|
||
|
|
||
|
Upstream-commit: c2ddc12d6086b522703c8b80a72ab791680f1a28
|
||
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
||
|
---
|
||
|
lib/url.c | 15 +++++++++------
|
||
|
lib/urldata.h | 1 +
|
||
|
2 files changed, 10 insertions(+), 6 deletions(-)
|
||
|
|
||
|
diff --git a/lib/url.c b/lib/url.c
|
||
|
index 32e7e2e..f87dca4 100644
|
||
|
--- a/lib/url.c
|
||
|
+++ b/lib/url.c
|
||
|
@@ -1965,15 +1965,17 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
||
|
* The application kindly asks for a differently sized receive buffer.
|
||
|
* If it seems reasonable, we'll use it.
|
||
|
*/
|
||
|
- data->set.buffer_size = va_arg(param, long);
|
||
|
+ arg = va_arg(param, long);
|
||
|
|
||
|
- if(data->set.buffer_size > MAX_BUFSIZE)
|
||
|
- data->set.buffer_size = MAX_BUFSIZE; /* huge internal default */
|
||
|
- else if(data->set.buffer_size < 1)
|
||
|
- data->set.buffer_size = BUFSIZE;
|
||
|
+ if(arg > MAX_BUFSIZE)
|
||
|
+ arg = MAX_BUFSIZE; /* huge internal default */
|
||
|
+ else if(arg < 1)
|
||
|
+ arg = BUFSIZE;
|
||
|
+ else if(arg < MIN_BUFSIZE)
|
||
|
+ arg = BUFSIZE;
|
||
|
|
||
|
/* Resize only if larger than default buffer size. */
|
||
|
- if(data->set.buffer_size > BUFSIZE) {
|
||
|
+ if(arg > BUFSIZE) {
|
||
|
data->state.buffer = realloc(data->state.buffer,
|
||
|
data->set.buffer_size + 1);
|
||
|
if(!data->state.buffer) {
|
||
|
@@ -1981,6 +1983,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
||
|
result = CURLE_OUT_OF_MEMORY;
|
||
|
}
|
||
|
}
|
||
|
+ data->set.buffer_size = arg;
|
||
|
|
||
|
break;
|
||
|
|
||
|
diff --git a/lib/urldata.h b/lib/urldata.h
|
||
|
index a7807cf..cd96e8f 100644
|
||
|
--- a/lib/urldata.h
|
||
|
+++ b/lib/urldata.h
|
||
|
@@ -198,6 +198,7 @@
|
||
|
#define BUFSIZE CURL_MAX_WRITE_SIZE
|
||
|
#undef MAX_BUFSIZE
|
||
|
#define MAX_BUFSIZE CURL_MAX_READ_SIZE
|
||
|
+#define MIN_BUFSIZE 1024
|
||
|
#define CURL_BUFSIZE(x) ((x)?(x):(BUFSIZE))
|
||
|
|
||
|
/* Initial size of the buffer to store headers in, it'll be enlarged in case
|
||
|
--
|
||
|
2.14.3
|
||
|
|
||
|
|
||
|
From 9798012315c087168c5a4a1dc56eacfe82c69626 Mon Sep 17 00:00:00 2001
|
||
|
From: Daniel Stenberg <daniel@haxx.se>
|
||
|
Date: Tue, 25 Apr 2017 00:15:28 +0200
|
||
|
Subject: [PATCH 5/7] file: use private buffer for C-L output
|
||
|
|
||
|
... instead of clobbering the download buffer.
|
||
|
|
||
|
Upstream-commit: 7c312f84ea930d89c0f0f774b50032c4f9ae30e4
|
||
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
||
|
---
|
||
|
lib/file.c | 7 ++++---
|
||
|
1 file changed, 4 insertions(+), 3 deletions(-)
|
||
|
|
||
|
diff --git a/lib/file.c b/lib/file.c
|
||
|
index 1ad4758..b6bf18e 100644
|
||
|
--- a/lib/file.c
|
||
|
+++ b/lib/file.c
|
||
|
@@ -473,9 +473,10 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
|
||
|
date. */
|
||
|
if(data->set.opt_no_body && data->set.include_header && fstated) {
|
||
|
CURLcode result;
|
||
|
- snprintf(buf, CURL_BUFSIZE(data->set.buffer_size),
|
||
|
+ char header[80];
|
||
|
+ snprintf(header, sizeof(header),
|
||
|
"Content-Length: %" FORMAT_OFF_T "\r\n", expected_size);
|
||
|
- result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
|
||
|
+ result = Curl_client_write(conn, CLIENTWRITE_BOTH, header, 0);
|
||
|
if(result)
|
||
|
return result;
|
||
|
|
||
|
@@ -493,7 +494,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
|
||
|
return result;
|
||
|
|
||
|
/* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
|
||
|
- snprintf(buf, BUFSIZE-1,
|
||
|
+ snprintf(header, sizeof(header),
|
||
|
"Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
|
||
|
Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
|
||
|
tm->tm_mday,
|
||
|
--
|
||
|
2.14.3
|
||
|
|
||
|
|
||
|
From f4868e737e9f8d719cb9897506da2c7f92dfd87d Mon Sep 17 00:00:00 2001
|
||
|
From: Daniel Stenberg <daniel@haxx.se>
|
||
|
Date: Tue, 25 Apr 2017 00:16:10 +0200
|
||
|
Subject: [PATCH 6/7] buffer_size: make sure it always has the correct size
|
||
|
|
||
|
Removes the need for CURL_BUFSIZE
|
||
|
|
||
|
Upstream-commit: f535f4f5fc6cbdce1aec5a3481cec37369dca468
|
||
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
||
|
---
|
||
|
lib/easy.c | 2 +-
|
||
|
lib/telnet.c | 2 +-
|
||
|
lib/url.c | 2 ++
|
||
|
lib/urldata.h | 1 -
|
||
|
4 files changed, 4 insertions(+), 3 deletions(-)
|
||
|
|
||
|
diff --git a/lib/easy.c b/lib/easy.c
|
||
|
index 5d4d5ae..9cad5f1 100644
|
||
|
--- a/lib/easy.c
|
||
|
+++ b/lib/easy.c
|
||
|
@@ -564,7 +564,7 @@ CURL *curl_easy_duphandle(CURL *incurl)
|
||
|
* the likeliness of us forgetting to init a buffer here in the future.
|
||
|
*/
|
||
|
outcurl->set.buffer_size = data->set.buffer_size;
|
||
|
- outcurl->state.buffer = malloc(CURL_BUFSIZE(outcurl->set.buffer_size) + 1);
|
||
|
+ outcurl->state.buffer = malloc(outcurl->set.buffer_size + 1);
|
||
|
if(!outcurl->state.buffer)
|
||
|
goto fail;
|
||
|
|
||
|
diff --git a/lib/telnet.c b/lib/telnet.c
|
||
|
index 89452dd..e43b423 100644
|
||
|
--- a/lib/telnet.c
|
||
|
+++ b/lib/telnet.c
|
||
|
@@ -1421,7 +1421,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
|
||
|
|
||
|
/* Keep on listening and act on events */
|
||
|
while(keepon) {
|
||
|
- const size_t buf_size = CURL_BUFSIZE(data->set.buffer_size);
|
||
|
+ const size_t buf_size = (DWORD)data->set.buffer_size;
|
||
|
waitret = WaitForMultipleObjects(obj_count, objs, FALSE, wait_timeout);
|
||
|
switch(waitret) {
|
||
|
case WAIT_TIMEOUT:
|
||
|
diff --git a/lib/url.c b/lib/url.c
|
||
|
index f87dca4..81de7c2 100644
|
||
|
--- a/lib/url.c
|
||
|
+++ b/lib/url.c
|
||
|
@@ -577,6 +577,8 @@ CURLcode Curl_init_userdefined(struct UserDefined *set)
|
||
|
set->tcp_keepintvl = 60;
|
||
|
set->tcp_keepidle = 60;
|
||
|
|
||
|
+ set->buffer_size = BUFSIZE;
|
||
|
+
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
diff --git a/lib/urldata.h b/lib/urldata.h
|
||
|
index cd96e8f..fbe69c2 100644
|
||
|
--- a/lib/urldata.h
|
||
|
+++ b/lib/urldata.h
|
||
|
@@ -199,7 +199,6 @@
|
||
|
#undef MAX_BUFSIZE
|
||
|
#define MAX_BUFSIZE CURL_MAX_READ_SIZE
|
||
|
#define MIN_BUFSIZE 1024
|
||
|
-#define CURL_BUFSIZE(x) ((x)?(x):(BUFSIZE))
|
||
|
|
||
|
/* Initial size of the buffer to store headers in, it'll be enlarged in case
|
||
|
of need. */
|
||
|
--
|
||
|
2.14.3
|
||
|
|
||
|
|
||
|
From 9f3810bae5fad685e848a39750863557e17a0163 Mon Sep 17 00:00:00 2001
|
||
|
From: Daniel Stenberg <daniel@haxx.se>
|
||
|
Date: Thu, 8 Mar 2018 10:33:16 +0100
|
||
|
Subject: [PATCH 7/7] readwrite: make sure excess reads don't go beyond buffer
|
||
|
end
|
||
|
|
||
|
CVE-2018-1000122
|
||
|
Bug: https://curl.haxx.se/docs/adv_2018-b047.html
|
||
|
|
||
|
Detected by OSS-fuzz
|
||
|
|
||
|
Upstream-commit: d52dc4760f6d9ca1937eefa2093058a952465128
|
||
|
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
||
|
---
|
||
|
lib/transfer.c | 9 +++++++--
|
||
|
1 file changed, 7 insertions(+), 2 deletions(-)
|
||
|
|
||
|
diff --git a/lib/transfer.c b/lib/transfer.c
|
||
|
index dff6838..7ad6e3c 100644
|
||
|
--- a/lib/transfer.c
|
||
|
+++ b/lib/transfer.c
|
||
|
@@ -738,10 +738,15 @@ static CURLcode readwrite_data(struct SessionHandle *data,
|
||
|
|
||
|
} /* if(! header and data to read ) */
|
||
|
|
||
|
- if(conn->handler->readwrite &&
|
||
|
- (excess > 0 && !conn->bits.stream_was_rewound)) {
|
||
|
+ if(conn->handler->readwrite && excess && !conn->bits.stream_was_rewound) {
|
||
|
/* Parse the excess data */
|
||
|
k->str += nread;
|
||
|
+
|
||
|
+ if(&k->str[excess] > &k->buf[data->set.buffer_size]) {
|
||
|
+ /* the excess amount was too excessive(!), make sure
|
||
|
+ it doesn't read out of buffer */
|
||
|
+ excess = &k->buf[data->set.buffer_size] - k->str;
|
||
|
+ }
|
||
|
nread = (ssize_t)excess;
|
||
|
|
||
|
result = conn->handler->readwrite(data, conn, &nread, &readmore);
|
||
|
--
|
||
|
2.14.3
|
||
|
|