tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

psconv.c (11649B)


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