@@ -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*/
0 commit comments