Fossil SCM

Fixed the blob-to-SMTP encoding logic to prevent a possible data truncation when the line wrapping happens to place a period alone at the start of a new line. SMTP treats that as end-of-message. Fix diagnosed by gumblex, /forumpost/4290f75ba1.

wyoung 2018-08-14 03:55 trunk
Commit 51740ce45fd4d498256d9610d3273f3bb2ee5f8bb11dc7058186801d00888601
1 file changed +6 -4
+6 -4
--- src/smtp.c
+++ src/smtp.c
@@ -448,11 +448,12 @@
448448
449449
/*
450450
** Send the content of an email message followed by a single
451451
** "." line. All lines must be \r\n terminated. Any isolated
452452
** \n line terminators in the input must be converted. Also,
453
-** an line contain using "." should be converted to "..".
453
+** a line beginning with "." must have the dot doubled per
454
+** https://tools.ietf.org/html/rfc5321#section-4.5.2
454455
*/
455456
static void smtp_send_email_body(
456457
const char *zMsg, /* Message to send */
457458
size_t (*xSend)(void*,const void*,size_t), /* Sender callback function */
458459
void *pArg /* First arg to sender */
@@ -465,16 +466,17 @@
465466
char *z = blob_buffer(&line);
466467
int n = blob_size(&line);
467468
if( n==0 ) break;
468469
n--;
469470
if( n && z[n-1]=='\r' ) n--;
470
- if( n==1 && z[0]=='.' ){
471
- blob_append(&out, "..\r\n", 4);
471
+ if( z[0]=='.' ){
472
+ blob_append(&out, "..", 2); /* RFC 5321 § 4.5.2 */
473
+ blob_append(&out, z+1, n-1);
472474
}else{
473475
blob_append(&out, z, n);
474
- blob_append(&out, "\r\n", 2);
475476
}
477
+ blob_append(&out, "\r\n", 2);
476478
}
477479
blob_append(&out, ".\r\n", 3);
478480
xSend(pArg, blob_buffer(&out), blob_size(&out));
479481
blob_reset(&out);
480482
blob_reset(&line);
481483
--- src/smtp.c
+++ src/smtp.c
@@ -448,11 +448,12 @@
448
449 /*
450 ** Send the content of an email message followed by a single
451 ** "." line. All lines must be \r\n terminated. Any isolated
452 ** \n line terminators in the input must be converted. Also,
453 ** an line contain using "." should be converted to "..".
 
454 */
455 static void smtp_send_email_body(
456 const char *zMsg, /* Message to send */
457 size_t (*xSend)(void*,const void*,size_t), /* Sender callback function */
458 void *pArg /* First arg to sender */
@@ -465,16 +466,17 @@
465 char *z = blob_buffer(&line);
466 int n = blob_size(&line);
467 if( n==0 ) break;
468 n--;
469 if( n && z[n-1]=='\r' ) n--;
470 if( n==1 && z[0]=='.' ){
471 blob_append(&out, "..\r\n", 4);
 
472 }else{
473 blob_append(&out, z, n);
474 blob_append(&out, "\r\n", 2);
475 }
 
476 }
477 blob_append(&out, ".\r\n", 3);
478 xSend(pArg, blob_buffer(&out), blob_size(&out));
479 blob_reset(&out);
480 blob_reset(&line);
481
--- src/smtp.c
+++ src/smtp.c
@@ -448,11 +448,12 @@
448
449 /*
450 ** Send the content of an email message followed by a single
451 ** "." line. All lines must be \r\n terminated. Any isolated
452 ** \n line terminators in the input must be converted. Also,
453 ** a line beginning with "." must have the dot doubled per
454 ** https://tools.ietf.org/html/rfc5321#section-4.5.2
455 */
456 static void smtp_send_email_body(
457 const char *zMsg, /* Message to send */
458 size_t (*xSend)(void*,const void*,size_t), /* Sender callback function */
459 void *pArg /* First arg to sender */
@@ -465,16 +466,17 @@
466 char *z = blob_buffer(&line);
467 int n = blob_size(&line);
468 if( n==0 ) break;
469 n--;
470 if( n && z[n-1]=='\r' ) n--;
471 if( z[0]=='.' ){
472 blob_append(&out, "..", 2); /* RFC 5321 § 4.5.2 */
473 blob_append(&out, z+1, n-1);
474 }else{
475 blob_append(&out, z, n);
 
476 }
477 blob_append(&out, "\r\n", 2);
478 }
479 blob_append(&out, ".\r\n", 3);
480 xSend(pArg, blob_buffer(&out), blob_size(&out));
481 blob_reset(&out);
482 blob_reset(&line);
483

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button