Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / sdk / lib / 3rdparty / freetype / src / gxvalid / gxvtrak.c
diff --git a/sdk/lib/3rdparty/freetype/src/gxvalid/gxvtrak.c b/sdk/lib/3rdparty/freetype/src/gxvalid/gxvtrak.c
new file mode 100644 (file)
index 0000000..dd49825
--- /dev/null
@@ -0,0 +1,288 @@
+/***************************************************************************/
+/*                                                                         */
+/*  gxvtrak.c                                                              */
+/*                                                                         */
+/*    TrueTypeGX/AAT trak table validation (body).                         */
+/*                                                                         */
+/*  Copyright 2004-2017 by                                                 */
+/*  suzuki toshiya, Masatake YAMATO, Red Hat K.K.,                         */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+/***************************************************************************/
+/*                                                                         */
+/* gxvalid is derived from both gxlayout module and otvalid module.        */
+/* Development of gxlayout is supported by the Information-technology      */
+/* Promotion Agency(IPA), Japan.                                           */
+/*                                                                         */
+/***************************************************************************/
+
+
+#include "gxvalid.h"
+#include "gxvcommn.h"
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
+  /* messages during execution.                                            */
+  /*                                                                       */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_gxvtrak
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                      Data and Types                           *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+    /*
+     * referred track table format specification:
+     * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6trak.html
+     * last update was 1996.
+     * ----------------------------------------------
+     * [MINIMUM HEADER]: GXV_TRAK_SIZE_MIN
+     * version          (fixed:  32bit) = 0x00010000
+     * format           (uint16: 16bit) = 0 is only defined (1996)
+     * horizOffset      (uint16: 16bit)
+     * vertOffset       (uint16: 16bit)
+     * reserved         (uint16: 16bit) = 0
+     * ----------------------------------------------
+     * [VARIABLE BODY]:
+     * horizData
+     *   header         ( 2 + 2 + 4
+     *   trackTable       + nTracks * ( 4 + 2 + 2 )
+     *   sizeTable        + nSizes * 4 )
+     * ----------------------------------------------
+     * vertData
+     *   header         ( 2 + 2 + 4
+     *   trackTable       + nTracks * ( 4 + 2 + 2 )
+     *   sizeTable        + nSizes * 4 )
+     * ----------------------------------------------
+     */
+  typedef struct  GXV_trak_DataRec_
+  {
+    FT_UShort  trackValueOffset_min;
+    FT_UShort  trackValueOffset_max;
+
+  } GXV_trak_DataRec, *GXV_trak_Data;
+
+
+#define GXV_TRAK_DATA( FIELD )  GXV_TABLE_DATA( trak, FIELD )
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                      UTILITY FUNCTIONS                        *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  static void
+  gxv_trak_trackTable_validate( FT_Bytes       table,
+                                FT_Bytes       limit,
+                                FT_UShort      nTracks,
+                                GXV_Validator  gxvalid )
+  {
+    FT_Bytes  p = table;
+
+    FT_Fixed   track, t;
+    FT_UShort  nameIndex;
+    FT_UShort  offset;
+    FT_UShort  i, j;
+
+
+    GXV_NAME_ENTER( "trackTable" );
+
+    GXV_TRAK_DATA( trackValueOffset_min ) = 0xFFFFU;
+    GXV_TRAK_DATA( trackValueOffset_max ) = 0x0000;
+
+    GXV_LIMIT_CHECK( nTracks * ( 4 + 2 + 2 ) );
+
+    for ( i = 0; i < nTracks; i++ )
+    {
+      p = table + i * ( 4 + 2 + 2 );
+      track     = FT_NEXT_LONG( p );
+      nameIndex = FT_NEXT_USHORT( p );
+      offset    = FT_NEXT_USHORT( p );
+
+      if ( offset < GXV_TRAK_DATA( trackValueOffset_min ) )
+        GXV_TRAK_DATA( trackValueOffset_min ) = offset;
+      if ( offset > GXV_TRAK_DATA( trackValueOffset_max ) )
+        GXV_TRAK_DATA( trackValueOffset_max ) = offset;
+
+      gxv_sfntName_validate( nameIndex, 256, 32767, gxvalid );
+
+      for ( j = i; j < nTracks; j++ )
+      {
+         p = table + j * ( 4 + 2 + 2 );
+         t = FT_NEXT_LONG( p );
+         if ( t == track )
+           GXV_TRACE(( "duplicated entries found for track value 0x%x\n",
+                        track ));
+      }
+    }
+
+    gxvalid->subtable_length = (FT_ULong)( p - table );
+    GXV_EXIT;
+  }
+
+
+  static void
+  gxv_trak_trackData_validate( FT_Bytes       table,
+                               FT_Bytes       limit,
+                               GXV_Validator  gxvalid )
+  {
+    FT_Bytes   p = table;
+    FT_UShort  nTracks;
+    FT_UShort  nSizes;
+    FT_ULong   sizeTableOffset;
+
+    GXV_ODTECT( 4, odtect );
+
+
+    GXV_ODTECT_INIT( odtect );
+    GXV_NAME_ENTER( "trackData" );
+
+    /* read the header of trackData */
+    GXV_LIMIT_CHECK( 2 + 2 + 4 );
+    nTracks         = FT_NEXT_USHORT( p );
+    nSizes          = FT_NEXT_USHORT( p );
+    sizeTableOffset = FT_NEXT_ULONG( p );
+
+    gxv_odtect_add_range( table, (FT_ULong)( p - table ),
+                          "trackData header", odtect );
+
+    /* validate trackTable */
+    gxv_trak_trackTable_validate( p, limit, nTracks, gxvalid );
+    gxv_odtect_add_range( p, gxvalid->subtable_length,
+                          "trackTable", odtect );
+
+    /* sizeTable is array of FT_Fixed, don't check contents */
+    p = gxvalid->root->base + sizeTableOffset;
+    GXV_LIMIT_CHECK( nSizes * 4 );
+    gxv_odtect_add_range( p, nSizes * 4, "sizeTable", odtect );
+
+    /* validate trackValueOffet */
+    p = gxvalid->root->base + GXV_TRAK_DATA( trackValueOffset_min );
+    if ( limit - p < nTracks * nSizes * 2 )
+      GXV_TRACE(( "too short trackValue array\n" ));
+
+    p = gxvalid->root->base + GXV_TRAK_DATA( trackValueOffset_max );
+    GXV_LIMIT_CHECK( nSizes * 2 );
+
+    gxv_odtect_add_range( gxvalid->root->base
+                            + GXV_TRAK_DATA( trackValueOffset_min ),
+                          GXV_TRAK_DATA( trackValueOffset_max )
+                            - GXV_TRAK_DATA( trackValueOffset_min )
+                            + nSizes * 2,
+                          "trackValue array", odtect );
+
+    gxv_odtect_validate( odtect, gxvalid );
+
+    GXV_EXIT;
+  }
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                          trak TABLE                           *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  FT_LOCAL_DEF( void )
+  gxv_trak_validate( FT_Bytes      table,
+                     FT_Face       face,
+                     FT_Validator  ftvalid )
+  {
+    FT_Bytes          p = table;
+    FT_Bytes          limit = 0;
+
+    GXV_ValidatorRec  gxvalidrec;
+    GXV_Validator     gxvalid = &gxvalidrec;
+    GXV_trak_DataRec  trakrec;
+    GXV_trak_Data     trak = &trakrec;
+
+    FT_ULong   version;
+    FT_UShort  format;
+    FT_UShort  horizOffset;
+    FT_UShort  vertOffset;
+    FT_UShort  reserved;
+
+
+    GXV_ODTECT( 3, odtect );
+
+    GXV_ODTECT_INIT( odtect );
+    gxvalid->root       = ftvalid;
+    gxvalid->table_data = trak;
+    gxvalid->face       = face;
+
+    limit      = gxvalid->root->limit;
+
+    FT_TRACE3(( "validating `trak' table\n" ));
+    GXV_INIT;
+
+    GXV_LIMIT_CHECK( 4 + 2 + 2 + 2 + 2 );
+    version     = FT_NEXT_ULONG( p );
+    format      = FT_NEXT_USHORT( p );
+    horizOffset = FT_NEXT_USHORT( p );
+    vertOffset  = FT_NEXT_USHORT( p );
+    reserved    = FT_NEXT_USHORT( p );
+
+    GXV_TRACE(( " (version = 0x%08x)\n", version ));
+    GXV_TRACE(( " (format = 0x%04x)\n", format ));
+    GXV_TRACE(( " (horizOffset = 0x%04x)\n", horizOffset ));
+    GXV_TRACE(( " (vertOffset = 0x%04x)\n", vertOffset ));
+    GXV_TRACE(( " (reserved = 0x%04x)\n", reserved ));
+
+    /* Version 1.0 (always:1996) */
+    if ( version != 0x00010000UL )
+      FT_INVALID_FORMAT;
+
+    /* format 0 (always:1996) */
+    if ( format != 0x0000 )
+      FT_INVALID_FORMAT;
+
+    GXV_32BIT_ALIGNMENT_VALIDATE( horizOffset );
+    GXV_32BIT_ALIGNMENT_VALIDATE( vertOffset );
+
+    /* Reserved Fixed Value (always) */
+    if ( reserved != 0x0000 )
+      FT_INVALID_DATA;
+
+    /* validate trackData */
+    if ( 0 < horizOffset )
+    {
+      gxv_trak_trackData_validate( table + horizOffset, limit, gxvalid );
+      gxv_odtect_add_range( table + horizOffset, gxvalid->subtable_length,
+                            "horizJustData", odtect );
+    }
+
+    if ( 0 < vertOffset )
+    {
+      gxv_trak_trackData_validate( table + vertOffset, limit, gxvalid );
+      gxv_odtect_add_range( table + vertOffset, gxvalid->subtable_length,
+                            "vertJustData", odtect );
+    }
+
+    gxv_odtect_validate( odtect, gxvalid );
+
+    FT_TRACE4(( "\n" ));
+  }
+
+
+/* END */