From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1386) id F02BB3858C74; Wed, 19 Apr 2023 09:44:03 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org F02BB3858C74 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Jan Beulich To: bfd-cvs@sourceware.org Subject: [binutils-gdb] x86: parse_register() must not alter the parsed string X-Act-Checkin: binutils-gdb X-Git-Author: Jan Beulich X-Git-Refname: refs/heads/master X-Git-Oldrev: 74e05e01e2de46dc817d747c646421125e59d6b1 X-Git-Newrev: 4f0813127bc0c525fca152bca4fea30b7490ae14 Message-Id: <20230419094403.F02BB3858C74@sourceware.org> Date: Wed, 19 Apr 2023 09:44:03 +0000 (GMT) X-BeenThere: binutils-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 19 Apr 2023 09:44:04 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D4f0813127bc0= c525fca152bca4fea30b7490ae14 commit 4f0813127bc0c525fca152bca4fea30b7490ae14 Author: Jan Beulich Date: Wed Apr 19 11:43:26 2023 +0200 x86: parse_register() must not alter the parsed string =20 This reverts the code change done by 100f993c53a5 ("x86: Check unbalanced braces in memory reference"), which wrongly identified e87fb6a6d0cd ("x86/gas: support quoted address scale factor in AT&T syntax") as the root cause of PR gas/30248. (The testcase is left in place, no matter that it's at best marginally useful in that shape.) =20 The problem instead is that parse_register() alters the string handed to it, thus breaking valid assumptions in subsequent parsing code. Since the function's behavior is a result of get_symbol_name()'s, make a copy of the incoming string before invoking that function. =20 Like for parse_real_register() follow the model of strtol() et al: input string is const-qualified to signal that the string isn't altered, but the returned "end" pointer is not const-qualified, requiring const to be cast away (which generally is a bad idea, but the alternative would again be more convoluted code). Diff: --- gas/config/tc-i386.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 063c9705ddd..7fdd71b490d 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -159,7 +159,7 @@ static int i386_att_operand (char *); static int i386_intel_operand (char *, int); static int i386_intel_simplify (expressionS *); static int i386_intel_parse_name (const char *, expressionS *); -static const reg_entry *parse_register (char *, char **); +static const reg_entry *parse_register (const char *, char **); static const char *parse_insn (const char *, char *, bool); static char *parse_operands (char *, const char *); static void swap_operands (void); @@ -12498,11 +12498,7 @@ i386_att_operand (char *operand_string) temp_string =3D base_string; =20 /* Skip past '(' and whitespace. */ - if (*base_string !=3D '(') - { - as_bad (_("unbalanced braces")); - return 0; - } + gas_assert (*base_string =3D=3D '('); ++base_string; if (is_space_char (*base_string)) ++base_string; @@ -13819,7 +13815,7 @@ parse_real_register (const char *reg_string, char *= *end_op) /* REG_STRING starts *before* REGISTER_PREFIX. */ =20 static const reg_entry * -parse_register (char *reg_string, char **end_op) +parse_register (const char *reg_string, char **end_op) { const reg_entry *r; =20 @@ -13830,12 +13826,12 @@ parse_register (char *reg_string, char **end_op) if (!r) { char *save =3D input_line_pointer; - char c; + char *buf =3D xstrdup (reg_string), *name; symbolS *symbolP; =20 - input_line_pointer =3D reg_string; - c =3D get_symbol_name (®_string); - symbolP =3D symbol_find (reg_string); + input_line_pointer =3D buf; + get_symbol_name (&name); + symbolP =3D symbol_find (name); while (symbolP && S_GET_SEGMENT (symbolP) !=3D reg_section) { const expressionS *e =3D symbol_get_value_expression(symbolP); @@ -13853,7 +13849,7 @@ parse_register (char *reg_string, char **end_op) know (e->X_add_number >=3D 0 && (valueT) e->X_add_number < i386_regtab_size); r =3D i386_regtab + e->X_add_number; - *end_op =3D input_line_pointer; + *end_op =3D (char *) reg_string + (input_line_pointer - buf); } if (r && !check_register (r)) { @@ -13862,8 +13858,8 @@ parse_register (char *reg_string, char **end_op) r =3D &bad_reg; } } - *input_line_pointer =3D c; input_line_pointer =3D save; + free (buf); } return r; }