Mercurial > octave
changeset 21361:9ca194f7a858
disallow assignment to "end" in indexed assignments (bug #46459)
* parse.h, oct-parse.in.yy
(octave_base_parser::valid_id_for_assignment): New function.
(octave_base_parser::make_assign_op): Use it.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Fri, 26 Feb 2016 13:13:21 -0500 |
parents | 06c2a109935c |
children | 1bb9a34011d1 |
files | libinterp/parse-tree/oct-parse.in.yy libinterp/parse-tree/parse.h |
diffstat | 2 files changed, 66 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/parse-tree/oct-parse.in.yy Fri Feb 26 09:19:25 2016 -0800 +++ b/libinterp/parse-tree/oct-parse.in.yy Fri Feb 26 13:13:21 2016 -0500 @@ -2951,8 +2951,6 @@ octave_base_parser::make_assign_op (int op, tree_argument_list *lhs, token *eq_tok, tree_expression *rhs) { - tree_expression *retval = 0; - octave_value::assign_op t = octave_value::unknown_assign_op; switch (op) @@ -3017,25 +3015,65 @@ int l = eq_tok->line (); int c = eq_tok->column (); - if (lhs->is_simple_assign_lhs ()) + if (! lhs->is_simple_assign_lhs () && t != octave_value::op_asn_eq) { - tree_expression *tmp = lhs->remove_front (); - - retval = new tree_simple_assignment (tmp, rhs, false, l, c, t); + // Multiple assignments like [x,y] OP= rhs are only valid for + // '=', not '+=', etc. delete lhs; + delete rhs; + + bison_error ("computed multiple assignment not allowed", l, c); + + return 0; } - else if (t == octave_value::op_asn_eq) - return new tree_multi_assignment (lhs, rhs, false, l, c); + + if (lhs->is_simple_assign_lhs ()) + { + // We are looking at a simple assignment statement like x = rhs; + + tree_expression *tmp = lhs->remove_front (); + + if ((tmp->is_identifier () || tmp->is_index_expression ()) + && ! valid_id_for_assignment (tmp->name ())) + { + std::string kw = tmp->name (); + + delete tmp; + delete lhs; + delete rhs; + + bison_error ("invalid assignment to keyword \"" + kw + "\"", l, c); + + return 0; + } + + delete lhs; + + return new tree_simple_assignment (tmp, rhs, false, l, c, t); + } else { - delete lhs; - delete rhs; - - bison_error ("computed multiple assignment not allowed"); + std::list<std::string> names = lhs->variable_names (); + + for (std::list<std::string>::const_iterator it = names.begin (); + it != names.end (); it++) + { + std::string kw = *it; + + if (! valid_id_for_assignment (kw)) + { + delete lhs; + delete rhs; + + bison_error ("invalid assignment to keyword \"" + kw + "\"", l, c); + + return 0; + } + } + + return new tree_multi_assignment (lhs, rhs, false, l, c); } - - return retval; } // Define a script. @@ -3986,6 +4024,18 @@ parse_error_msg = output_buf.str (); } +bool +octave_base_parser::valid_id_for_assignment (const std::string& s) +{ + // is_keyword will return true for some identfiers that are only + // keywords in certain contexts. + + return (! is_keyword (s) + || (! lexer.parsing_classdef + && (s == "enumeration" || s == "events" + || s == "methods" || s == "properties"))); +} + int octave_parser::run (void) {
--- a/libinterp/parse-tree/parse.h Fri Feb 26 09:19:25 2016 -0800 +++ b/libinterp/parse-tree/parse.h Fri Feb 26 13:13:21 2016 -0500 @@ -393,6 +393,8 @@ // Generic error messages. void bison_error (const std::string& s, int l = -1, int c = -1); + bool valid_id_for_assignment (const std::string& s); + // Contains error message if Bison-generated parser returns non-zero // status. std::string parse_error_msg;