1 /***************************************************************************/
5 /* Some convenience conversions (body). */
7 /* Copyright 2006, 2008, 2009, 2012-2013 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
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. */
16 /***************************************************************************/
19 #include "../../include/ft2build.h"
20 #include "../../include/freetype/internal/psaux.h"
21 #include "../../include/freetype/internal/ftdebug.h"
27 /*************************************************************************/
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. */
34 #define FT_COMPONENT trace_psconv
37 /* The following array is used by various functions to quickly convert */
38 /* digits (both decimal and non-decimal) into numbers. */
43 static const FT_Char ft_char_table[128] =
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,
56 /* no character >= 0x80 can represent a valid number */
59 #endif /* 'A' == 65 */
64 static const FT_Char ft_char_table[128] =
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,
77 /* no character < 0x80 can represent a valid number */
80 #endif /* 'A' == 193 */
83 FT_LOCAL_DEF( FT_Long )
84 PS_Conv_Strtol( FT_Byte** cursor,
92 FT_Bool have_overflow = 0;
101 if ( base < 2 || base > 36 )
103 FT_TRACE4(( "!!!INVALID BASE:!!!" ));
107 if ( *p == '-' || *p == '+' )
109 sign = FT_BOOL( *p == '-' );
116 num_limit = 0x7FFFFFFFL / base;
117 c_limit = (FT_Char)( 0x7FFFFFFFL % base );
119 for ( ; p < limit; p++ )
124 if ( IS_PS_SPACE( *p ) || *p OP 0x80 )
127 c = ft_char_table[*p & 0x7f];
129 if ( c < 0 || c >= base )
132 if ( num > num_limit || ( num == num_limit && c > c_limit ) )
135 num = num * base + c;
143 FT_TRACE4(( "!!!OVERFLOW:!!!" ));
152 FT_TRACE4(( "!!!END OF DATA:!!!" ));
157 FT_LOCAL_DEF( FT_Long )
158 PS_Conv_ToInt( FT_Byte** cursor,
162 FT_Byte* p = *cursor;
169 num = PS_Conv_Strtol( &p, limit, 10 );
174 if ( p < limit && *p == '#' )
179 num = PS_Conv_Strtol( &p, limit, num );
191 FT_LOCAL_DEF( FT_Fixed )
192 PS_Conv_ToFixed( FT_Byte** cursor,
196 FT_Byte* p = *cursor;
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;
205 FT_Long integral = 0;
207 FT_Int temp0 = 65536;
208 FT_Int temp1 = power_ten;
213 FT_Bool have_overflow = 0;
214 FT_Bool have_underflow = 0;
219 if ( *p == '-' || *p == '+' )
221 sign = FT_BOOL( *p == '-' );
228 /* read the integer part */
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;
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 ++; }
243 integral = PS_Conv_ToInt( &p, limit );
246 if ( integral > 0x7FFF )
249 integral = integral << 16;
253 /* read the decimal part */
254 if ( p < limit && *p == '.' )
258 for ( ; p < limit; p++ )
263 if ( IS_PS_SPACE( *p ) || *p OP 0x80 )
266 c = ft_char_table[*p & 0x7f];
268 if ( c < 0 || c >= 10 )
271 if ( decimal < 0xCCCCCCCL )
273 decimal = decimal * 10 + c;
275 if ( !integral && power_ten > 0 )
283 /* read exponent, if any */
284 if ( p + 1 < limit && ( *p == 'e' || *p == 'E' ) )
292 exponent = PS_Conv_ToInt( &p, limit );
297 /* arbitrarily limit exponent */
298 if ( exponent > 1000 )
300 else if ( exponent < -1000 )
303 power_ten += exponent;
308 if ( !integral && !decimal )
313 if ( have_underflow )
316 while ( power_ten > 0 )
318 if ( integral >= 0xCCCCCCCL )
322 if ( decimal >= 0xCCCCCCCL )
334 while ( power_ten < 0 )
337 if ( divider < 0xCCCCCCCL )
342 if ( !integral && !decimal )
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)
354 integral += FT_DivFix( (FT_Long)decimal, divider );
356 if ( integral > 2147483647) integral = 2147483647;
359 integral += FT_DivFix( decimal, divider );
366 integral = -integral;
368 return (FT_Long)integral;
371 FT_TRACE4(( "!!!END OF DATA:!!!" ));
375 integral = 0x7FFFFFFFL;
376 FT_TRACE4(( "!!!OVERFLOW:!!!" ));
380 FT_TRACE4(( "!!!UNDERFLOW:!!!" ));
386 FT_LOCAL_DEF( FT_UInt )
387 PS_Conv_StringDecode( FT_Byte** cursor,
396 for ( p = *cursor; r < n && p < limit; p++ )
440 if ( IS_PS_DIGIT( *p ) )
446 if ( IS_PS_DIGIT( *p ) )
448 b = b * 8 + *p - '0';
452 if ( IS_PS_DIGIT( *p ) )
453 b = b * 8 + *p - '0';
481 FT_LOCAL_DEF( FT_UInt )
482 PS_Conv_ASCIIHexDecode( FT_Byte** cursor,
502 if ( n > (FT_UInt)( limit - p ) )
503 n = (FT_UInt)( limit - p );
505 /* we try to process two nibbles at a time to be as fast as possible */
511 if ( IS_PS_SPACE( c ) )
517 c = ft_char_table[c & 0x7F];
518 if ( (unsigned)c >= 16 )
521 pad = ( pad << 4 ) | c;
524 buffer[w++] = (FT_Byte)pad;
530 buffer[w++] = (FT_Byte)( pad << 4 );
538 for ( r = 0; r < n; r++ )
543 if ( IS_PS_SPACE( *p ) )
549 c = ft_char_table[*p & 0x7f];
551 if ( (unsigned)c >= 16 )
556 *buffer = (FT_Byte)(*buffer + c);
560 *buffer = (FT_Byte)(c << 4);
567 return ( r + 1 ) / 2;
574 FT_LOCAL_DEF( FT_UInt )
575 PS_Conv_EexecDecode( FT_Byte** cursor,
593 if ( n > (FT_UInt)(limit - p) )
594 n = (FT_UInt)(limit - p);
596 for ( r = 0; r < n; r++ )
599 FT_UInt b = ( val ^ ( s >> 8 ) );
602 s = ( (val + s)*52845U + 22719 ) & 0xFFFFU;
603 buffer[r] = (FT_Byte) b;
607 *seed = (FT_UShort)s;
611 for ( r = 0, p = *cursor; r < n && p < limit; r++, p++ )
613 FT_Byte b = (FT_Byte)( *p ^ ( s >> 8 ) );
616 s = (FT_UShort)( ( *p + s ) * 52845U + 22719 );
627 FT_LOCAL_DEF( FT_Bool )
628 xyq_PS_Conv_ToInt( FT_Byte** cursor,
629 FT_Byte* limit, FT_Long* val )
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);