]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-var-expand: Fix lexer error passing
authorAki Tuomi <aki.tuomi@open-xchange.com>
Mon, 17 Feb 2025 10:44:04 +0000 (12:44 +0200)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Mon, 17 Feb 2025 18:43:45 +0000 (18:43 +0000)
This way we can actually tell what the lexer did wrong.

src/lib-var-expand/test-var-expand.c
src/lib-var-expand/var-expand-lexer.l

index a96d8202abcfc85d049ac1a9f3e0696d2b972339..6c227df5670e84028f2eaafee4621ceff86bbd30 100644 (file)
@@ -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 = {
index fd1eabf9b718a3b52410df4f5588b6d9f0ed6d8d..64e0cc2794eb3399348e488b94a5c3fbb090ca7f 100644 (file)
@@ -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"); }
 }
 
 <stringdq>{
@@ -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);