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.
Commit
51740ce45fd4d498256d9610d3273f3bb2ee5f8bb11dc7058186801d00888601
Parent
31631b756e08ae1…
1 file changed
+6
-4
+6
-4
| --- src/smtp.c | ||
| +++ src/smtp.c | ||
| @@ -448,11 +448,12 @@ | ||
| 448 | 448 | |
| 449 | 449 | /* |
| 450 | 450 | ** Send the content of an email message followed by a single |
| 451 | 451 | ** "." line. All lines must be \r\n terminated. Any isolated |
| 452 | 452 | ** \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 | |
| 454 | 455 | */ |
| 455 | 456 | static void smtp_send_email_body( |
| 456 | 457 | const char *zMsg, /* Message to send */ |
| 457 | 458 | size_t (*xSend)(void*,const void*,size_t), /* Sender callback function */ |
| 458 | 459 | void *pArg /* First arg to sender */ |
| @@ -465,16 +466,17 @@ | ||
| 465 | 466 | char *z = blob_buffer(&line); |
| 466 | 467 | int n = blob_size(&line); |
| 467 | 468 | if( n==0 ) break; |
| 468 | 469 | n--; |
| 469 | 470 | 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); | |
| 472 | 474 | }else{ |
| 473 | 475 | blob_append(&out, z, n); |
| 474 | - blob_append(&out, "\r\n", 2); | |
| 475 | 476 | } |
| 477 | + blob_append(&out, "\r\n", 2); | |
| 476 | 478 | } |
| 477 | 479 | blob_append(&out, ".\r\n", 3); |
| 478 | 480 | xSend(pArg, blob_buffer(&out), blob_size(&out)); |
| 479 | 481 | blob_reset(&out); |
| 480 | 482 | blob_reset(&line); |
| 481 | 483 |
| --- 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 |