Skip to content

Commit a399504

Browse files
authored
Apply Sebtous 2023 UID FETCH parsing fix (libetpan #426), adapted via a-chaudhari/mailspring-patcher (#14)
1 parent 3824e35 commit a399504

2 files changed

Lines changed: 232 additions & 89 deletions

File tree

Vendor/libetpan/src/low-level/imap/mailimap_parser.c

Lines changed: 204 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -5265,19 +5265,73 @@ static int mailimap_env_in_reply_to_parse(mailstream * fd,
52655265
progr_rate, progr_fun);
52665266
}
52675267

5268+
/*
5269+
Workaround for iCloud issue where the ENVELOPE's messageid contains unescaped DQUOTE's
5270+
*/
5271+
5272+
static int mailimap_env_message_id_parse_icloud_workaround ( mailstream* fd,
5273+
MMAPString* buffer, struct mailimap_parser_context* parser_ctx,
5274+
size_t* indx, char** result,
5275+
size_t progr_rate,
5276+
progress_function* progr_fun )
5277+
{
5278+
int r;
5279+
size_t cur_token;
5280+
5281+
// Workaround for iCloud issue where the ENVELOPE's messageid contains DQUOTE's
5282+
5283+
cur_token = *indx;
5284+
r = mailimap_dquote_parse ( fd, buffer, parser_ctx, &cur_token );
5285+
5286+
if ( r != MAILIMAP_NO_ERROR )
5287+
return r;
5288+
5289+
r = mailimap_encapsulated_parse ( fd, buffer, parser_ctx,
5290+
&cur_token, result, progr_rate,
5291+
progr_fun, '<', '>', true );
5292+
5293+
if ( r != MAILIMAP_NO_ERROR )
5294+
return r;
5295+
5296+
r = mailimap_dquote_parse ( fd, buffer, parser_ctx, &cur_token );
5297+
5298+
if ( r != MAILIMAP_NO_ERROR )
5299+
return r;
5300+
5301+
*indx = cur_token;
5302+
return MAILIMAP_NO_ERROR;
5303+
}
5304+
52685305
/*
52695306
env-message-id = nstring
52705307
*/
52715308

5272-
static int mailimap_env_message_id_parse(mailstream * fd,
5273-
MMAPString * buffer, struct mailimap_parser_context * parser_ctx,
5274-
size_t * indx, char ** result,
5275-
size_t progr_rate,
5276-
progress_function * progr_fun)
5277-
{
5278-
return mailimap_nstring_parse(fd, buffer, parser_ctx, indx, result, NULL,
5279-
progr_rate, progr_fun);
5280-
}
5309+
static int mailimap_env_message_id_parse ( mailstream* fd,
5310+
MMAPString* buffer, struct mailimap_parser_context* parser_ctx,
5311+
size_t* indx, char** result,
5312+
size_t progr_rate,
5313+
progress_function* progr_fun )
5314+
{
5315+
int r;
5316+
size_t cur_token;
5317+
5318+
cur_token = *indx;
5319+
5320+
r = mailimap_nstring_parse ( fd, buffer, parser_ctx, &cur_token, result, NULL,
5321+
progr_rate, progr_fun );
5322+
5323+
if ( r == MAILIMAP_NO_ERROR && *result != NULL && strlen ( *result ) == 1 && *result[0] == '<' )
5324+
{
5325+
return mailimap_env_message_id_parse_icloud_workaround ( fd, buffer, parser_ctx, indx, result,
5326+
progr_rate, progr_fun );
5327+
}
5328+
else if ( r == MAILIMAP_NO_ERROR )
5329+
{
5330+
*indx = cur_token;
5331+
}
5332+
5333+
return r;
5334+
}
52815335

52825336
/*
52835337
env-reply-to = "(" 1*address ")" / nil
@@ -8699,104 +8753,142 @@ mailimap_nz_number_parse(mailstream * fd, MMAPString * buffer, struct mailimap_p
86998753
*/
87008754

87018755
/*
8702-
quoted = DQUOTE *QUOTED-CHAR DQUOTE
8703-
*/
87048756
8705-
static int
8706-
mailimap_quoted_parse(mailstream * fd, MMAPString * buffer, struct mailimap_parser_context * parser_ctx,
8707-
size_t * indx, char ** result,
8708-
size_t progr_rate,
8709-
progress_function * progr_fun)
8710-
{
8711-
char ch;
8712-
size_t cur_token;
8713-
MMAPString * gstr_quoted;
8714-
int r;
8715-
int res;
8716-
bool use_msg_body_handler;
8757+
generic encapsulated string parser
87178758
8718-
cur_token = * indx;
8759+
*/
87198760

8720-
use_msg_body_handler = (parser_ctx->msg_body_handler != NULL
8721-
&& parser_ctx->msg_body_parse_in_progress);
8761+
static int
8762+
mailimap_encapsulated_parse ( mailstream* fd, MMAPString* buffer, struct mailimap_parser_context* parser_ctx,
8763+
size_t* indx, char** result,
8764+
size_t progr_rate,
8765+
progress_function* progr_fun,
8766+
char open_token, char close_token, bool include_tokens )
8767+
{
8768+
char ch;
8769+
size_t cur_token;
8770+
MMAPString* gstr_quoted;
8771+
int r;
8772+
int res;
8773+
bool use_msg_body_handler;
8774+
bool is_quoted;
8775+
8776+
is_quoted = open_token == '\"' && close_token == '\"';
8777+
cur_token = *indx;
8778+
8779+
use_msg_body_handler = ( parser_ctx->msg_body_handler != NULL
8780+
&& parser_ctx->msg_body_parse_in_progress );
87228781

87238782
#ifdef UNSTRICT_SYNTAX
8724-
r = mailimap_space_parse(fd, buffer, &cur_token);
8725-
if ((r != MAILIMAP_NO_ERROR) && (r != MAILIMAP_ERROR_PARSE))
8726-
return r;
8783+
r = mailimap_space_parse ( fd, buffer, &cur_token );
8784+
if ( ( r != MAILIMAP_NO_ERROR ) && ( r != MAILIMAP_ERROR_PARSE ) )
8785+
return r;
87278786
#endif
87288787

8729-
r = mailimap_dquote_parse(fd, buffer, parser_ctx, &cur_token);
8730-
if (r != MAILIMAP_NO_ERROR) {
8731-
res = r;
8732-
goto err;
8733-
}
8788+
r = mailimap_char_parse ( fd, buffer, &cur_token, open_token );
8789+
if ( r != MAILIMAP_NO_ERROR ) {
8790+
res = r;
8791+
goto err;
8792+
}
87348793

8735-
gstr_quoted = mmap_string_new("");
8736-
if (gstr_quoted == NULL) {
8737-
res = MAILIMAP_ERROR_MEMORY;
8738-
goto err;
8739-
}
8794+
gstr_quoted = mmap_string_new ( "" );
87408795

8741-
while (1) {
8742-
if (cur_token >= buffer->len) {
8743-
if (fd == NULL) {
8744-
if (!has_crlf(buffer, cur_token)) {
8745-
res = MAILIMAP_ERROR_NEEDS_MORE_DATA;
8746-
goto free;
8796+
if ( gstr_quoted == NULL ) {
8797+
res = MAILIMAP_ERROR_MEMORY;
8798+
goto err;
87478799
}
8748-
}
8749-
else if (mailstream_read_line_append(fd, buffer) == NULL) {
8750-
res = MAILIMAP_ERROR_PARSE;
8800+
8801+
if ( include_tokens && mmap_string_append_c ( gstr_quoted, open_token ) == NULL )
8802+
{
8803+
res = MAILIMAP_ERROR_MEMORY;
87518804
goto free;
8752-
}
8753-
}
8805+
}
8806+
8807+
while ( 1 ) {
8808+
if ( cur_token >= buffer->len ) {
8809+
if ( fd == NULL ) {
8810+
if ( !has_crlf ( buffer, cur_token ) ) {
8811+
res = MAILIMAP_ERROR_NEEDS_MORE_DATA;
8812+
goto free;
8813+
}
8814+
}
8815+
else if ( mailstream_read_line_append ( fd, buffer ) == NULL ) {
8816+
res = MAILIMAP_ERROR_PARSE;
8817+
goto free;
8818+
}
8819+
}
8820+
8821+
if ( is_quoted )
8822+
r = mailimap_quoted_char_parse ( fd, buffer, parser_ctx, &cur_token, &ch );
8823+
else
8824+
r = mailimap_any_char_except_parse ( fd, buffer, parser_ctx, &cur_token, &ch, close_token );
8825+
8826+
if ( r == MAILIMAP_ERROR_PARSE )
8827+
break;
8828+
else if ( r == MAILIMAP_NO_ERROR ) {
8829+
if ( use_msg_body_handler ) {
8830+
if ( !parser_ctx->msg_body_handler ( parser_ctx->msg_body_att_type, parser_ctx->msg_body_section,
8831+
&ch, 1,
8832+
parser_ctx->msg_body_handler_context ) ) {
8833+
res = MAILIMAP_ERROR_MEMORY;
8834+
goto free;
8835+
}
8836+
}
8837+
else {
8838+
if ( mmap_string_append_c ( gstr_quoted, ch ) == NULL ) {
8839+
res = MAILIMAP_ERROR_MEMORY;
8840+
goto free;
8841+
}
8842+
}
8843+
}
8844+
else {
8845+
res = r;
8846+
goto free;
8847+
}
8848+
}
8849+
8850+
r = mailimap_char_parse ( fd, buffer, &cur_token, close_token );
87548851

8755-
r = mailimap_quoted_char_parse(fd, buffer, parser_ctx, &cur_token, &ch);
8756-
if (r == MAILIMAP_ERROR_PARSE)
8757-
break;
8758-
else if (r == MAILIMAP_NO_ERROR) {
8759-
if (use_msg_body_handler) {
8760-
if (!parser_ctx->msg_body_handler(parser_ctx->msg_body_att_type, parser_ctx->msg_body_section,
8761-
&ch, 1,
8762-
parser_ctx->msg_body_handler_context)) {
8763-
res = MAILIMAP_ERROR_MEMORY;
8764-
goto free;
8852+
if ( r != MAILIMAP_NO_ERROR ) {
8853+
res = r;
8854+
goto free;
87658855
}
8766-
}
8767-
else {
8768-
if (mmap_string_append_c(gstr_quoted, ch) == NULL) {
8769-
res = MAILIMAP_ERROR_MEMORY;
8770-
goto free;
8856+
8857+
if ( include_tokens && mmap_string_append_c ( gstr_quoted, close_token ) == NULL )
8858+
{
8859+
res = MAILIMAP_ERROR_MEMORY;
8860+
goto free;
87718861
}
8772-
}
8773-
}
8774-
else {
8775-
res = r;
8776-
goto free;
8777-
}
8778-
}
87798862

8780-
r = mailimap_dquote_parse(fd, buffer, parser_ctx, &cur_token);
8781-
if (r != MAILIMAP_NO_ERROR) {
8782-
res = r;
8783-
goto free;
8784-
}
8863+
if ( mmap_string_ref ( gstr_quoted ) < 0 ) {
8864+
res = MAILIMAP_ERROR_MEMORY;
8865+
goto free;
8866+
}
87858867

8786-
if (mmap_string_ref(gstr_quoted) < 0) {
8787-
res = MAILIMAP_ERROR_MEMORY;
8788-
goto free;
8789-
}
8868+
*indx = cur_token;
8869+
*result = gstr_quoted->str;
87908870

8791-
* indx = cur_token;
8792-
* result = gstr_quoted->str;
8871+
return MAILIMAP_NO_ERROR;
87938872

8794-
return MAILIMAP_NO_ERROR;
8873+
free:
8874+
mmap_string_free ( gstr_quoted );
8875+
err:
8876+
return res;
8877+
}
87958878

8796-
free:
8797-
mmap_string_free(gstr_quoted);
8798-
err:
8799-
return res;
8879+
/*
8880+
quoted = DQUOTE *QUOTED-CHAR DQUOTE
8881+
*/
8882+
8883+
static int
8884+
mailimap_quoted_parse(mailstream * fd, MMAPString * buffer, struct mailimap_parser_context * parser_ctx,
8885+
size_t * indx, char ** result,
8886+
size_t progr_rate,
8887+
progress_function * progr_fun)
8888+
{
8889+
return mailimap_encapsulated_parse ( fd, buffer, parser_ctx,
8890+
indx, result, progr_rate,
8891+
progr_fun, '\"', '\"', false );
88008892
}
88018893

88028894
/*
@@ -8850,6 +8942,30 @@ mailimap_quoted_char_parse(mailstream * fd, MMAPString * buffer, struct mailimap
88508942
}
88518943
}
88528944

8945+
int
8946+
mailimap_any_char_except_parse ( mailstream* fd, MMAPString* buffer, struct mailimap_parser_context* parser_ctx,
8947+
size_t* indx, char* result, char except_char )
8948+
{
8949+
size_t cur_token;
8950+
char cur_char;
8951+
8952+
cur_token = *indx;
8953+
8954+
if ( cur_token >= buffer->len )
8955+
return MAILIMAP_ERROR_PARSE;
8956+
8957+
cur_char = buffer->str[cur_token];
8958+
8959+
if ( is_text_char ( cur_char ) && cur_char != except_char ) {
8960+
*result = cur_char;
8961+
cur_token++;
8962+
*indx = cur_token;
8963+
return MAILIMAP_NO_ERROR;
8964+
}
8965+
else
8966+
return MAILIMAP_ERROR_PARSE;
8967+
}
8968+
88538969
/*
88548970
quoted-specials = DQUOTE / "\"
88558971
*/

Vendor/libetpan/src/low-level/imap/mailimap_parser.h

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,13 +183,40 @@ int mailimap_capability_data_parse(mailstream * fd, MMAPString * buffer, struct
183183
size_t progr_rate,
184184
progress_function * progr_fun);
185185

186+
static int is_text_char(char ch);
187+
186188
int mailimap_capability_list_parse(mailstream * fd,
187189
MMAPString * buffer, struct mailimap_parser_context * parser_ctx,
188190
size_t * indx,
189191
clist ** result,
190192
size_t progr_rate,
191193
progress_function * progr_fun);
192194

195+
int
196+
mailimap_any_char_except_parse ( mailstream* fd, MMAPString* buffer, struct mailimap_parser_context* parser_ctx,
197+
size_t* indx, char* result, char except_char );
198+
199+
static int
200+
mailimap_env_message_id_parse_icloud_workaround ( mailstream* fd,
201+
MMAPString* buffer, struct mailimap_parser_context* parser_ctx,
202+
size_t* indx, char** result,
203+
size_t progr_rate,
204+
progress_function* progr_fun );
205+
206+
static int
207+
mailimap_env_message_id_parse ( mailstream* fd,
208+
MMAPString* buffer, struct mailimap_parser_context* parser_ctx,
209+
size_t* indx, char** result,
210+
size_t progr_rate,
211+
progress_function* progr_fun );
212+
213+
static int
214+
mailimap_encapsulated_parse ( mailstream* fd, MMAPString* buffer, struct mailimap_parser_context* parser_ctx,
215+
size_t* indx, char** result,
216+
size_t progr_rate,
217+
progress_function* progr_fun,
218+
char open_token, char close_token, bool include_tokens );
219+
193220
int mailimap_status_att_parse(mailstream * fd, MMAPString * buffer, struct mailimap_parser_context * parser_ctx,
194221
size_t * indx, int * result);
195222

@@ -218,4 +245,4 @@ int mailimap_hack_date_time_parse(char * str,
218245
}
219246
#endif
220247

221-
#endif
248+
#endif

0 commit comments

Comments
 (0)