dovecot-2.2-pigeonhole: lib-sieve: Improved handling of stream e...
pigeonhole at rename-it.nl
pigeonhole at rename-it.nl
Sun Oct 19 09:01:27 UTC 2014
details: http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/e11f41c437a5
changeset: 1929:e11f41c437a5
user: Stephan Bosch <stephan at rename-it.nl>
date: Sun Oct 19 11:01:17 2014 +0200
description:
lib-sieve: Improved handling of stream errors in lexical scannner.
diffstat:
src/lib-sieve/sieve-lexer.c | 168 ++++++++++++++++++++++++++++---------------
1 files changed, 108 insertions(+), 60 deletions(-)
diffs (267 lines):
diff -r 05225545cdeb -r e11f41c437a5 src/lib-sieve/sieve-lexer.c
--- a/src/lib-sieve/sieve-lexer.c Sun Oct 19 09:37:48 2014 +0200
+++ b/src/lib-sieve/sieve-lexer.c Sun Oct 19 11:01:17 2014 +0200
@@ -277,17 +277,61 @@
return t_strdup_printf("0x%02x", ch);
}
+static bool
+sieve_lexer_scan_hash_comment(struct sieve_lexical_scanner *scanner)
+{
+ struct sieve_lexer *lexer = &scanner->lexer;
+
+ while ( sieve_lexer_curchar(scanner) != '\n' ) {
+ switch( sieve_lexer_curchar(scanner) ) {
+ case -1:
+ if ( scanner->input->eof ) {
+ sieve_lexer_warning(lexer,
+ "no newline (CRLF) at end of hash comment at end of file");
+ lexer->token_type = STT_WHITESPACE;
+ } else {
+ lexer->token_type = STT_ERROR;
+ }
+ return TRUE;
+ case '\0':
+ sieve_lexer_error
+ (lexer, "encountered NUL character in hash comment");
+ lexer->token_type = STT_ERROR;
+ return FALSE;
+ default:
+ break;
+ }
+
+ /* Stray CR is ignored */
+
+ sieve_lexer_shift(scanner);
+ }
+
+ sieve_lexer_shift(scanner);
+
+ lexer->token_type = STT_WHITESPACE;
+ return TRUE;
+}
+
/* sieve_lexer_scan_raw_token:
* Scans valid tokens and whitespace
*/
-static bool sieve_lexer_scan_raw_token(struct sieve_lexical_scanner *scanner)
+static bool
+sieve_lexer_scan_raw_token(struct sieve_lexical_scanner *scanner)
{
struct sieve_lexer *lexer = &scanner->lexer;
string_t *str;
+ int ret;
/* Read first character */
if ( lexer->token_type == STT_NONE ) {
- i_stream_read(scanner->input);
+ if ( (ret=i_stream_read(scanner->input)) < 0 ) {
+ i_assert( ret != -2 );
+ if ( !scanner->input->eof ) {
+ lexer->token_type = STT_ERROR;
+ return FALSE;
+ }
+ }
sieve_lexer_shift(scanner);
}
@@ -300,32 +344,7 @@
// hash-comment = ( "#" *CHAR-NOT-CRLF CRLF )
case '#':
sieve_lexer_shift(scanner);
-
- while ( sieve_lexer_curchar(scanner) != '\n' ) {
- switch( sieve_lexer_curchar(scanner) ) {
- case -1:
- sieve_lexer_warning
- (lexer, "no newline (CRLF) at end of hash comment at end of file");
- lexer->token_type = STT_WHITESPACE;
- return TRUE;
- case '\0':
- sieve_lexer_error
- (lexer, "encountered NUL character in hash comment");
- lexer->token_type = STT_ERROR;
- return FALSE;
- default:
- break;
- }
-
- /* Stray CR is ignored */
-
- sieve_lexer_shift(scanner);
- }
-
- sieve_lexer_shift(scanner);
-
- lexer->token_type = STT_WHITESPACE;
- return TRUE;
+ return sieve_lexer_scan_hash_comment(scanner);
// bracket-comment = "/*" *(CHAR-NOT-STAR / ("*" CHAR-NOT-SLASH)) "*/"
// ;; No */ allowed inside a comment.
@@ -341,9 +360,11 @@
while ( TRUE ) {
switch ( sieve_lexer_curchar(scanner) ) {
case -1:
- sieve_lexer_error(lexer,
- "end of file before end of bracket comment ('/* ... */') "
- "started at line %d", lexer->token_line);
+ if ( scanner->input->eof ) {
+ sieve_lexer_error(lexer,
+ "end of file before end of bracket comment ('/* ... */') "
+ "started at line %d", lexer->token_line);
+ }
lexer->token_type = STT_ERROR;
return FALSE;
case '*':
@@ -407,17 +428,18 @@
str = lexer->token_str_value;
while ( sieve_lexer_curchar(scanner) != '"' ) {
- if ( sieve_lexer_curchar(scanner) == '\\' ) {
+ if ( sieve_lexer_curchar(scanner) == '\\' )
sieve_lexer_shift(scanner);
- }
switch ( sieve_lexer_curchar(scanner) ) {
/* End of file */
case -1:
- sieve_lexer_error(lexer,
- "end of file before end of quoted string "
- "started at line %d", lexer->token_line);
+ if ( scanner->input->eof ) {
+ sieve_lexer_error(lexer,
+ "end of file before end of quoted string "
+ "started at line %d", lexer->token_line);
+ }
lexer->token_type = STT_ERROR;
return FALSE;
@@ -510,7 +532,10 @@
/* EOF */
case -1:
- lexer->token_type = STT_EOF;
+ if ( scanner->input->eof )
+ lexer->token_type = STT_EOF;
+ else
+ lexer->token_type = STT_ERROR;
return TRUE;
default:
@@ -627,24 +652,30 @@
sieve_lexer_shift(scanner);
/* Discard hash comment or handle single CRLF */
- switch ( sieve_lexer_curchar(scanner) ) {
+ if ( sieve_lexer_curchar(scanner) == '\r' )
+ sieve_lexer_shift(scanner);
+ switch ( sieve_lexer_curchar(scanner) ) {
case '#':
- while ( sieve_lexer_curchar(scanner) != '\n' )
- sieve_lexer_shift(scanner);
+ if ( !sieve_lexer_scan_hash_comment(scanner) )
+ return FALSE;
+ if ( scanner->input->eof ) {
+ sieve_lexer_error(lexer,
+ "end of file before end of multi-line string");
+ lexer->token_type = STT_ERROR;
+ return FALSE;
+ } else if ( scanner->input->stream_errno != 0 ) {
+ lexer->token_type = STT_ERROR;
+ return FALSE;
+ }
break;
- case '\r':
- sieve_lexer_shift(scanner);
- break;
- }
-
- /* Terminating LF required */
- switch ( sieve_lexer_curchar(scanner) ) {
case '\n':
sieve_lexer_shift(scanner);
break;
case -1:
- sieve_lexer_error(lexer,
- "end of file before end of multi-line string");
+ if ( scanner->input->eof ) {
+ sieve_lexer_error(lexer,
+ "end of file before end of multi-line string");
+ }
lexer->token_type = STT_ERROR;
return FALSE;
default:
@@ -692,9 +723,12 @@
return TRUE;
} else if ( cr_shifted ) {
/* Seen CR, but no LF */
- sieve_lexer_error(lexer,
- "found stray carriage-return (CR) character "
- "in multi-line string started at line %d", lexer->token_line);
+ if ( sieve_lexer_curchar(scanner) != -1 ||
+ !scanner->input->eof ) {
+ sieve_lexer_error(lexer,
+ "found stray carriage-return (CR) character "
+ "in multi-line string started at line %d", lexer->token_line);
+ }
lexer->token_type = STT_ERROR;
return FALSE;
}
@@ -712,8 +746,10 @@
switch ( sieve_lexer_curchar(scanner) ) {
case -1:
- sieve_lexer_error(lexer,
- "end of file before end of multi-line string");
+ if ( scanner->input->eof ) {
+ sieve_lexer_error(lexer,
+ "end of file before end of multi-line string");
+ }
lexer->token_type = STT_ERROR;
return FALSE;
case '\0':
@@ -731,15 +767,17 @@
}
/* If exited loop due to CR, skip it */
- if ( sieve_lexer_curchar(scanner) == '\r' ) {
+ if ( sieve_lexer_curchar(scanner) == '\r' )
sieve_lexer_shift(scanner);
- }
/* Now we must see an LF */
if ( sieve_lexer_curchar(scanner) != '\n' ) {
- sieve_lexer_error(lexer,
- "found stray carriage-return (CR) character "
- "in multi-line string started at line %d", lexer->token_line);
+ if ( sieve_lexer_curchar(scanner) != -1 ||
+ !scanner->input->eof ) {
+ sieve_lexer_error(lexer,
+ "found stray carriage-return (CR) character "
+ "in multi-line string started at line %d", lexer->token_line);
+ }
lexer->token_type = STT_ERROR;
return FALSE;
}
@@ -782,8 +820,18 @@
{
/* Scan token while skipping whitespace */
do {
- if ( !sieve_lexer_scan_raw_token(lexer->scanner) )
+ struct sieve_lexical_scanner *scanner = lexer->scanner;
+
+ if ( !sieve_lexer_scan_raw_token(scanner) ) {
+ if ( !scanner->input->eof && scanner->input->stream_errno != 0 ) {
+ sieve_critical(scanner->svinst, scanner->ehandler,
+ sieve_error_script_location(scanner->script, scanner->current_line),
+ "error reading script",
+ "error reading script during lexical analysis: %s",
+ i_stream_get_error(scanner->input));
+ }
return FALSE;
+ }
} while ( lexer->token_type == STT_WHITESPACE );
return TRUE;
More information about the dovecot-cvs
mailing list