Mercurial > hg > octave-avbm
diff src/oct-parse.yy @ 10578:cb0883127251
limit on recursion via calls to source function
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Tue, 27 Apr 2010 12:07:04 -0400 |
parents | a61d7248627c |
children | 8baff2aceabc |
line wrap: on
line diff
--- a/src/oct-parse.yy +++ b/src/oct-parse.yy @@ -3877,8 +3877,45 @@ source_file (const std::string& file_name, const std::string& context, bool verbose, bool require_file, const std::string& warn_for) { + // Map from absolute name of script file to recursion level. We + // use a map instead of simply placing a limit on recursion in the + // source_file function so that two mutually recursive scripts + // written as + // + // foo1.m: + // ------ + // foo2 + // + // foo2.m: + // ------ + // foo1 + // + // and called with + // + // foo1 + // + // (for example) will behave the same if they are written as + // + // foo1.m: + // ------ + // source ("foo2.m") + // + // foo2.m: + // ------ + // source ("foo1.m") + // + // and called with + // + // source ("foo1.m") + // + // (for example). + + static std::map<std::string, int> source_call_depth; + std::string file_full_name = file_ops::tilde_expand (file_name); + file_full_name = octave_env::make_absolute (file_full_name); + unwind_protect frame; frame.protect_var (curr_fcn_file_name); @@ -3887,6 +3924,19 @@ curr_fcn_file_name = file_name; curr_fcn_file_full_name = file_full_name; + if (source_call_depth.find (file_full_name) == source_call_depth.end ()) + source_call_depth[file_full_name] = -1; + + frame.protect_var (source_call_depth[file_full_name]); + + source_call_depth[file_full_name]++; + + if (source_call_depth[file_full_name] >= Vmax_recursion_depth) + { + error ("max_recursion_depth exceeded"); + return; + } + if (! context.empty ()) { if (context == "caller")