diff --git a/util/cairo-script/cairo-script-private.h b/util/cairo-script/cairo-script-private.h index f09c69bef..c5c3b5990 100644 --- a/util/cairo-script/cairo-script-private.h +++ b/util/cairo-script/cairo-script-private.h @@ -424,6 +424,7 @@ union _csi_union_object { struct _csi_scanner { jmp_buf jmpbuf; + int depth; enum { NONE, diff --git a/util/cairo-script/cairo-script-scanner.c b/util/cairo-script/cairo-script-scanner.c index 0c6a64d23..9cc2ce953 100644 --- a/util/cairo-script/cairo-script-scanner.c +++ b/util/cairo-script/cairo-script-scanner.c @@ -1101,13 +1101,22 @@ _csi_scan_file (csi_t *ctx, csi_scanner_t *scan, csi_file_t *src) }; csi_status_t status; - if ((status = setjmp (scan->jmpbuf))) - return status; + /* This function needs to be reentrant to handle recursive scanners. + * i.e. one script executes a second. + */ - scan->line_number = 0; + if (scan->depth++ == 0) { + if ((status = setjmp (scan->jmpbuf))) { + scan->depth = 0; + return status; + } + } + + scan->line_number = 0; /* XXX broken by recursive scanning */ while (func[scan->state] (ctx, scan, src)) ; + --scan->depth; return CSI_STATUS_SUCCESS; }