changeset 14066:80bda7c4f012 stable

Avoid segfault in test() and demo() blocks with embedded functions (Bugs #35068, #32843, #33981) * test.m, demo.m: Search code block to be executed for any embedded functions. Return an error if any functions found without executing the code block to avoid segmentation fault.
author Rik <octave@nomad.inbox5.com>
date Sun, 18 Dec 2011 18:15:18 -0800
parents 3709aaf73715
children b2e9c4b0c4f8
files scripts/testfun/demo.m scripts/testfun/test.m
diffstat 2 files changed, 24 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/testfun/demo.m
+++ b/scripts/testfun/demo.m
@@ -122,11 +122,19 @@
     ## Process each demo without failing
     try
       block = code(idx(doidx(i)):idx(doidx(i)+1)-1);
-      ## Use an environment without variables
-      eval (cstrcat ("function __demo__()\n", block, "\nendfunction"));
-      ## Display the code that will be executed before executing it
-      printf ("%s example %d:%s\n\n", name, doidx(i), block);
-      __demo__;
+      ## FIXME: need to check for embedded test functions, which cause
+      ## segfaults, until issues with subfunctions in functions are resolved.
+      embed_func = regexp (block, '^\s*function ', 'once', 'lineanchors');
+      if (isempty (embed_func))
+        ## Use an environment without variables
+        eval (cstrcat ("function __demo__()\n", block, "\nendfunction"));
+        ## Display the code that will be executed before executing it
+        printf ("%s example %d:%s\n\n", name, doidx(i), block);
+        __demo__;
+      else
+        error (["Functions embedded in %!demo blocks are not allowed.\n", ...
+                "Use the %!function/%!endfunction syntax instead to define shared functions for testing.\n"]);
+      endif
     catch
       ## Let the programmer know which demo failed.
       printf ("%s example %d: failed\n%s\n", name, doidx(i), lasterr ());
--- a/scripts/testfun/test.m
+++ b/scripts/testfun/test.m
@@ -491,9 +491,17 @@
     ## evaluate code for test, shared, and assert.
     if (! isempty(__code))
       try
-        eval (sprintf ("function %s__test__(%s)\n%s\nendfunction",
-                       __shared_r,__shared, __code));
-        eval (sprintf ("%s__test__(%s);", __shared_r, __shared));
+        ## FIXME: need to check for embedded test functions, which cause
+        ## segfaults, until issues with subfunctions in functions are resolved.
+        embed_func = regexp (__code, '^\s*function ', 'once', 'lineanchors');
+        if (isempty (embed_func))
+          eval (sprintf ("function %s__test__(%s)\n%s\nendfunction",
+                         __shared_r,__shared, __code));
+          eval (sprintf ("%s__test__(%s);", __shared_r, __shared));
+        else
+          error (["Functions embedded in %!test blocks are not allowed.\n", ...
+                  "Use the %!function/%!endfunction syntax instead to define shared functions for testing.\n"]);
+        endif
       catch
         if (strcmp (__type, "xtest"))
            __msg = sprintf ("%sknown failure\n%s", __signal_fail, lasterr ());