From 32c8a9891f2c0bdc9e1cda13f1313843bc4e6044 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sun, 17 Oct 2010 10:08:53 -0700 Subject: [PATCH] format-parser: Fix parse_format_specifier() failure case. When the current token is an identifier that takes the abstract syntax of a format specifier, but its "name" part is not a valid format name, parse_format_specifier() returned false but still consumed the token. This is a potential issue for callers that want to report an error that mentions the identifier, e.g. parse_primary(), although the current lexer tends to retain the same identifier when the new token is not an identifier. --- src/language/lexer/format-parser.c | 42 +++++++++++++++++++----------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/src/language/lexer/format-parser.c b/src/language/lexer/format-parser.c index 39dbacbf..9adbeb15 100644 --- a/src/language/lexer/format-parser.c +++ b/src/language/lexer/format-parser.c @@ -33,18 +33,10 @@ #include "gettext.h" #define _(msgid) gettext (msgid) -/* Parses a token taking the form of a format specifier and - returns true only if successful. Emits an error message on - failure. Stores a null-terminated string representing the - format type in TYPE, and the width and number of decimal - places in *WIDTH and *DECIMALS. - - TYPE is not checked as to whether it is really the name of a - format. Both width and decimals are considered optional. If - missing, *WIDTH or *DECIMALS or both will be set to 0. */ -bool -parse_abstract_format_specifier (struct lexer *lexer, char type[FMT_TYPE_LEN_MAX + 1], - int *width, int *decimals) +static bool +parse_abstract_format_specifier__ (struct lexer *lexer, + char type[FMT_TYPE_LEN_MAX + 1], + int *width, int *decimals) { struct substring s; struct substring type_ss, width_ss, decimals_ss; @@ -81,14 +73,33 @@ parse_abstract_format_specifier (struct lexer *lexer, char type[FMT_TYPE_LEN_MAX *width = strtol (ss_data (width_ss), NULL, 10); *decimals = has_decimals ? strtol (ss_data (decimals_ss), NULL, 10) : 0; - lex_get (lexer); return true; - error: +error: lex_error (lexer, _("expecting valid format specifier")); return false; } +/* Parses a token taking the form of a format specifier and + returns true only if successful. Emits an error message on + failure. Stores a null-terminated string representing the + format type in TYPE, and the width and number of decimal + places in *WIDTH and *DECIMALS. + + TYPE is not checked as to whether it is really the name of a + format. Both width and decimals are considered optional. If + missing, *WIDTH or *DECIMALS or both will be set to 0. */ +bool +parse_abstract_format_specifier (struct lexer *lexer, + char type[FMT_TYPE_LEN_MAX + 1], + int *width, int *decimals) +{ + bool ok = parse_abstract_format_specifier__ (lexer, type, width, decimals); + if (ok) + lex_get (lexer); + return ok; +} + /* Parses a format specifier from the token stream and returns true only if successful. Emits an error message on failure. The caller should call check_input_specifier() or @@ -99,7 +110,7 @@ parse_format_specifier (struct lexer *lexer, struct fmt_spec *format) { char type[FMT_TYPE_LEN_MAX + 1]; - if (!parse_abstract_format_specifier (lexer, type, &format->w, &format->d)) + if (!parse_abstract_format_specifier__ (lexer, type, &format->w, &format->d)) return false; if (!fmt_from_name (type, &format->type)) @@ -108,6 +119,7 @@ parse_format_specifier (struct lexer *lexer, struct fmt_spec *format) return false; } + lex_get (lexer); return true; } -- 2.30.2