Mercurial > octave
changeset 24377:ea3458c1d884
improve handling of invalid symbol_scope objects (bug #52607)
* symscope.h (class symbol_scope): Validate all uses of m_rep.
(symbol_scope::symbol_scope (const std::string&)): Don't provide
default argument value. Any named scope is considered valid, even if
the name is "".
(symbol_scope::symbol_scope (symbol_scope_rep *)): Provide default
argument of nullptr. If m_rep is nullptr, then the scope is invalid.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Thu, 07 Dec 2017 01:31:34 -0500 |
parents | 0755de78071c |
children | 64a85a19f6e3 |
files | libinterp/corefcn/symscope.h libinterp/parse-tree/oct-parse.in.yy |
diffstat | 2 files changed, 118 insertions(+), 68 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/symscope.h Wed Dec 06 18:49:31 2017 -0800 +++ b/libinterp/corefcn/symscope.h Thu Dec 07 01:31:34 2017 -0500 @@ -562,10 +562,15 @@ { public: - symbol_scope (const std::string& name = "") + // Create a valid but possibly unnamed scope. + symbol_scope (const std::string& name) : m_rep (new symbol_scope_rep (name)) { } + // NEW_REP must be dynamically allocated or nullptr. If it is + // nullptr, the scope is invalid. + symbol_scope (symbol_scope_rep *new_rep = nullptr) : m_rep (new_rep) { } + symbol_scope (const symbol_scope&) = default; symbol_scope& operator = (const symbol_scope&) = default; @@ -578,314 +583,361 @@ void insert_symbol_record (const symbol_record& sr) { - m_rep->insert_symbol_record (sr); + if (m_rep) + m_rep->insert_symbol_record (sr); } bool is_nested (void) const { - return m_rep->is_nested (); + return m_rep ? m_rep->is_nested () : false; } void mark_nested (void) { - m_rep->mark_nested (); + if (m_rep) + m_rep->mark_nested (); } bool is_static (void) const { - return m_rep->is_static (); + return m_rep ? m_rep->is_static () : false; } void mark_static (void) { - m_rep->mark_static (); + if (m_rep) + m_rep->mark_static (); } symbol_scope_rep * parent_scope (void) const { - return m_rep->parent_scope_rep (); + return m_rep ? m_rep->parent_scope_rep () : nullptr; } octave_value parent_fcn (void) const { - return m_rep->parent_fcn (); + return m_rep ? m_rep->parent_fcn () : octave_value (); } symbol_scope dup (void) const { - return symbol_scope (m_rep->dup ()); + return symbol_scope (m_rep ? m_rep->dup () : nullptr); } void set_context (symbol_record::context_id context) { - m_rep->set_context (context); + if (m_rep) + m_rep->set_context (context); } symbol_record::context_id current_context (void) const { - return m_rep->current_context (); + return m_rep ? m_rep->current_context () : 0; } symbol_record find_symbol (const std::string& name) { - return m_rep->find_symbol (name); + return m_rep ? m_rep->find_symbol (name) : symbol_record (); } void inherit (const symbol_scope& donor_scope) { - m_rep->inherit (donor_scope.get_rep ()); + if (m_rep) + m_rep->inherit (donor_scope.get_rep ()); } octave_value find (const std::string& name, const octave_value_list& args, bool skip_variables, bool local_funcs) { - return m_rep->find (name, args, skip_variables, local_funcs); + return (m_rep + ? m_rep->find (name, args, skip_variables, local_funcs) + : octave_value ()); } symbol_record& insert (const std::string& name, bool force_add = false) { - return m_rep->insert (name, force_add); + static symbol_record dummy_symrec; + return m_rep ? m_rep->insert (name, force_add) : dummy_symrec; } void rename (const std::string& old_name, const std::string& new_name) { - m_rep->rename (old_name, new_name); + if (m_rep) + m_rep->rename (old_name, new_name); } void assign (const std::string& name, const octave_value& value, bool force_add) { - m_rep->assign (name, value, force_add); + if (m_rep) + m_rep->assign (name, value, force_add); } void assign (const std::string& name, const octave_value& value = octave_value ()) { - m_rep->assign (name, value); + if (m_rep) + m_rep->assign (name, value); } void force_assign (const std::string& name, const octave_value& value) { - m_rep->force_assign (name, value); + if (m_rep) + m_rep->force_assign (name, value); } octave_value varval (const std::string& name) const { - return m_rep->varval (name); + return m_rep ? m_rep->varval (name) : octave_value (); } bool is_variable (const std::string& name) const { - return m_rep->is_variable (name); + return m_rep ? m_rep->is_variable (name) : false; } void push_context (void) { - m_rep->push_context (); + if (m_rep) + m_rep->push_context (); } void pop_context (void) { - m_rep->pop_context (); + if (m_rep) + m_rep->pop_context (); } void refresh (void) { - m_rep->refresh (); + if (m_rep) + m_rep->refresh (); } void clear_variables (void) { - m_rep->clear_variables (); + if (m_rep) + m_rep->clear_variables (); } void clear_objects (void) { - m_rep->clear_objects (); + if (m_rep) + m_rep->clear_objects (); } void clear_variable (const std::string& name) { - m_rep->clear_variable (name); + if (m_rep) + m_rep->clear_variable (name); } void clear_variable_pattern (const std::string& pat) { - m_rep->clear_variable_pattern (pat); + if (m_rep) + m_rep->clear_variable_pattern (pat); } void clear_variable_regexp (const std::string& pat) { - m_rep->clear_variable_regexp (pat); + if (m_rep) + m_rep->clear_variable_regexp (pat); } void mark_automatic (const std::string& name) { - m_rep->mark_automatic (name); + if (m_rep) + m_rep->mark_automatic (name); } void mark_hidden (const std::string& name) { - m_rep->mark_hidden (name); + if (m_rep) + m_rep->mark_hidden (name); } void mark_global (const std::string& name) { - m_rep->mark_global (name); + if (m_rep) + m_rep->mark_global (name); } std::list<symbol_record> all_variables (bool defined_only = true, unsigned int exclude = symbol_record::hidden) const { - return m_rep->all_variables (defined_only, exclude); + return (m_rep + ? m_rep->all_variables (defined_only, exclude) + : std::list<symbol_record> ()); } std::list<symbol_record> glob (const std::string& pattern, bool vars_only = false) const { - return m_rep->glob (pattern, vars_only); + return (m_rep + ? m_rep->glob (pattern, vars_only) + : std::list<symbol_record> ()); } std::list<symbol_record> regexp (const std::string& pattern, bool vars_only = false) const { - return m_rep->regexp (pattern, vars_only); + return (m_rep + ? m_rep->regexp (pattern, vars_only) + : std::list<symbol_record> ()); } std::list<std::string> variable_names (void) { - return m_rep->variable_names (); + return m_rep ? m_rep->variable_names () : std::list<std::string> (); } bool is_local_variable (const std::string& name) const { - return m_rep->is_local_variable (name); + return m_rep ? m_rep->is_local_variable (name) : false; } bool is_global (const std::string& name) const { - return m_rep->is_global (name); + return m_rep ? m_rep->is_global (name) : false; } void install_subfunction (const std::string& name, const octave_value& fval, bool is_nested = false) { - m_rep->install_subfunction (name, fval, is_nested); + if (m_rep) + m_rep->install_subfunction (name, fval, is_nested); } void install_nestfunction (const std::string& name, const octave_value& fval) { - m_rep->install_nestfunction (name, fval); + if (m_rep) + m_rep->install_nestfunction (name, fval); } octave_value find_subfunction (const std::string& name) const { - return m_rep->find_subfunction (name); + return m_rep ? m_rep->find_subfunction (name) : octave_value (); } void lock_subfunctions (void) { - m_rep->lock_subfunctions (); + if (m_rep) + m_rep->lock_subfunctions (); } void unlock_subfunctions (void) { - m_rep->unlock_subfunctions (); + if (m_rep) + m_rep->unlock_subfunctions (); } std::map<std::string, octave_value> subfunctions (void) const { - return m_rep->subfunctions (); + return (m_rep + ? m_rep->subfunctions () + : std::map<std::string, octave_value> ()); } void erase_subfunctions (void) { - m_rep->erase_subfunctions (); + if (m_rep) + m_rep->erase_subfunctions (); } void mark_subfunctions_in_scope_as_private (const std::string& class_name) { - m_rep->mark_subfunctions_in_scope_as_private (class_name); + if (m_rep) + m_rep->mark_subfunctions_in_scope_as_private (class_name); } bool has_subfunctions (void) const { - return m_rep->has_subfunctions (); + return m_rep ? m_rep->has_subfunctions () : false; } void stash_subfunction_names (const std::list<std::string>& names) { - m_rep->stash_subfunction_names (names); + if (m_rep) + m_rep->stash_subfunction_names (names); } std::list<std::string> subfunction_names (void) const { - return m_rep->subfunction_names (); + return m_rep ? m_rep->subfunction_names () : std::list<std::string> (); } std::list<workspace_element> workspace_info (void) const { - return m_rep->workspace_info (); + return (m_rep + ? m_rep->workspace_info () + : std::list<workspace_element> ()); } octave_value dump (void) const { - return m_rep->dump (); + return m_rep ? m_rep->dump () : octave_value (); } std::string name (void) const { - return m_rep->name (); + return m_rep ? m_rep->name () : ""; } void cache_name (const std::string& name) { - m_rep->cache_name (name); + if (m_rep) + m_rep->cache_name (name); } - octave_user_function *function (void) + octave_user_function * function (void) { - return m_rep->function (); + return m_rep ? m_rep->function () : nullptr; } void set_function (octave_user_function *fcn) { - m_rep->set_function (fcn); + if (m_rep) + m_rep->set_function (fcn); } void set_parent (const symbol_scope& p) { - m_rep->set_parent (p.get_rep ()); + if (m_rep) + m_rep->set_parent (p.get_rep ()); } void set_parent (symbol_scope_rep *p) { - m_rep->set_parent (p); + if (m_rep) + m_rep->set_parent (p); } void update_nest (void) { - m_rep->update_nest (); + if (m_rep) + m_rep->update_nest (); } bool look_nonlocal (const std::string& name, symbol_record& result) { - return m_rep->look_nonlocal (name, result); + return m_rep ? m_rep->look_nonlocal (name, result) : false; } void bind_script_symbols (const symbol_scope& curr_scope) { - m_rep->bind_script_symbols (curr_scope.get_rep ()); + if (m_rep) + m_rep->bind_script_symbols (curr_scope.get_rep ()); } void unbind_script_symbols (void) { - m_rep->unbind_script_symbols (); + if (m_rep) + m_rep->unbind_script_symbols (); } symbol_scope_rep * get_rep (void) const @@ -929,17 +981,14 @@ std::shared_ptr<symbol_scope_rep> m_rep; - // NEW_REP must be dynamically allocated or nullptr. - symbol_scope (symbol_scope_rep *new_rep) : m_rep (new_rep) { } - octave_value dump_symbols_map (void) const { - return m_rep->dump_symbols_map (); + return m_rep ? m_rep->dump_symbols_map () : octave_value (); } symbol_scope_rep * parent_scope_rep (void) const { - return m_rep->parent_scope_rep (); + return m_rep ? m_rep->parent_scope_rep () : nullptr; } }; }
--- a/libinterp/parse-tree/oct-parse.in.yy Wed Dec 06 18:49:31 2017 -0800 +++ b/libinterp/parse-tree/oct-parse.in.yy Thu Dec 07 01:31:34 2017 -0500 @@ -1452,7 +1452,8 @@ { $$ = 0; - // Will get a real name later. + // This scope may serve as the parent scope for local + // functions in classdef files.. lexer.symtab_context.push (octave::symbol_scope ("parser:push_script_symtab")); } ;