XFA: merge patch from CL 817753002
[pdfium.git] / core / src / fxge / fx_freetype / fxft2.5.01 / src / psaux / psconv.c
1 /***************************************************************************/
2 /*                                                                         */
3 /*  psconv.c                                                               */
4 /*                                                                         */
5 /*    Some convenience conversions (body).                                 */
6 /*                                                                         */
7 /*  Copyright 2006, 2008, 2009, 2012-2013 by                               */
8 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9 /*                                                                         */
10 /*  This file is part of the FreeType project, and may only be used,       */
11 /*  modified, and distributed under the terms of the FreeType project      */
12 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13 /*  this file you indicate that you have read the license and              */
14 /*  understand and accept it fully.                                        */
15 /*                                                                         */
16 /***************************************************************************/
17
18
19 #include "../../include/ft2build.h"
20 #include "../../include/freetype/internal/psaux.h"
21 #include "../../include/freetype/internal/ftdebug.h"
22
23 #include "psconv.h"
24 #include "psauxerr.h"
25
26
27   /*************************************************************************/
28   /*                                                                       */
29   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
30   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
31   /* messages during execution.                                            */
32   /*                                                                       */
33 #undef  FT_COMPONENT
34 #define FT_COMPONENT  trace_psconv
35
36
37   /* The following array is used by various functions to quickly convert */
38   /* digits (both decimal and non-decimal) into numbers.                 */
39
40 #if 'A' == 65
41   /* ASCII */
42
43   static const FT_Char  ft_char_table[128] =
44   {
45     /* 0x00 */
46     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
47     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
48     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
49      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1,
50     -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
51     25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,
52     -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
53     25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,
54   };
55
56   /* no character >= 0x80 can represent a valid number */
57 #define OP  >=
58
59 #endif /* 'A' == 65 */
60
61 #if 'A' == 193
62   /* EBCDIC */
63
64   static const FT_Char  ft_char_table[128] =
65   {
66     /* 0x80 */
67     -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, -1, -1, -1, -1, -1,
68     -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1,
69     -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1,
70     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
71     -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, -1, -1, -1, -1, -1,
72     -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1,
73     -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1,
74      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1,
75   };
76
77   /* no character < 0x80 can represent a valid number */
78 #define OP  <
79
80 #endif /* 'A' == 193 */
81
82
83   FT_LOCAL_DEF( FT_Long )
84   PS_Conv_Strtol( FT_Byte**  cursor,
85                   FT_Byte*   limit,
86                   FT_Long    base )
87   {
88     FT_Byte*  p = *cursor;
89
90     FT_Long   num           = 0;
91     FT_Bool   sign          = 0;
92     FT_Bool   have_overflow = 0;
93
94     FT_Long   num_limit;
95     FT_Char   c_limit;
96
97
98     if ( p >= limit )
99       goto Bad;
100
101     if ( base < 2 || base > 36 )
102     {
103       FT_TRACE4(( "!!!INVALID BASE:!!!" ));
104       return 0;
105     }
106
107     if ( *p == '-' || *p == '+' )
108     {
109       sign = FT_BOOL( *p == '-' );
110
111       p++;
112       if ( p == limit )
113         goto Bad;
114     }
115
116     num_limit = 0x7FFFFFFFL / base;
117     c_limit   = (FT_Char)( 0x7FFFFFFFL % base );
118
119     for ( ; p < limit; p++ )
120     {
121       FT_Char  c;
122
123
124       if ( IS_PS_SPACE( *p ) || *p OP 0x80 )
125         break;
126
127       c = ft_char_table[*p & 0x7f];
128
129       if ( c < 0 || c >= base )
130         break;
131
132       if ( num > num_limit || ( num == num_limit && c > c_limit ) )
133         have_overflow = 1;
134       else
135         num = num * base + c;
136     }
137
138     *cursor = p;
139
140     if ( have_overflow )
141     {
142       num = 0x7FFFFFFFL;
143       FT_TRACE4(( "!!!OVERFLOW:!!!" ));
144     }
145
146     if ( sign )
147       num = -num;
148
149     return num;
150
151   Bad:
152     FT_TRACE4(( "!!!END OF DATA:!!!" ));
153     return 0;
154   }
155
156
157   FT_LOCAL_DEF( FT_Long )
158   PS_Conv_ToInt( FT_Byte**  cursor,
159                  FT_Byte*   limit )
160
161   {
162     FT_Byte*  p = *cursor;
163     FT_Byte*  curp;
164
165     FT_Long   num;
166
167
168     curp = p;
169     num  = PS_Conv_Strtol( &p, limit, 10 );
170
171     if ( p == curp )
172       return 0;
173
174     if ( p < limit && *p == '#' )
175     {
176       p++;
177
178       curp = p;
179       num  = PS_Conv_Strtol( &p, limit, num );
180
181       if ( p == curp )
182         return 0;
183     }
184
185     *cursor = p;
186
187     return num;
188   }
189
190
191   FT_LOCAL_DEF( FT_Fixed )
192   PS_Conv_ToFixed( FT_Byte**  cursor,
193                    FT_Byte*   limit,
194                    FT_Long    power_ten )
195   {
196     FT_Byte*  p = *cursor;
197     FT_Byte*  curp;
198         // Fix the Vulnerability Report FoxIT Reader - MSVR-10-0077.
199         // We must use 64-bit integer to avoid overflow. If there is some 64-bit integer support.
200         // Since some platform doesn't support 64-bit integer, then use integer instead.
201 #if defined(FT_INT64)
202     FT_INT64  integral = 0;
203     FT_INT64  decimal = 0;
204 #else
205         FT_Long integral = 0;
206         FT_Long decimal = 0;
207         FT_Int temp0 = 65536;
208         FT_Int temp1 = power_ten;
209 #endif
210         FT_Long divider = 1;
211
212         FT_Bool   sign = 0;
213     FT_Bool   have_overflow  = 0;
214     FT_Bool   have_underflow = 0;
215
216     if ( p >= limit )
217       goto Bad;
218
219     if ( *p == '-' || *p == '+' )
220     {
221       sign = FT_BOOL( *p == '-' );
222
223       p++;
224       if ( p == limit )
225         goto Bad;
226     }
227
228     /* read the integer part */
229     if ( *p != '.' )
230     {
231       curp     = p;
232
233                 // Fix the Vulnerability Report FoxIT Reader - MSVR-10-0077.
234                 // Limited to the fix-point mechanism, we have no choice now to crop the value domain.
235                 // Do accurate overflow check if FT_INT64 supported, otherwise vague check.
236 #if defined(FT_INT64)
237                 integral = ((FT_INT64)PS_Conv_ToInt( &p, limit )) << 16;
238 #else
239                 // We use 'power_ten' and 2^16 to compute the coefficient.
240                 //while ( temp1 > 0 ) { temp0 *= 10; temp1 --; }
241                 //while ( temp1 < 0 ) { temp0 /= 10; temp1 ++; }
242                 
243                 integral = PS_Conv_ToInt( &p, limit );
244                 if ( p == curp )
245                         return 0;
246                 if ( integral > 0x7FFF )
247                         have_overflow = 1;
248                 else 
249                         integral = integral << 16;
250 #endif   
251     }
252
253     /* read the decimal part */
254     if ( p < limit && *p == '.' )
255     {
256       p++;
257
258       for ( ; p < limit; p++ )
259       {
260         FT_Char  c;
261
262
263         if ( IS_PS_SPACE( *p ) || *p OP 0x80 )
264           break;
265
266         c = ft_char_table[*p & 0x7f];
267
268         if ( c < 0 || c >= 10 )
269           break;
270
271         if ( decimal < 0xCCCCCCCL )
272         {
273           decimal = decimal * 10 + c;
274
275           if ( !integral && power_ten > 0 )
276             power_ten--;
277           else
278             divider *= 10;
279         }
280       }
281     }
282
283     /* read exponent, if any */
284     if ( p + 1 < limit && ( *p == 'e' || *p == 'E' ) )
285     {
286       FT_Long  exponent;
287
288
289       p++;
290
291       curp     = p;
292       exponent = PS_Conv_ToInt( &p, limit );
293
294       if ( curp == p )
295         return 0;
296
297       /* arbitrarily limit exponent */
298       if ( exponent > 1000 )
299         have_overflow = 1;
300       else if ( exponent < -1000 )
301         have_underflow = 1;
302       else
303         power_ten += exponent;
304     }
305
306     *cursor = p;
307
308     if ( !integral && !decimal )
309       return 0;
310
311     if ( have_overflow )
312       goto Overflow;
313     if ( have_underflow )
314       goto Underflow;
315
316     while ( power_ten > 0 )
317     {
318       if ( integral >= 0xCCCCCCCL )
319         goto Overflow;
320       integral *= 10;
321
322       if ( decimal >= 0xCCCCCCCL )
323       {
324         if ( divider == 1 )
325           goto Overflow;
326         divider /= 10;
327       }
328       else
329         decimal *= 10;
330
331       power_ten--;
332     }
333
334     while ( power_ten < 0 )
335     {
336       integral /= 10;
337       if ( divider < 0xCCCCCCCL )
338         divider *= 10;
339       else
340         decimal /= 10;
341
342       if ( !integral && !decimal )
343         goto Underflow;
344
345       power_ten++;
346     }
347
348 // Fix the Vulnerability Report FoxIT Reader - MSVR-10-0077.
349         // Limited to the fix-point mechanism, we have no choice now to crop the value domain.
350         // Do accurate overflow check if FT_INT64 supported, otherwise ignore the check at this moment.
351         // Since there is also a check using divider < 10000000L.  
352 #if defined(FT_INT64) 
353     if ( decimal ) {
354                 integral += FT_DivFix( (FT_Long)decimal, divider );
355         }
356         if ( integral > 2147483647) integral = 2147483647;
357 #else
358         if ( decimal ) {
359                 integral += FT_DivFix( decimal, divider );
360         }
361 #endif
362
363
364   Exit:
365     if ( sign )
366       integral = -integral;
367
368     return (FT_Long)integral;
369
370   Bad:
371     FT_TRACE4(( "!!!END OF DATA:!!!" ));
372     return 0;
373
374   Overflow:
375     integral = 0x7FFFFFFFL;
376     FT_TRACE4(( "!!!OVERFLOW:!!!" ));
377     goto Exit;
378
379   Underflow:
380     FT_TRACE4(( "!!!UNDERFLOW:!!!" ));
381     return 0;
382   }
383
384
385 #if 0
386   FT_LOCAL_DEF( FT_UInt )
387   PS_Conv_StringDecode( FT_Byte**  cursor,
388                         FT_Byte*   limit,
389                         FT_Byte*   buffer,
390                         FT_Offset  n )
391   {
392     FT_Byte*  p;
393     FT_UInt   r = 0;
394
395
396     for ( p = *cursor; r < n && p < limit; p++ )
397     {
398       FT_Byte  b;
399
400
401       if ( *p != '\\' )
402       {
403         buffer[r++] = *p;
404
405         continue;
406       }
407
408       p++;
409
410       switch ( *p )
411       {
412       case 'n':
413         b = '\n';
414         break;
415       case 'r':
416         b = '\r';
417         break;
418       case 't':
419         b = '\t';
420         break;
421       case 'b':
422         b = '\b';
423         break;
424       case 'f':
425         b = '\f';
426         break;
427       case '\r':
428         p++;
429         if ( *p != '\n' )
430         {
431           b = *p;
432
433           break;
434         }
435         /* no break */
436       case '\n':
437         continue;
438         break;
439       default:
440         if ( IS_PS_DIGIT( *p ) )
441         {
442           b = *p - '0';
443
444           p++;
445
446           if ( IS_PS_DIGIT( *p ) )
447           {
448             b = b * 8 + *p - '0';
449
450             p++;
451
452             if ( IS_PS_DIGIT( *p ) )
453               b = b * 8 + *p - '0';
454             else
455             {
456               buffer[r++] = b;
457               b = *p;
458             }
459           }
460           else
461           {
462             buffer[r++] = b;
463             b = *p;
464           }
465         }
466         else
467           b = *p;
468         break;
469       }
470
471       buffer[r++] = b;
472     }
473
474     *cursor = p;
475
476     return r;
477   }
478 #endif /* 0 */
479
480
481   FT_LOCAL_DEF( FT_UInt )
482   PS_Conv_ASCIIHexDecode( FT_Byte**  cursor,
483                           FT_Byte*   limit,
484                           FT_Byte*   buffer,
485                           FT_Offset  n )
486   {
487     FT_Byte*  p;
488     FT_UInt   r   = 0;
489     FT_UInt   w   = 0;
490     FT_UInt   pad = 0x01;
491
492
493     n *= 2;
494
495 #if 1
496
497     p = *cursor;
498
499     if ( p >= limit )
500       return 0;
501
502     if ( n > (FT_UInt)( limit - p ) )
503       n = (FT_UInt)( limit - p );
504
505     /* we try to process two nibbles at a time to be as fast as possible */
506     for ( ; r < n; r++ )
507     {
508       FT_UInt  c = p[r];
509
510
511       if ( IS_PS_SPACE( c ) )
512         continue;
513
514       if ( c OP 0x80 )
515         break;
516
517       c = ft_char_table[c & 0x7F];
518       if ( (unsigned)c >= 16 )
519         break;
520
521       pad = ( pad << 4 ) | c;
522       if ( pad & 0x100 )
523       {
524         buffer[w++] = (FT_Byte)pad;
525         pad         = 0x01;
526       }
527     }
528
529     if ( pad != 0x01 )
530       buffer[w++] = (FT_Byte)( pad << 4 );
531
532     *cursor = p + r;
533
534     return w;
535
536 #else /* 0 */
537
538     for ( r = 0; r < n; r++ )
539     {
540       FT_Char  c;
541
542
543       if ( IS_PS_SPACE( *p ) )
544         continue;
545
546       if ( *p OP 0x80 )
547         break;
548
549       c = ft_char_table[*p & 0x7f];
550
551       if ( (unsigned)c >= 16 )
552         break;
553
554       if ( r & 1 )
555       {
556         *buffer = (FT_Byte)(*buffer + c);
557         buffer++;
558       }
559       else
560         *buffer = (FT_Byte)(c << 4);
561
562       r++;
563     }
564
565     *cursor = p;
566
567     return ( r + 1 ) / 2;
568
569 #endif /* 0 */
570
571   }
572
573
574   FT_LOCAL_DEF( FT_UInt )
575   PS_Conv_EexecDecode( FT_Byte**   cursor,
576                        FT_Byte*    limit,
577                        FT_Byte*    buffer,
578                        FT_Offset   n,
579                        FT_UShort*  seed )
580   {
581     FT_Byte*  p;
582     FT_UInt   r;
583     FT_UInt   s = *seed;
584
585
586 #if 1
587
588     p = *cursor;
589
590     if ( p >= limit )
591       return 0;
592
593     if ( n > (FT_UInt)(limit - p) )
594       n = (FT_UInt)(limit - p);
595
596     for ( r = 0; r < n; r++ )
597     {
598       FT_UInt  val = p[r];
599       FT_UInt  b   = ( val ^ ( s >> 8 ) );
600
601
602       s         = ( (val + s)*52845U + 22719 ) & 0xFFFFU;
603       buffer[r] = (FT_Byte) b;
604     }
605
606     *cursor = p + n;
607     *seed   = (FT_UShort)s;
608
609 #else /* 0 */
610
611     for ( r = 0, p = *cursor; r < n && p < limit; r++, p++ )
612     {
613       FT_Byte  b = (FT_Byte)( *p ^ ( s >> 8 ) );
614
615
616       s = (FT_UShort)( ( *p + s ) * 52845U + 22719 );
617       *buffer++ = b;
618     }
619     *cursor = p;
620     *seed   = s;
621
622 #endif /* 0 */
623
624     return r;
625   }
626
627 FT_LOCAL_DEF( FT_Bool )
628           xyq_PS_Conv_ToInt( FT_Byte**  cursor,
629           FT_Byte*   limit, FT_Long* val )
630           
631   {
632           FT_Byte first_char = **cursor;
633           if (first_char == '+' || first_char == '-' || (first_char >= '0' && first_char <= '9')) {
634                   *val = PS_Conv_ToInt(cursor, limit);
635                   return 1;
636           }
637           return 0;
638   }
639
640 /* END */
641