summaryrefslogtreecommitdiff
path: root/psi/interp.c
diff options
context:
space:
mode:
authorChris Liddell <chris.liddell@artifex.com>2016-10-25 11:16:13 +0100
committerChris Liddell <chris.liddell@artifex.com>2016-10-25 15:37:36 +0100
commit2f3679b53632c5b7b9e9a416311ae82f36645fc9 (patch)
treec8cc20dadef2631f3fba28053a243be42ce3f3d3 /psi/interp.c
parent3f09e7022e39412af98602cdfe22adfb34a7fa63 (diff)
downloadghostpdl-2f3679b53632c5b7b9e9a416311ae82f36645fc9.tar.gz
Bug 697220(2): Fix returning execstackoverflow
In one case of returning execstackoverflow from the main interpreter loop, we'd set the interpreter's private count value of objects to execute, *before* we try to push the ref array onto the stack. As a consequence the object count was for the new array, but the top of the exec stack was still the previous array. This meant when we sync'ed the interpreter loop's internal state with the state in the interpreter context, the size of the top object on the exec stack could be wrong, causing problems in the garbager - especially if the length was too long. To resolve, move the exec stack bounds check before the count gets set.
Diffstat (limited to 'psi/interp.c')
-rw-r--r--psi/interp.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/psi/interp.c b/psi/interp.c
index 0ce633f03..654d9dba0 100644
--- a/psi/interp.c
+++ b/psi/interp.c
@@ -1156,6 +1156,12 @@ x_sub: INCR(x_sub);
prst: /* Prepare to call the procedure (array) in *pvalue. */
store_state(iesp);
pr: /* Call the array in *pvalue. State has been stored. */
+ /* We want to do this check before assigning icount so icount is correct
+ * in the event of a gs_error_execstackoverflow
+ */
+ if (iesp >= estop) {
+ return_with_error_iref(gs_error_execstackoverflow);
+ }
if ((icount = r_size(pvalue) - 1) <= 0) {
if (icount < 0)
goto up; /* 0-element proc */
@@ -1163,8 +1169,6 @@ x_sub: INCR(x_sub);
if (--(*ticks_left) > 0)
goto top;
}
- if (iesp >= estop)
- return_with_error_iref(gs_error_execstackoverflow);
++iesp;
/* Do a ref_assign, but also set iref. */
iesp->tas = pvalue->tas;