From a7a180366686298fa7f7aae686152e5a759d3a89 Mon Sep 17 00:00:00 2001 From: Sebastian Rasmussen Date: Thu, 16 Feb 2012 01:08:05 +0100 Subject: Take care of boundary conditions in ps function evaluation. Floating point numbers are now clamped, division by zero is approximated by minimum or maximum value and NaN results in 1.0. --- pdf/pdf_function.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'pdf') diff --git a/pdf/pdf_function.c b/pdf/pdf_function.c index 932d4c77..a6941ca1 100644 --- a/pdf/pdf_function.c +++ b/pdf/pdf_function.c @@ -203,7 +203,13 @@ ps_push_real(ps_stack *st, float n) if (!ps_overflow(st, 1)) { st->stack[st->sp].type = PS_REAL; - st->stack[st->sp].u.f = n; + if (isnan(n)) + { + /* Push 1.0, as it's a small known value that won't + cause a divide by 0. Same reason as in fz_atof. */ + n = 1.0; + } + st->stack[st->sp].u.f = CLAMP(n, -FLT_MAX, FLT_MAX); st->sp++; } } @@ -360,9 +366,9 @@ ps_run(fz_context *ctx, psobj *code, ps_stack *st, int pc) case PS_OP_BITSHIFT: i2 = ps_pop_int(st); i1 = ps_pop_int(st); - if (i2 > 0) + if (i2 > 0 && i2 < 8 * sizeof (i2)) ps_push_int(st, i1 << i2); - else if (i2 < 0) + else if (i2 < 0 && i2 > -8 * sizeof (i2)) ps_push_int(st, (int)((unsigned int)i1 >> i2)); else ps_push_int(st, i1); @@ -393,7 +399,10 @@ ps_run(fz_context *ctx, psobj *code, ps_stack *st, int pc) case PS_OP_DIV: r2 = ps_pop_real(st); r1 = ps_pop_real(st); - ps_push_real(st, r1 / r2); + if (fabsf(r2) < FLT_EPSILON) + ps_push_real(st, r1 / r2); + else + ps_push_real(st, DIV_BY_ZERO(r1, r2, -FLT_MAX, FLT_MAX)); break; case PS_OP_DUP: @@ -466,7 +475,10 @@ ps_run(fz_context *ctx, psobj *code, ps_stack *st, int pc) case PS_OP_IDIV: i2 = ps_pop_int(st); i1 = ps_pop_int(st); - ps_push_int(st, i1 / i2); + if (i2 != 0) + ps_push_int(st, i1 / i2); + else + ps_push_int(st, DIV_BY_ZERO(i1, i2, INT_MIN, INT_MAX)); break; case PS_OP_INDEX: @@ -512,7 +524,10 @@ ps_run(fz_context *ctx, psobj *code, ps_stack *st, int pc) case PS_OP_MOD: i2 = ps_pop_int(st); i1 = ps_pop_int(st); - ps_push_int(st, i1 % i2); + if (i2 != 0) + ps_push_int(st, i1 % i2); + else + ps_push_int(st, DIV_BY_ZERO(i1, i2, INT_MIN, INT_MAX)); break; case PS_OP_MUL: -- cgit v1.2.3 From 65ca742ba4aabda2768ba4423eeaf06d5d46c76e Mon Sep 17 00:00:00 2001 From: Robin Watts Date: Mon, 12 Mar 2012 13:11:03 +0000 Subject: Fix bitshifting by a negative amount in PS functions When bitshifting by a negative amount, we should shift right; thanks to Sebras' work in this area, I spotted that we are attempting to shift right by a negative number. --- pdf/pdf_function.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'pdf') diff --git a/pdf/pdf_function.c b/pdf/pdf_function.c index a6941ca1..b02ae3c5 100644 --- a/pdf/pdf_function.c +++ b/pdf/pdf_function.c @@ -369,7 +369,7 @@ ps_run(fz_context *ctx, psobj *code, ps_stack *st, int pc) if (i2 > 0 && i2 < 8 * sizeof (i2)) ps_push_int(st, i1 << i2); else if (i2 < 0 && i2 > -8 * sizeof (i2)) - ps_push_int(st, (int)((unsigned int)i1 >> i2)); + ps_push_int(st, (int)((unsigned int)i1 >> -i2)); else ps_push_int(st, i1); break; -- cgit v1.2.3 From caf8e7a6c7cfeb245cdb5ac44d310a82ab0155b3 Mon Sep 17 00:00:00 2001 From: Robin Watts Date: Mon, 12 Mar 2012 13:33:29 +0000 Subject: Squash MSVC warning. --- pdf/pdf_function.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'pdf') diff --git a/pdf/pdf_function.c b/pdf/pdf_function.c index b02ae3c5..681c0157 100644 --- a/pdf/pdf_function.c +++ b/pdf/pdf_function.c @@ -368,7 +368,7 @@ ps_run(fz_context *ctx, psobj *code, ps_stack *st, int pc) i1 = ps_pop_int(st); if (i2 > 0 && i2 < 8 * sizeof (i2)) ps_push_int(st, i1 << i2); - else if (i2 < 0 && i2 > -8 * sizeof (i2)) + else if (i2 < 0 && i2 > -8 * (int)sizeof (i2)) ps_push_int(st, (int)((unsigned int)i1 >> -i2)); else ps_push_int(st, i1); -- cgit v1.2.3