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.
667 lines
24 KiB
667 lines
24 KiB
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 |
|
|
|
|