From: Reinhold Kainhofer Date: Thu, 15 Sep 2011 13:36:48 +0000 (+0200) Subject: Introduce a maximum depth for markup evaluation X-Git-Tag: release/2.15.12-1~7 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=16e626a8524421eda692cb19be6d0ec5bff723b7;p=lilypond.git Introduce a maximum depth for markup evaluation This will fix cases where a markup function calls itself (or other functions) recursively with different arguments, so the loop detection fails. --- diff --git a/input/regression/markup-depth-non-terminating.ly b/input/regression/markup-depth-non-terminating.ly new file mode 100644 index 0000000000..52e0f70ee0 --- /dev/null +++ b/input/regression/markup-depth-non-terminating.ly @@ -0,0 +1,15 @@ +\version "2.15.12" +#(ly:set-option 'warning-as-error #f) + +\header { + texidoc = "Markups have a maximum depth to prevent non-termination." + +} + +% A simple markup function that calls itself and increases its argument, so +% it will grow forever, unless we terminate it. +#(define-markup-command (recursive-explosion layout props nr) + (number?) + (interpret-markup layout props (make-recursive-explosion-markup (+ nr 1)))) + +\markup { Test: \recursive-explosion #1 } diff --git a/lily/text-interface.cc b/lily/text-interface.cc index 5bd13641d7..232d9c3824 100644 --- a/lily/text-interface.cc +++ b/lily/text-interface.cc @@ -28,6 +28,7 @@ #include "modified-font-metric.hh" #include "output-def.hh" #include "pango-font.hh" +#include "program-option.hh" #include "international.hh" #include "warn.hh" @@ -118,6 +119,19 @@ Text_interface::interpret_markup (SCM layout_smob, SCM props, SCM markup) } } + /* Check for non-terminating markups, e.g. recursive calls with + * changing arguments */ + SCM opt_depth = ly_get_option (ly_symbol2scm ("max-markup-depth")); + size_t max_depth = robust_scm2int(opt_depth, 1024); + if (depth > max_depth) + { + string name = ly_symbol2string (scm_procedure_name (func)); + // TODO: Also print the arguments of the markup! + non_fatal_error (_f("Markup depth exceeds maximal value of %d; " + "Markup: %s", max_depth, name.c_str ())); + return Stencil().smobbed_copy (); + } + encountered_markups.push_back (markup); SCM retval = scm_apply_2 (func, layout_smob, props, args); encountered_markups.pop_back (); diff --git a/scm/lily.scm b/scm/lily.scm index ac735bc489..f3ce9c33c0 100644 --- a/scm/lily.scm +++ b/scm/lily.scm @@ -120,6 +120,9 @@ jobs.") (log-file #f "If string FOO is given as argument, redirect output to log file `FOO.log'.") + (max-markup-depth 1024 +"Maximum depth for the markup tree. If a markup has more levels, assume that +it will not terminate at all and print out a warning, but continue processing.") (midi-extension ,(if (eq? PLATFORM 'windows) "mid" "midi")