Mercurial > octave
changeset 26512:4d6392c879d7 stable
avoid double free of lexer on exit (bug #55347)
* parse.h (parser::parser): Accept pointer to lexer object instead of
reference. Comment to state that lexer object must be allocated by
new and will be deleted by the parser destructor.
* pt-eval.cc (tree_evaluator::repl): Construct parser using pointer to
lexer. Don't delete lexer object.
(tree_evaluator::repl, tree_evaluator::eval_string): Avoid confusing
"parser parser" declaration by renaming parser objects to be
repl_parser and eval_parser, respectively.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 09 Jan 2019 14:49:01 -0500 |
parents | 7bf8036ad3f6 |
children | 32890ede698c 02a9e1bb314a |
files | libinterp/parse-tree/parse.h libinterp/parse-tree/pt-eval.cc |
diffstat | 2 files changed, 26 insertions(+), 24 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/parse-tree/parse.h Wed Jan 09 09:05:31 2019 +0100 +++ b/libinterp/parse-tree/parse.h Wed Jan 09 14:49:01 2019 -0500 @@ -498,8 +498,12 @@ : base_parser (*(new lexer (eval_string, interp))) { } - parser (lexer& lxr) - : base_parser (lxr) + // The lexer must be allocated with new. The parser object + // takes ownership of and deletes the lexer object in its + // destructor. + + parser (lexer *lxr) + : base_parser (*lxr) { } // No copying!
--- a/libinterp/parse-tree/pt-eval.cc Wed Jan 09 09:05:31 2019 +0100 +++ b/libinterp/parse-tree/pt-eval.cc Wed Jan 09 14:49:01 2019 -0500 @@ -77,11 +77,12 @@ { int retval = 0; - lexer *lxr = (interactive - ? new lexer (m_interpreter) - : new lexer (stdin, m_interpreter)); - - parser parser (*lxr); + // The parser takes ownership of the lexer and will delete it when + // the parser goes out of scope. + + parser repl_parser (interactive + ? new lexer (m_interpreter) + : new lexer (stdin, m_interpreter)); symbol_table& symtab = m_interpreter.get_symbol_table (); @@ -91,18 +92,18 @@ { reset_error_handler (); - parser.reset (); + repl_parser.reset (); if (symtab.at_top_level ()) reset_debug_state (); - retval = parser.run (); + retval = repl_parser.run (); if (retval == 0) { - if (parser.m_stmt_list) + if (repl_parser.m_stmt_list) { - parser.m_stmt_list->accept (*this); + repl_parser.m_stmt_list->accept (*this); octave_quit (); @@ -125,7 +126,7 @@ else command_editor::increment_current_command_number (); } - else if (parser.m_lexer.m_end_of_input) + else if (repl_parser.m_lexer.m_end_of_input) { retval = EOF; break; @@ -190,9 +191,6 @@ retval = 0; } - // Clean up memory - delete lxr; - return retval; } @@ -202,22 +200,22 @@ { octave_value_list retval; - parser parser (eval_str, m_interpreter); + parser eval_parser (eval_str, m_interpreter); do { - parser.reset (); - - parse_status = parser.run (); + eval_parser.reset (); + + parse_status = eval_parser.run (); if (parse_status == 0) { - if (parser.m_stmt_list) + if (eval_parser.m_stmt_list) { tree_statement *stmt = nullptr; - if (parser.m_stmt_list->length () == 1 - && (stmt = parser.m_stmt_list->front ()) + if (eval_parser.m_stmt_list->length () == 1 + && (stmt = eval_parser.m_stmt_list->front ()) && stmt->is_expression ()) { tree_expression *expr = stmt->expression (); @@ -251,14 +249,14 @@ retval = octave_value_list (); } else if (nargout == 0) - parser.m_stmt_list->accept (*this); + eval_parser.m_stmt_list->accept (*this); else error ("eval: invalid use of statement list"); if (returning () || breaking () || continuing ()) break; } - else if (parser.m_lexer.m_end_of_input) + else if (eval_parser.m_lexer.m_end_of_input) break; } }