Пример #1
0
  FT_Realloc( FT_Memory  memory,
              FT_Long    current,
              FT_Long    size,
              void*     *P )
  {
    FT_Error  error;


    (void)FT_REALLOC( *P, current, size );
    return error;
  }
Пример #2
0
  /* return false on memory error */
  static FT_Bool
  cf2_arrstack_setNumElements( CF2_ArrStack  arrstack,
                               size_t        numElements )
  {
    FT_ASSERT( arrstack != NULL );

    {
      FT_Error   error  = FT_Err_Ok;        /* for FT_REALLOC */
      FT_Memory  memory = arrstack->memory; /* for FT_REALLOC */

      FT_Long  newSize = numElements * arrstack->sizeItem;


      if ( numElements > LONG_MAX / arrstack->sizeItem )
        goto exit;


      FT_ASSERT( newSize > 0 );   /* avoid realloc with zero size */

      if ( !FT_REALLOC( arrstack->ptr, arrstack->totalSize, newSize ) )
      {
        arrstack->allocated = numElements;
        arrstack->totalSize = newSize;

        if ( arrstack->count > numElements )
        {
          /* we truncated the list! */
          CF2_SET_ERROR( arrstack->error, Stack_Overflow );
          arrstack->count = numElements;
          return FALSE;
        }

        return TRUE;     /* success */
      }
    }

  exit:
    /* if there's not already an error, store this one */
    CF2_SET_ERROR( arrstack->error, Out_Of_Memory );

    return FALSE;
  }
Пример #3
0
/* Builds a table that maps Unicode values to glyph indices */
static FT_Error
ps_unicodes_init( FT_Memory     memory,
                  FT_UInt       num_glyphs,
                  const char**  glyph_names,
                  PS_Unicodes*  table )
{
    FT_Error  error;


    /* we first allocate the table */
    table->num_maps = 0;
    table->maps     = 0;

    if ( !FT_NEW_ARRAY( table->maps, num_glyphs ) )
    {
        FT_UInt     n;
        FT_UInt     count;
        PS_UniMap*  map;
        FT_UInt32   uni_char;


        map = table->maps;

        for ( n = 0; n < num_glyphs; n++ )
        {
            const char*  gname = glyph_names[n];


            if ( gname )
            {
                uni_char = ps_unicode_value( gname );

                if ( uni_char != 0 && uni_char != 0xFFFFL )
                {
                    map->unicode     = (FT_UInt)uni_char;
                    map->glyph_index = n;
                    map++;
                }
            }
        }

        /* now, compress the table a bit */
        count = (FT_UInt)( map - table->maps );

        if ( count > 0 && FT_REALLOC( table->maps,
                                      num_glyphs * sizeof ( PS_UniMap ),
                                      count * sizeof ( PS_UniMap ) ) )
            count = 0;

        if ( count == 0 )
        {
            FT_FREE( table->maps );
            if ( !error )
                error = PSnames_Err_Invalid_Argument;  /* no unicode chars here! */
        }
        else
            /* sort the table in increasing order of unicode values */
            ft_qsort( table->maps, count, sizeof ( PS_UniMap ), compare_uni_maps );

        table->num_maps = count;
    }

    return error;
}
Пример #4
0
  static void
  t42_parse_sfnts( T42_Face    face,
                   T42_Loader  loader )
  {
    T42_Parser  parser = &loader->parser;
    FT_Memory   memory = parser->root.memory;
    FT_Byte*    cur;
    FT_Byte*    limit  = parser->root.limit;
    FT_Error    error;
    FT_Int      num_tables = 0;
    FT_ULong    count;

    FT_Long     n, string_size, old_string_size, real_size;
    FT_Byte*    string_buf = NULL;
    FT_Bool     allocated  = 0;

    T42_Load_Status  status;


    /* The format is                                */
    /*                                              */
    /*   /sfnts [ <hexstring> <hexstring> ... ] def */
    /*                                              */
    /* or                                           */
    /*                                              */
    /*   /sfnts [                                   */
    /*      <num_bin_bytes> RD <binary data>        */
    /*      <num_bin_bytes> RD <binary data>        */
    /*      ...                                     */
    /*   ] def                                      */
    /*                                              */
    /* with exactly one space after the `RD' token. */

    T1_Skip_Spaces( parser );

    if ( parser->root.cursor >= limit || *parser->root.cursor++ != '[' )
    {
      FT_ERROR(( "t42_parse_sfnts: can't find begin of sfnts vector\n" ));
      error = FT_THROW( Invalid_File_Format );
      goto Fail;
    }

    T1_Skip_Spaces( parser );
    status          = BEFORE_START;
    string_size     = 0;
    old_string_size = 0;
    count           = 0;

    while ( parser->root.cursor < limit )
    {
      cur = parser->root.cursor;

      if ( *cur == ']' )
      {
        parser->root.cursor++;
        goto Exit;
      }

      else if ( *cur == '<' )
      {
        T1_Skip_PS_Token( parser );
        if ( parser->root.error )
          goto Exit;

        /* don't include delimiters */
        string_size = (FT_Long)( ( parser->root.cursor - cur - 2 + 1 ) / 2 );
        if ( !string_size )
        {
          FT_ERROR(( "t42_parse_sfnts: invalid data in sfnts array\n" ));
          error = FT_THROW( Invalid_File_Format );
          goto Fail;
        }
        if ( FT_REALLOC( string_buf, old_string_size, string_size ) )
          goto Fail;

        allocated = 1;

        parser->root.cursor = cur;
        (void)T1_ToBytes( parser, string_buf, string_size, &real_size, 1 );
        old_string_size = string_size;
        string_size = real_size;
      }

      else if ( ft_isdigit( *cur ) )
      {
        if ( allocated )
        {
          FT_ERROR(( "t42_parse_sfnts: "
                     "can't handle mixed binary and hex strings\n" ));
          error = FT_THROW( Invalid_File_Format );
          goto Fail;
        }

        string_size = T1_ToInt( parser );
        if ( string_size < 0 )
        {
          FT_ERROR(( "t42_parse_sfnts: invalid string size\n" ));
          error = FT_THROW( Invalid_File_Format );
          goto Fail;
        }

        T1_Skip_PS_Token( parser );             /* `RD' */
        if ( parser->root.error )
          return;

        string_buf = parser->root.cursor + 1;   /* one space after `RD' */

        if ( limit - parser->root.cursor < string_size )
        {
          FT_ERROR(( "t42_parse_sfnts: too much binary data\n" ));
          error = FT_THROW( Invalid_File_Format );
          goto Fail;
        }
        else
          parser->root.cursor += string_size + 1;
      }

      if ( !string_buf )
      {
        FT_ERROR(( "t42_parse_sfnts: invalid data in sfnts array\n" ));
        error = FT_THROW( Invalid_File_Format );
        goto Fail;
      }

      /* A string can have a trailing zero (odd) byte for padding. */
      /* Ignore it.                                                */
      if ( ( string_size & 1 ) && string_buf[string_size - 1] == 0 )
        string_size--;

      if ( !string_size )
      {
        FT_ERROR(( "t42_parse_sfnts: invalid string\n" ));
        error = FT_THROW( Invalid_File_Format );
        goto Fail;
      }

      for ( n = 0; n < string_size; n++ )
      {
        switch ( status )
        {
        case BEFORE_START:
          /* load offset table, 12 bytes */
          if ( count < 12 )
          {
            face->ttf_data[count++] = string_buf[n];
            continue;
          }
          else
          {
            num_tables     = 16 * face->ttf_data[4] + face->ttf_data[5];
            status         = BEFORE_TABLE_DIR;
            face->ttf_size = 12 + 16 * num_tables;

            if ( (FT_ULong)( limit - parser->root.cursor ) < face->ttf_size )
            {
              FT_ERROR(( "t42_parse_sfnts: invalid data in sfnts array\n" ));
              error = FT_THROW( Invalid_File_Format );
              goto Fail;
            }

            if ( FT_REALLOC( face->ttf_data, 12, face->ttf_size ) )
              goto Fail;
          }
          /* fall through */

        case BEFORE_TABLE_DIR:
          /* the offset table is read; read the table directory */
          if ( count < face->ttf_size )
          {
            face->ttf_data[count++] = string_buf[n];
            continue;
          }
          else
          {
            int       i;
            FT_ULong  len;


            for ( i = 0; i < num_tables; i++ )
            {
              FT_Byte*  p = face->ttf_data + 12 + 16 * i + 12;


              len = FT_PEEK_ULONG( p );

              /* Pad to a 4-byte boundary length */
              face->ttf_size += ( len + 3 ) & ~3;
            }

            status = OTHER_TABLES;

            /* there are no more than 256 tables, so no size check here */
            if ( FT_REALLOC( face->ttf_data, 12 + 16 * num_tables,
                             face->ttf_size + 1 ) )
              goto Fail;
          }
          /* fall through */

        case OTHER_TABLES:
          /* all other tables are just copied */
          if ( count >= face->ttf_size )
          {
            FT_ERROR(( "t42_parse_sfnts: too much binary data\n" ));
            error = FT_THROW( Invalid_File_Format );
            goto Fail;
          }
          face->ttf_data[count++] = string_buf[n];
        }
      }

      T1_Skip_Spaces( parser );
    }

    /* if control reaches this point, the format was not valid */
    error = FT_THROW( Invalid_File_Format );

  Fail:
    parser->root.error = error;

  Exit:
    if ( allocated )
      FT_FREE( string_buf );
  }