Fix for 687497, for loop with integer increment and big limit doesn't work
Alex Cherepanov <[email protected]> Sat, 05 Jun 2004 07:26:21 -0400
| Newsgroups | gmane.comp.printing.ghostscript.patches |
|---|---|
| Organization | Coscript Software |
| Message-ID | <[email protected]> |
Check for integer overflow in the for loop control variable and break out of the loop when the overflow is detected. Use floating point calculations when the end value of the loop doesn't fit into an integer. The latter change doesn't work well because of the lower precision of float numbers and rounding effects. The test file attached shows (among other things) the effects of integer to float conversion. _______________________________________________ gs-code-review mailing list [email protected] http://www.ghostscript.com/mailman/listinfo/gs-code-review
zcontrol.c.diff
(text/plain, 2.4 KB)
Index: gs/src/zcontrol.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/zcontrol.c,v
retrieving revision 1.10
diff -b -u -r1.10 zcontrol.c
--- gs/src/zcontrol.c 16 Sep 2002 17:11:15 -0000 1.10
+++ gs/src/zcontrol.c 4 Jun 2004 23:30:25 -0000
@@ -300,10 +300,10 @@
os_ptr op = osp;
register es_ptr ep;
- check_estack(7);
- ep = esp + 6;
+ check_estack(8);
+ ep = esp + 7;
check_proc(*op);
- /* Push a mark, the control variable set to the initial value, */
+ /* Push a mark, the initial value, the control variable set to the initial value, */
/* the increment, the limit, and the procedure, */
/* and invoke the continuation operator. */
if (r_has_type(op - 3, t_integer) &&
@@ -316,6 +316,10 @@
make_int(ep - 2, op[-1].value.intval);
break;
case t_real:
+ if (op[-1].value.realval >= max_long + 1.0 ||
+ op[-1].value.realval <= min_long - 1.0 )
+ goto float_loop;
+ /* Not a bug! "-1 1 -0.5 {==} for" prints -1 0 on Adobe */
make_int(ep - 2, (long)op[-1].value.realval);
break;
default:
@@ -326,6 +330,8 @@
else
make_op_estack(ep, for_neg_int_continue);
} else {
+ float_loop:;
+ {
float params[3];
int code;
@@ -336,7 +342,9 @@
make_real(ep - 2, params[2]);
make_op_estack(ep, for_real_continue);
}
- make_mark_estack(ep - 5, es_for, no_cleanup);
+ }
+ make_mark_estack(ep - 6, es_for, no_cleanup);
+ ref_assign(ep - 5, ep - 4);
ref_assign(ep - 1, op);
esp = ep;
pop(4);
@@ -354,8 +362,9 @@
register es_ptr ep = esp;
long var = ep[-3].value.intval;
- if (var > ep[-1].value.intval) {
- esp -= 5; /* pop everything */
+ if (var > ep[-1].value.intval ||
+ var < ep[-4].value.intval) {
+ esp -= 6; /* pop everything */
return o_pop_estack;
}
push(1);
@@ -373,8 +382,9 @@
register es_ptr ep = esp;
long var = ep[-3].value.intval;
- if (var < ep[-1].value.intval) {
- esp -= 5; /* pop everything */
+ if (var < ep[-1].value.intval ||
+ var > ep[-4].value.intval) {
+ esp -= 6; /* pop everything */
return o_pop_estack;
}
push(1);
@@ -396,7 +406,7 @@
if (incr >= 0 ? (var > ep[-1].value.realval) :
(var < ep[-1].value.realval)
) {
- esp -= 5; /* pop everything */
+ esp -= 6; /* pop everything */
return o_pop_estack;
}
push(1);
for.ps
(application/postscript, 2.4 KB) - not displayed