From: Ben Pfaff Date: Sun, 17 Oct 2010 17:08:53 +0000 (-0700) Subject: format-parser: Fix parse_format_specifier() failure case. X-Git-Tag: v0.7.7~199 X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=32c8a9891f2c0bdc9e1cda13f1313843bc4e6044;p=pspp-builds.git 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. --- 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; }