examples: safer and more proper read callback logic

The same callback code is used in:

 imap-append.c
 smtp-authzid.c
 smtp-mail.c
 smtp-multi.c
 smtp-ssl.c
 smtp-tls.c

It should not assume that it can copy full lines into the buffer as it
will encourage sloppy coding practices. Instead use byte-wise logic and
check/acknowledge the buffer size appropriately.

Reported-by: Harry Sintonen
Fixes #7330
Closes #7331
This commit is contained in:
Daniel Stenberg 2021-07-01 09:21:40 +02:00
parent 07fa74d34a
commit a37fc62e8b
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
6 changed files with 139 additions and 149 deletions

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2021, 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
@ -39,41 +39,42 @@
#define TO "<addressee@example.net>"
#define CC "<info@example.org>"
static const char *payload_text[] = {
"Date: Mon, 29 Nov 2010 21:54:29 +1100\r\n",
"To: " TO "\r\n",
"From: " FROM "(Example User)\r\n",
"Cc: " CC "(Another example User)\r\n",
static const char *payload_text =
"Date: Mon, 29 Nov 2010 21:54:29 +1100\r\n"
"To: " TO "\r\n"
"From: " FROM "(Example User)\r\n"
"Cc: " CC "(Another example User)\r\n"
"Message-ID: "
"<dcd7cb36-11db-487a-9f3a-e652a9458efd@rfcpedant.example.org>\r\n",
"Subject: IMAP example message\r\n",
"\r\n", /* empty line to divide headers from body, see RFC5322 */
"The body of the message starts here.\r\n",
"\r\n",
"It could be a lot of lines, could be MIME encoded, whatever.\r\n",
"Check RFC5322.\r\n",
NULL
};
"<dcd7cb36-11db-487a-9f3a-e652a9458efd@rfcpedant.example.org>\r\n"
"Subject: IMAP example message\r\n"
"\r\n" /* empty line to divide headers from body, see RFC5322 */
"The body of the message starts here.\r\n"
"\r\n"
"It could be a lot of lines, could be MIME encoded, whatever.\r\n"
"Check RFC5322.\r\n";
struct upload_status {
int lines_read;
size_t bytes_read;
};
static size_t payload_source(char *ptr, size_t size, size_t nmemb, void *userp)
{
struct upload_status *upload_ctx = (struct upload_status *)userp;
const char *data;
size_t room = size * nmemb;
if((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {
return 0;
}
data = payload_text[upload_ctx->lines_read];
data = &payload_text[upload_ctx->bytes_read];
if(data) {
size_t len = strlen(data);
if(room < len)
len = room;
memcpy(ptr, data, len);
upload_ctx->lines_read++;
upload_ctx->bytes_read += len;
return len;
}
@ -88,11 +89,8 @@ int main(void)
curl = curl_easy_init();
if(curl) {
const char **p;
long infilesize;
struct upload_status upload_ctx;
upload_ctx.lines_read = 0;
struct upload_status upload_ctx = { 0 };
/* Set username and password */
curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
@ -110,10 +108,7 @@ int main(void)
curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx);
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
infilesize = 0;
for(p = payload_text; *p; ++p) {
infilesize += (long)strlen(*p);
}
infilesize = strlen(payload_text);
curl_easy_setopt(curl, CURLOPT_INFILESIZE, infilesize);
/* Perform the append */

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2021, 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
@ -47,41 +47,42 @@
#define SENDER_MAIL "Kurt " SENDER_ADDR
#define TO_MAIL "A Receiver " TO_ADDR
static const char *payload_text[] = {
"Date: Mon, 29 Nov 2010 21:54:29 +1100\r\n",
"To: " TO_MAIL "\r\n",
"From: " FROM_MAIL "\r\n",
"Sender: " SENDER_MAIL "\r\n",
static const char *payload_text =
"Date: Mon, 29 Nov 2010 21:54:29 +1100\r\n"
"To: " TO_MAIL "\r\n"
"From: " FROM_MAIL "\r\n"
"Sender: " SENDER_MAIL "\r\n"
"Message-ID: <dcd7cb36-11db-487a-9f3a-e652a9458efd@"
"rfcpedant.example.org>\r\n",
"Subject: SMTP example message\r\n",
"\r\n", /* empty line to divide headers from body, see RFC5322 */
"The body of the message starts here.\r\n",
"\r\n",
"It could be a lot of lines, could be MIME encoded, whatever.\r\n",
"Check RFC5322.\r\n",
NULL
};
"rfcpedant.example.org>\r\n"
"Subject: SMTP example message\r\n"
"\r\n" /* empty line to divide headers from body, see RFC5322 */
"The body of the message starts here.\r\n"
"\r\n"
"It could be a lot of lines, could be MIME encoded, whatever.\r\n"
"Check RFC5322.\r\n";
struct upload_status {
int lines_read;
size_t bytes_read;
};
static size_t payload_source(char *ptr, size_t size, size_t nmemb, void *userp)
{
struct upload_status *upload_ctx = (struct upload_status *)userp;
const char *data;
size_t room = size * nmemb;
if((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {
return 0;
}
data = payload_text[upload_ctx->lines_read];
data = &payload_text[upload_ctx->bytes_read];
if(data) {
size_t len = strlen(data);
if(room < len)
len = room;
memcpy(ptr, data, len);
upload_ctx->lines_read++;
upload_ctx->bytes_read += len;
return len;
}
@ -94,9 +95,7 @@ int main(void)
CURL *curl;
CURLcode res = CURLE_OK;
struct curl_slist *recipients = NULL;
struct upload_status upload_ctx;
upload_ctx.lines_read = 0;
struct upload_status upload_ctx = { 0 };
curl = curl_easy_init();
if(curl) {

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2021, 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
@ -44,41 +44,42 @@
#define TO_MAIL "A Receiver " TO_ADDR
#define CC_MAIL "John CC Smith " CC_ADDR
static const char *payload_text[] = {
"Date: Mon, 29 Nov 2010 21:54:29 +1100\r\n",
"To: " TO_MAIL "\r\n",
"From: " FROM_MAIL "\r\n",
"Cc: " CC_MAIL "\r\n",
static const char *payload_text =
"Date: Mon, 29 Nov 2010 21:54:29 +1100\r\n"
"To: " TO_MAIL "\r\n"
"From: " FROM_MAIL "\r\n"
"Cc: " CC_MAIL "\r\n"
"Message-ID: <dcd7cb36-11db-487a-9f3a-e652a9458efd@"
"rfcpedant.example.org>\r\n",
"Subject: SMTP example message\r\n",
"\r\n", /* empty line to divide headers from body, see RFC5322 */
"The body of the message starts here.\r\n",
"\r\n",
"It could be a lot of lines, could be MIME encoded, whatever.\r\n",
"Check RFC5322.\r\n",
NULL
};
"rfcpedant.example.org>\r\n"
"Subject: SMTP example message\r\n"
"\r\n" /* empty line to divide headers from body, see RFC5322 */
"The body of the message starts here.\r\n"
"\r\n"
"It could be a lot of lines, could be MIME encoded, whatever.\r\n"
"Check RFC5322.\r\n";
struct upload_status {
int lines_read;
size_t bytes_read;
};
static size_t payload_source(char *ptr, size_t size, size_t nmemb, void *userp)
{
struct upload_status *upload_ctx = (struct upload_status *)userp;
const char *data;
size_t room = size * nmemb;
if((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {
return 0;
}
data = payload_text[upload_ctx->lines_read];
data = &payload_text[upload_ctx->bytes_read];
if(data) {
size_t len = strlen(data);
if(room < len)
len = room;
memcpy(ptr, data, len);
upload_ctx->lines_read++;
upload_ctx->bytes_read += len;
return len;
}
@ -91,9 +92,7 @@ int main(void)
CURL *curl;
CURLcode res = CURLE_OK;
struct curl_slist *recipients = NULL;
struct upload_status upload_ctx;
upload_ctx.lines_read = 0;
struct upload_status upload_ctx = { 0 };
curl = curl_easy_init();
if(curl) {

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2021, 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
@ -35,47 +35,48 @@
* Note that this example requires libcurl 7.20.0 or above.
*/
#define FROM "<sender@example.com>"
#define TO "<recipient@example.com>"
#define CC "<info@example.com>"
#define FROM_MAIL "<sender@example.com>"
#define TO_MAIL "<recipient@example.com>"
#define CC_MAIL "<info@example.com>"
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
static const char *payload_text[] = {
"Date: Mon, 29 Nov 2010 21:54:29 +1100\r\n",
"To: " TO "\r\n",
"From: " FROM " (Example User)\r\n",
"Cc: " CC " (Another example User)\r\n",
static const char *payload_text =
"Date: Mon, 29 Nov 2010 21:54:29 +1100\r\n"
"To: " TO_MAIL "\r\n"
"From: " FROM_MAIL "\r\n"
"Cc: " CC_MAIL "\r\n"
"Message-ID: <dcd7cb36-11db-487a-9f3a-e652a9458efd@"
"rfcpedant.example.org>\r\n",
"Subject: SMTP multi example message\r\n",
"\r\n", /* empty line to divide headers from body, see RFC5322 */
"The body of the message starts here.\r\n",
"\r\n",
"It could be a lot of lines, could be MIME encoded, whatever.\r\n",
"Check RFC5322.\r\n",
NULL
};
"rfcpedant.example.org>\r\n"
"Subject: SMTP example message\r\n"
"\r\n" /* empty line to divide headers from body, see RFC5322 */
"The body of the message starts here.\r\n"
"\r\n"
"It could be a lot of lines, could be MIME encoded, whatever.\r\n"
"Check RFC5322.\r\n";
struct upload_status {
int lines_read;
size_t bytes_read;
};
static size_t payload_source(char *ptr, size_t size, size_t nmemb, void *userp)
{
struct upload_status *upload_ctx = (struct upload_status *)userp;
const char *data;
size_t room = size * nmemb;
if((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {
return 0;
}
data = payload_text[upload_ctx->lines_read];
data = &payload_text[upload_ctx->bytes_read];
if(data) {
size_t len = strlen(data);
if(room < len)
len = room;
memcpy(ptr, data, len);
upload_ctx->lines_read++;
upload_ctx->bytes_read += len;
return len;
}
@ -107,9 +108,7 @@ int main(void)
int still_running = 1;
struct timeval mp_start;
struct curl_slist *recipients = NULL;
struct upload_status upload_ctx;
upload_ctx.lines_read = 0;
struct upload_status upload_ctx = { 0 };
curl_global_init(CURL_GLOBAL_DEFAULT);
@ -130,13 +129,13 @@ int main(void)
* to the address in the reverse-path which triggered them. Otherwise, they
* could cause an endless loop. See RFC 5321 Section 4.5.5 for more details.
*/
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM);
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM_MAIL);
/* Add two recipients, in this particular case they correspond to the
* To: and Cc: addressees in the header, but they could be any kind of
* recipient. */
recipients = curl_slist_append(recipients, TO);
recipients = curl_slist_append(recipients, CC);
recipients = curl_slist_append(recipients, TO_MAIL);
recipients = curl_slist_append(recipients, CC_MAIL);
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);
/* We're using a callback function to specify the payload (the headers and

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2021, 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
@ -37,45 +37,46 @@
* Note that this example requires libcurl 7.20.0 or above.
*/
#define FROM "<sender@example.org>"
#define TO "<addressee@example.net>"
#define CC "<info@example.org>"
#define FROM_MAIL "<sender@example.com>"
#define TO_MAIL "<recipient@example.com>"
#define CC_MAIL "<info@example.com>"
static const char *payload_text[] = {
"Date: Mon, 29 Nov 2010 21:54:29 +1100\r\n",
"To: " TO "\r\n",
"From: " FROM " (Example User)\r\n",
"Cc: " CC " (Another example User)\r\n",
static const char *payload_text =
"Date: Mon, 29 Nov 2010 21:54:29 +1100\r\n"
"To: " TO_MAIL "\r\n"
"From: " FROM_MAIL "\r\n"
"Cc: " CC_MAIL "\r\n"
"Message-ID: <dcd7cb36-11db-487a-9f3a-e652a9458efd@"
"rfcpedant.example.org>\r\n",
"Subject: SMTP SSL example message\r\n",
"\r\n", /* empty line to divide headers from body, see RFC5322 */
"The body of the message starts here.\r\n",
"\r\n",
"It could be a lot of lines, could be MIME encoded, whatever.\r\n",
"Check RFC5322.\r\n",
NULL
};
"rfcpedant.example.org>\r\n"
"Subject: SMTP example message\r\n"
"\r\n" /* empty line to divide headers from body, see RFC5322 */
"The body of the message starts here.\r\n"
"\r\n"
"It could be a lot of lines, could be MIME encoded, whatever.\r\n"
"Check RFC5322.\r\n";
struct upload_status {
int lines_read;
size_t bytes_read;
};
static size_t payload_source(char *ptr, size_t size, size_t nmemb, void *userp)
{
struct upload_status *upload_ctx = (struct upload_status *)userp;
const char *data;
size_t room = size * nmemb;
if((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {
return 0;
}
data = payload_text[upload_ctx->lines_read];
data = &payload_text[upload_ctx->bytes_read];
if(data) {
size_t len = strlen(data);
if(room < len)
len = room;
memcpy(ptr, data, len);
upload_ctx->lines_read++;
upload_ctx->bytes_read += len;
return len;
}
@ -88,9 +89,7 @@ int main(void)
CURL *curl;
CURLcode res = CURLE_OK;
struct curl_slist *recipients = NULL;
struct upload_status upload_ctx;
upload_ctx.lines_read = 0;
struct upload_status upload_ctx = { 0 };
curl = curl_easy_init();
if(curl) {
@ -129,13 +128,13 @@ int main(void)
* they could cause an endless loop. See RFC 5321 Section 4.5.5 for more
* details.
*/
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM);
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM_MAIL);
/* Add two recipients, in this particular case they correspond to the
* To: and Cc: addressees in the header, but they could be any kind of
* recipient. */
recipients = curl_slist_append(recipients, TO);
recipients = curl_slist_append(recipients, CC);
recipients = curl_slist_append(recipients, TO_MAIL);
recipients = curl_slist_append(recipients, CC_MAIL);
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);
/* We're using a callback function to specify the payload (the headers and

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2021, 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
@ -37,45 +37,46 @@
* Note that this example requires libcurl 7.20.0 or above.
*/
#define FROM "<sender@example.org>"
#define TO "<addressee@example.net>"
#define CC "<info@example.org>"
#define FROM_MAIL "<sender@example.com>"
#define TO_MAIL "<recipient@example.com>"
#define CC_MAIL "<info@example.com>"
static const char *payload_text[] = {
"Date: Mon, 29 Nov 2010 21:54:29 +1100\r\n",
"To: " TO "\r\n",
"From: " FROM " (Example User)\r\n",
"Cc: " CC " (Another example User)\r\n",
static const char *payload_text =
"Date: Mon, 29 Nov 2010 21:54:29 +1100\r\n"
"To: " TO_MAIL "\r\n"
"From: " FROM_MAIL "\r\n"
"Cc: " CC_MAIL "\r\n"
"Message-ID: <dcd7cb36-11db-487a-9f3a-e652a9458efd@"
"rfcpedant.example.org>\r\n",
"Subject: SMTP TLS example message\r\n",
"\r\n", /* empty line to divide headers from body, see RFC5322 */
"The body of the message starts here.\r\n",
"\r\n",
"It could be a lot of lines, could be MIME encoded, whatever.\r\n",
"Check RFC5322.\r\n",
NULL
};
"rfcpedant.example.org>\r\n"
"Subject: SMTP example message\r\n"
"\r\n" /* empty line to divide headers from body, see RFC5322 */
"The body of the message starts here.\r\n"
"\r\n"
"It could be a lot of lines, could be MIME encoded, whatever.\r\n"
"Check RFC5322.\r\n";
struct upload_status {
int lines_read;
size_t bytes_read;
};
static size_t payload_source(char *ptr, size_t size, size_t nmemb, void *userp)
{
struct upload_status *upload_ctx = (struct upload_status *)userp;
const char *data;
size_t room = size * nmemb;
if((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {
return 0;
}
data = payload_text[upload_ctx->lines_read];
data = &payload_text[upload_ctx->bytes_read];
if(data) {
size_t len = strlen(data);
if(room < len)
len = room;
memcpy(ptr, data, len);
upload_ctx->lines_read++;
upload_ctx->bytes_read += len;
return len;
}
@ -88,9 +89,7 @@ int main(void)
CURL *curl;
CURLcode res = CURLE_OK;
struct curl_slist *recipients = NULL;
struct upload_status upload_ctx;
upload_ctx.lines_read = 0;
struct upload_status upload_ctx = { 0 };
curl = curl_easy_init();
if(curl) {
@ -131,13 +130,13 @@ int main(void)
* they could cause an endless loop. See RFC 5321 Section 4.5.5 for more
* details.
*/
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM);
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM_MAIL);
/* Add two recipients, in this particular case they correspond to the
* To: and Cc: addressees in the header, but they could be any kind of
* recipient. */
recipients = curl_slist_append(recipients, TO);
recipients = curl_slist_append(recipients, CC);
recipients = curl_slist_append(recipients, TO_MAIL);
recipients = curl_slist_append(recipients, CC_MAIL);
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);
/* We're using a callback function to specify the payload (the headers and