~ubuntu-branches/ubuntu/jaunty/ghostscript/jaunty-updates

« back to all changes in this revision

Viewing changes to psi/iscannum.c

  • Committer: Bazaar Package Importer
  • Author(s): Till Kamppeter
  • Date: 2009-01-20 16:40:45 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20090120164045-lnfhi0n30o5lwhwa
Tags: 8.64.dfsg.1~svn9377-0ubuntu1
* New upstream release (SVN rev 9377)
   o Fixes many bugs concerning PDF rendering, to make the PDF printing
     workflow correctly working.
   o Fixes long-standing bugs in many drivers, like input paper tray and
     duplex options not working for the built-in PCL 4, 5, 5c, 5e, and
     6/XL drivers, PDF input not working for bjc600, bjc800, and cups
     output devices, several options not working and uninitialized
     memory with cups output device.
   o Merged nearly all patches of the Ubuntu and Debian packages upstream.
   o Fixes LP: #317810, LP: #314439, LP: #314018.
* debian/patches/03_libpaper_support.dpatch,
  debian/patches/11_gs-cjk_font_glyph_handling_fix.dpatch,
  debian/patches/12_gs-cjk_vertical_writing_metrics_fix.dpatch,
  debian/patches/13_gs-cjk_cjkps_examples.dpatch,
  debian/patches/20_bbox_segv_fix.dpatch,
  debian/patches/21_brother_7x0_gdi_fix.dpatch,
  debian/patches/22_epsn_margin_workaround.dpatch,
  debian/patches/24_gs_man_fix.dpatch,
  debian/patches/25_toolbin_insecure_tmp_usage_fix.dpatch,
  debian/patches/26_assorted_script_fixes.dpatch,
  debian/patches/29_gs_css_fix.dpatch,
  debian/patches/30_ps2pdf_man_improvement.dpatch,
  debian/patches/31_fix-gc-sigbus.dpatch,
  debian/patches/34_ftbfs-on-hurd-fix.dpatch,
  debian/patches/35_disable_libcairo.dpatch,
  debian/patches/38_pxl-duplex.dpatch,
  debian/patches/39_pxl-resolution.dpatch,
  debian/patches/42_gs-init-ps-delaybind-fix.dpatch,
  debian/patches/45_bjc600-bjc800-pdf-input.dpatch,
  debian/patches/48_cups-output-device-pdf-duplex-uninitialized-memory-fix.dpatch,
  debian/patches/50_lips4-floating-point-exception.dpatch,
  debian/patches/52_cups-device-logging.dpatch,
  debian/patches/55_pcl-input-slot-fix.dpatch,
  debian/patches/57_pxl-input-slot-fix.dpatch,
  debian/patches/60_pxl-cups-driver-pdf.dpatch,
  debian/patches/62_onebitcmyk-pdf.dpatch,
  debian/patches/65_too-big-temp-files-1.dpatch,
  debian/patches/67_too-big-temp-files-2.dpatch,
  debian/patches/70_take-into-account-data-in-stream-buffer-before-refill.dpatch:
  Removed, applied upstream.
* debian/patches/01_docdir_fix_for_debian.dpatch,
  debian/patches/02_gs_man_fix_debian.dpatch,
  debian/patches/01_docdir-fix-for-debian.dpatch,
  debian/patches/02_docdir-fix-for-debian.dpatch: Renamed patches to
  make merging with Debian easier.
* debian/patches/32_improve-handling-of-media-size-changes-from-gv.dpatch, 
  debian/patches/33_bad-params-to-xinitimage-on-large-bitmaps.dpatch:
  regenerated for new source directory structure.
* debian/rules: Corrected paths to remove cidfmap (it is in Resource/Init/
  in GS 8.64) and to install headers (source paths are psi/ and base/ now).
* debian/rules: Remove all fontmaps, as DeFoMa replaces them.
* debian/local/pdftoraster/pdftoraster.c,
  debian/local/pdftoraster/pdftoraster.convs, debian/rules: Removed
  added pdftoraster filter and use the one which comes with Ghostscript.
* debian/ghostscript.links: s/8.63/8.64/

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2001-2006 Artifex Software, Inc.
 
2
   All Rights Reserved.
 
3
  
 
4
   This software is provided AS-IS with no warranty, either express or
 
5
   implied.
 
6
 
 
7
   This software is distributed under license and may not be copied, modified
 
8
   or distributed except as expressly authorized under the terms of that
 
9
   license.  Refer to licensing information at http://www.artifex.com/
 
10
   or contact Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134,
 
11
   San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
 
12
*/
 
13
 
 
14
/* $Id: iscannum.c 9043 2008-08-28 22:48:19Z giles $ */
 
15
/* Number scanner for Ghostscript interpreter */
 
16
#include "math_.h"
 
17
#include "ghost.h"
 
18
#include "ierrors.h"
 
19
#include "scommon.h"
 
20
#include "iscan.h"
 
21
#include "iscannum.h"           /* defines interface */
 
22
#include "scanchar.h"
 
23
#include "store.h"
 
24
 
 
25
/*
 
26
 * Warning: this file has a "spaghetti" control structure.  But since this
 
27
 * code accounts for over 10% of the execution time of some PostScript
 
28
 * files, this is one of the few places we feel this is justified.
 
29
 */
 
30
 
 
31
/*
 
32
 * Scan a number.  If the number consumes the entire string, return 0;
 
33
 * if not, set *psp to the first character beyond the number and return 1.
 
34
 */
 
35
int
 
36
scan_number(const byte * str, const byte * end, int sign,
 
37
            ref * pref, const byte ** psp, int scanner_options)
 
38
{
 
39
    const byte *sp = str;
 
40
#define GET_NEXT(cvar, sp, end_action)\
 
41
  if (sp >= end) { end_action; } else cvar = *sp++
 
42
 
 
43
    /*
 
44
     * Powers of 10 up to 6 can be represented accurately as
 
45
     * a single-precision float.
 
46
     */
 
47
#define NUM_POWERS_10 6
 
48
    static const float powers_10[NUM_POWERS_10 + 1] = {
 
49
        1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6
 
50
    };
 
51
    static const double neg_powers_10[NUM_POWERS_10 + 1] = {
 
52
        1e0, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6
 
53
    };
 
54
 
 
55
    int ival;
 
56
    long lval;
 
57
    double dval;
 
58
    int exp10;
 
59
    int code = 0;
 
60
    int c, d;
 
61
    uint max_scan; /* max signed or unsigned int */
 
62
    const byte *const decoder = scan_char_decoder;
 
63
#define IS_DIGIT(d, c)\
 
64
  ((d = decoder[c]) < 10)
 
65
#define WOULD_OVERFLOW(val, d, maxv)\
 
66
  (val >= maxv / 10 && (val > maxv / 10 || d > (int)(maxv % 10)))
 
67
 
 
68
    GET_NEXT(c, sp, return_error(e_syntaxerror));
 
69
    if (!IS_DIGIT(d, c)) {
 
70
        if (c != '.')
 
71
            return_error(e_syntaxerror);
 
72
        /* Might be a number starting with '.'. */
 
73
        GET_NEXT(c, sp, return_error(e_syntaxerror));
 
74
        if (!IS_DIGIT(d, c))
 
75
            return_error(e_syntaxerror);
 
76
        ival = 0;
 
77
        goto i2r;
 
78
    }
 
79
    /* Accumulate an integer in ival. */
 
80
    /* Do up to 4 digits without a loop, */
 
81
    /* since we know this can't overflow and since */
 
82
    /* most numbers have 4 (integer) digits or fewer. */
 
83
    ival = d;
 
84
    if (end - sp >= 3) {        /* just check once */
 
85
        if (!IS_DIGIT(d, (c = *sp))) {
 
86
            sp++;
 
87
            goto ind;
 
88
        }
 
89
        ival = ival * 10 + d;
 
90
        if (!IS_DIGIT(d, (c = sp[1]))) {
 
91
            sp += 2;
 
92
            goto ind;
 
93
        }
 
94
        ival = ival * 10 + d;
 
95
        sp += 3;
 
96
        if (!IS_DIGIT(d, (c = sp[-1])))
 
97
            goto ind;
 
98
        ival = ival * 10 + d;
 
99
    }
 
100
    max_scan = scanner_options & SCAN_PDF_UNSIGNED && sign >= 0 ? ~0 : max_int;
 
101
    for (;; ival = ival * 10 + d) {
 
102
        GET_NEXT(c, sp, goto iret);
 
103
        if (!IS_DIGIT(d, c))
 
104
            break;
 
105
        if (WOULD_OVERFLOW(((unsigned)ival), d, max_scan))
 
106
            goto i2l;
 
107
    }
 
108
  ind:                          /* We saw a non-digit while accumulating an integer in ival. */
 
109
    switch (c) {
 
110
        case '.':
 
111
            GET_NEXT(c, sp, c = EOFC);
 
112
            goto i2r;
 
113
        default:
 
114
            *psp = sp;
 
115
            code = 1;
 
116
            break;
 
117
        case 'e':
 
118
        case 'E':
 
119
            if (sign < 0)
 
120
                ival = -ival;
 
121
            dval = ival;
 
122
            exp10 = 0;
 
123
            goto fe;
 
124
        case '#':
 
125
            {
 
126
                const uint radix = (uint)ival;
 
127
                ulong uval = 0, lmax;
 
128
 
 
129
                if (sign || radix < min_radix || radix > max_radix)
 
130
                    return_error(e_syntaxerror);
 
131
                /* Avoid multiplies for power-of-2 radix. */
 
132
                if (!(radix & (radix - 1))) {
 
133
                    int shift;
 
134
 
 
135
                    switch (radix) {
 
136
                        case 2:
 
137
                            shift = 1, lmax = max_ulong >> 1;
 
138
                            break;
 
139
                        case 4:
 
140
                            shift = 2, lmax = max_ulong >> 2;
 
141
                            break;
 
142
                        case 8:
 
143
                            shift = 3, lmax = max_ulong >> 3;
 
144
                            break;
 
145
                        case 16:
 
146
                            shift = 4, lmax = max_ulong >> 4;
 
147
                            break;
 
148
                        case 32:
 
149
                            shift = 5, lmax = max_ulong >> 5;
 
150
                            break;
 
151
                        default:        /* can't happen */
 
152
                            return_error(e_rangecheck);
 
153
                    }
 
154
                    for (;; uval = (uval << shift) + d) {
 
155
                        GET_NEXT(c, sp, break);
 
156
                        d = decoder[c];
 
157
                        if (d >= radix) {
 
158
                            *psp = sp;
 
159
                            code = 1;
 
160
                            break;
 
161
                        }
 
162
                        if (uval > lmax)
 
163
                            return_error(e_limitcheck);
 
164
                    }
 
165
                } else {
 
166
                    int lrem = max_ulong % radix;
 
167
 
 
168
                    lmax = max_ulong / radix;
 
169
                    for (;; uval = uval * radix + d) {
 
170
                        GET_NEXT(c, sp, break);
 
171
                        d = decoder[c];
 
172
                        if (d >= radix) {
 
173
                            *psp = sp;
 
174
                            code = 1;
 
175
                            break;
 
176
                        }
 
177
                        if (uval >= lmax &&
 
178
                            (uval > lmax || d > lrem)
 
179
                            )
 
180
                            return_error(e_limitcheck);
 
181
                    }
 
182
                }
 
183
                make_int(pref, uval);
 
184
                return code;
 
185
            }
 
186
    }
 
187
iret:
 
188
    make_int(pref, (sign < 0 ? -ival : ival));
 
189
    return code;
 
190
 
 
191
    /* Accumulate a long in lval. */
 
192
i2l:
 
193
    for (lval = (unsigned)ival;;) {
 
194
        if (WOULD_OVERFLOW(((unsigned long)lval), d, ((unsigned long)max_long))) {
 
195
            /* Make a special check for entering the smallest */
 
196
            /* (most negative) integer. */
 
197
            if (lval == max_long / 10 &&
 
198
                d == (int)(max_long % 10) + 1 && sign < 0
 
199
                ) {
 
200
                GET_NEXT(c, sp, c = EOFC);
 
201
                dval = -(double)min_long;
 
202
                if (c == 'e' || c == 'E') {
 
203
                    exp10 = 0;
 
204
                    goto fs;
 
205
                } else if (c == '.') {
 
206
                    GET_NEXT(c, sp, c = EOFC);
 
207
                    exp10 = 0;
 
208
                    goto fd;
 
209
                } else if (!IS_DIGIT(d, c)) {
 
210
                    lval = min_long;
 
211
                    break;
 
212
                }
 
213
            } else
 
214
                dval = (unsigned long)lval;
 
215
            goto l2d;
 
216
        }
 
217
        lval = lval * 10 + d;
 
218
        GET_NEXT(c, sp, goto lret);
 
219
        if (!IS_DIGIT(d, c))
 
220
            break;
 
221
    }
 
222
    switch (c) {
 
223
        case '.':
 
224
            GET_NEXT(c, sp, c = EOFC);
 
225
            exp10 = 0;
 
226
            goto l2r;
 
227
        case EOFC:
 
228
            break;
 
229
        default:
 
230
            *psp = sp;
 
231
            code = 1;
 
232
            break;
 
233
        case 'e':
 
234
        case 'E':
 
235
            exp10 = 0;
 
236
            goto le;
 
237
        case '#':
 
238
            return_error(e_syntaxerror);
 
239
    }
 
240
lret:
 
241
    make_int(pref, (sign < 0 ? -lval : lval));
 
242
    return code;
 
243
 
 
244
    /* Accumulate a double in dval. */
 
245
l2d:
 
246
    exp10 = 0;
 
247
    for (;;) {
 
248
        dval = dval * 10 + d;
 
249
        GET_NEXT(c, sp, c = EOFC);
 
250
        if (!IS_DIGIT(d, c))
 
251
            break;
 
252
    }
 
253
    switch (c) {
 
254
        case '.':
 
255
            GET_NEXT(c, sp, c = EOFC);
 
256
            exp10 = 0;
 
257
            goto fd;
 
258
        default:
 
259
            *psp = sp;
 
260
            code = 1;
 
261
            /* falls through */
 
262
        case EOFC:
 
263
            if (sign < 0)
 
264
                dval = -dval;
 
265
            goto rret;
 
266
        case 'e':
 
267
        case 'E':
 
268
            exp10 = 0;
 
269
            goto fs;
 
270
        case '#':
 
271
            return_error(e_syntaxerror);
 
272
    }
 
273
 
 
274
    /* We saw a '.' while accumulating an integer in ival. */
 
275
i2r:
 
276
    exp10 = 0;
 
277
    while (IS_DIGIT(d, c) || c == '-') {
 
278
        /*
 
279
         * PostScript gives an error on numbers with a '-' following a '.'
 
280
         * Adobe Acrobat Reader (PDF) apparently doesn't treat this as an
 
281
         * error. Experiments show that the numbers following the '-' are
 
282
         * ignored, so we swallow the fractional part. SCAN_PDF_INV_NUM
 
283
         *  enables this compatibility kloodge.
 
284
         */
 
285
        if (c == '-') {
 
286
            if ((SCAN_PDF_INV_NUM & scanner_options) == 0)
 
287
                break;
 
288
            do {
 
289
                GET_NEXT(c, sp, c = EOFC);
 
290
            } while (IS_DIGIT(d, c));
 
291
            break;
 
292
        }
 
293
        if (WOULD_OVERFLOW(ival, d, max_int)) {
 
294
            lval = ival;
 
295
            goto l2r;
 
296
        }
 
297
        ival = ival * 10 + d;
 
298
        exp10--;
 
299
        GET_NEXT(c, sp, c = EOFC);
 
300
    }
 
301
    if (sign < 0)
 
302
        ival = -ival;
 
303
    /* Take a shortcut for the common case */
 
304
    if (!(c == 'e' || c == 'E' || exp10 < -NUM_POWERS_10)) {    /* Check for trailing garbage */
 
305
        if (c != EOFC)
 
306
            *psp = sp, code = 1;
 
307
        make_real(pref, ival * neg_powers_10[-exp10]);
 
308
        return code;
 
309
    }
 
310
    dval = ival;
 
311
    goto fe;
 
312
 
 
313
    /* We saw a '.' while accumulating a long in lval. */
 
314
l2r:
 
315
    while (IS_DIGIT(d, c) || c == '-') {
 
316
        /* Handle bogus '-' following '.' as in i2r above.      */
 
317
        if (c == '-') {
 
318
            if ((scanner_options & SCAN_PDF_INV_NUM) == 0)
 
319
                break;
 
320
            do {
 
321
                GET_NEXT(c, sp, c = EOFC);
 
322
            } while (IS_DIGIT(d, c));
 
323
            break;
 
324
        }
 
325
        if (WOULD_OVERFLOW(lval, d, max_long)) {
 
326
            dval = lval;
 
327
            goto fd;
 
328
        }
 
329
        lval = lval * 10 + d;
 
330
        exp10--;
 
331
        GET_NEXT(c, sp, c = EOFC);
 
332
    }
 
333
le:
 
334
    if (sign < 0)
 
335
        lval = -lval;
 
336
    dval = lval;
 
337
    goto fe;
 
338
 
 
339
    /* Now we are accumulating a double in dval. */
 
340
fd:
 
341
    while (IS_DIGIT(d, c)) {
 
342
        dval = dval * 10 + d;
 
343
        exp10--;
 
344
        GET_NEXT(c, sp, c = EOFC);
 
345
    }
 
346
fs:
 
347
    if (sign < 0)
 
348
        dval = -dval;
 
349
fe:
 
350
    /* Now dval contains the value, negated if necessary. */
 
351
    switch (c) {
 
352
        case 'e':
 
353
        case 'E':
 
354
            {                   /* Check for a following exponent. */
 
355
                int esign = 0;
 
356
                int iexp;
 
357
 
 
358
                GET_NEXT(c, sp, return_error(e_syntaxerror));
 
359
                switch (c) {
 
360
                    case '-':
 
361
                        esign = 1;
 
362
                    case '+':
 
363
                        GET_NEXT(c, sp, return_error(e_syntaxerror));
 
364
                }
 
365
                /* Scan the exponent.  We limit it arbitrarily to 999. */
 
366
                if (!IS_DIGIT(d, c))
 
367
                    return_error(e_syntaxerror);
 
368
                iexp = d;
 
369
                for (;; iexp = iexp * 10 + d) {
 
370
                    GET_NEXT(c, sp, break);
 
371
                    if (!IS_DIGIT(d, c)) {
 
372
                        *psp = sp;
 
373
                        code = 1;
 
374
                        break;
 
375
                    }
 
376
                    if (iexp > 99)
 
377
                        return_error(e_limitcheck);
 
378
                }
 
379
                if (esign)
 
380
                    exp10 -= iexp;
 
381
                else
 
382
                    exp10 += iexp;
 
383
                break;
 
384
            }
 
385
        default:
 
386
            *psp = sp;
 
387
            code = 1;
 
388
        case EOFC:
 
389
            ;
 
390
    }
 
391
    /* Compute dval * 10^exp10. */
 
392
    if (exp10 > 0) {
 
393
        while (exp10 > NUM_POWERS_10)
 
394
            dval *= powers_10[NUM_POWERS_10],
 
395
                exp10 -= NUM_POWERS_10;
 
396
        if (exp10 > 0)
 
397
            dval *= powers_10[exp10];
 
398
    } else if (exp10 < 0) {
 
399
        while (exp10 < -NUM_POWERS_10)
 
400
            dval /= powers_10[NUM_POWERS_10],
 
401
                exp10 += NUM_POWERS_10;
 
402
        if (exp10 < 0)
 
403
            dval /= powers_10[-exp10];
 
404
    }
 
405
    /*
 
406
     * Check for an out-of-range result.  Currently we don't check for
 
407
     * absurdly large numbers of digits in the accumulation loops,
 
408
     * but we should.
 
409
     */
 
410
    if (dval >= 0) {
 
411
        if (dval > MAX_FLOAT)
 
412
            return_error(e_limitcheck);
 
413
    } else {
 
414
        if (dval < -MAX_FLOAT)
 
415
            return_error(e_limitcheck);
 
416
    }
 
417
rret:
 
418
    make_real(pref, dval);
 
419
    return code;
 
420
}