From: Aki Tuomi Date: Mon, 17 Feb 2025 10:44:04 +0000 (+0200) Subject: lib-var-expand: Fix lexer error passing X-Git-Tag: 2.4.1~191 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1be3feeb10cd8d1fb6a3e87d34ea7bd62530cd7e;p=thirdparty%2Fdovecot%2Fcore.git lib-var-expand: Fix lexer error passing This way we can actually tell what the lexer did wrong. --- diff --git a/src/lib-var-expand/test-var-expand.c b/src/lib-var-expand/test-var-expand.c index a96d8202ab..6c227df567 100644 --- a/src/lib-var-expand/test-var-expand.c +++ b/src/lib-var-expand/test-var-expand.c @@ -639,15 +639,17 @@ static void test_var_expand_escape(void) { .in = "%{literal('\\\\x20')}", .out = "'\\x20'", .ret = 0 }, /* Bad hex / oct */ { .in = "\\xgg", .out = "\\xgg", .ret = 0 }, - { .in = "%{literal('\\xgg')}", .out = "expecting MINUS or NAME or VALUE or NUMBER", .ret = -1 }, + { .in = "%{literal('\\xgg')}", .out = "Invalid character escape", .ret = -1 }, { .in = "\\999", .out = "\\999", .ret = 0 }, - { .in = "%{literal('\\999')}", .out = "expecting MINUS or NAME or VALUE or NUMBER", .ret = -1 }, + { .in = "%{literal('\\999')}", .out = "Invalid character escape", .ret = -1 }, /* List test */ { .in = "%{literal('one\ttwo\tthree') | list}", .out="'one,two,three'", .ret = 0 }, /* Escape escape */ { .in = "\\hello\\world", .out = "\\hello\\world", .ret = 0 }, { .in = "%{literal('\\'\\\\hello\\\\world\\'')}", .out = "'\\'\\hello\\world\\''", .ret = 0 }, { .in = "%{literal(\"\\\"\\\\hello\\\\world\\\"\")}", .out = "'\"\\hello\\world\"'", .ret = 0 }, + /* Unsupported escape sequence */ + { .in = "%{literal('\\z')}", .out = "Invalid character escape", .ret = -1 }, }; const struct var_expand_params params = { diff --git a/src/lib-var-expand/var-expand-lexer.l b/src/lib-var-expand/var-expand-lexer.l index fd1eabf9b7..64e0cc2794 100644 --- a/src/lib-var-expand/var-expand-lexer.l +++ b/src/lib-var-expand/var-expand-lexer.l @@ -46,6 +46,7 @@ static size_t input_proc(char *buf, size_t size, yyscan_t scanner); yylval->str = str_new(state->pool, 32); \ } STMT_END +static int scanner_error(void *yyscanner, const char *msg); %} %x stringsq @@ -60,18 +61,14 @@ static size_t input_proc(char *buf, size_t size, yyscan_t scanner); x[0-9a-fA-F]{2} { unsigned int c; if (str_to_uint_hex(yytext+1, &c) < 0 || c > 255) { - YYSTYPE *state = yyget_extra(yyscanner); - state->error = "Invalid character escape"; - yyterminate(); + return scanner_error(yyscanner, "Invalid character escape"); } yy_pop_state(yyscanner); str_append_c(yylval->str, c); } [0-9]{1,3} { unsigned int c; if (str_to_uint_oct(yytext, &c) < 0 || c > 255) { - YYSTYPE *state = yyget_extra(yyscanner); - state->error = "Invalid character escape"; - yyterminate(); + return scanner_error(yyscanner, "Invalid character escape"); } yy_pop_state(yyscanner); str_append_c(yylval->str, c); } @@ -80,7 +77,7 @@ static size_t input_proc(char *buf, size_t size, yyscan_t scanner); n { yy_pop_state(yyscanner); str_append_c(yylval->str, '\n'); } ["] { yy_pop_state(yyscanner); str_append_c(yylval->str, '"'); } ['] { yy_pop_state(yyscanner); str_append_c(yylval->str, '\''); } - . { YYSTYPE *state = yyget_extra(yyscanner); state->error = "Invalid character escape"; } + . { return scanner_error(yyscanner, "Invalid character escape"); } } { @@ -122,12 +119,20 @@ static size_t input_proc(char *buf, size_t size, yyscan_t scanner); %% extern void var_expand_parser_error(YYLTYPE *loc, YYSTYPE *state, const char *error); -void var_expand_parser_error(YYLTYPE *loc, YYSTYPE *state, const char *error) +void var_expand_parser_error(YYLTYPE *loc ATTR_UNUSED, YYSTYPE *state, const char *error) { state->failed = TRUE; state->error = p_strdup(state->pool, error); } +static int scanner_error(void *scanner, const char *msg) +{ + YYSTYPE *state = yyget_extra(scanner); + struct yyguts_t *yyg = (struct yyguts_t *)scanner; + var_expand_parser_error(yylloc, state, msg); + return VAR_EXPAND_PARSER_error; +} + void *yyalloc(size_t bytes, void* yyscanner) { YYSTYPE *state = yyget_extra(yyscanner);