1 /**************************************************************************** 2 * 3 * otvbase.c 4 * 5 * OpenType BASE table validation (body). 6 * 7 * Copyright (C) 2004-2020 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 "otvalid.h" 20 #include "otvcommn.h" 21 22 23 /************************************************************************** 24 * 25 * The macro FT_COMPONENT is used in trace mode. It is an implicit 26 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log 27 * messages during execution. 28 */ 29 #undef FT_COMPONENT 30 #define FT_COMPONENT otvbase 31 32 33 static void otv_BaseCoord_validate(FT_Bytes table,OTV_Validator otvalid)34 otv_BaseCoord_validate( FT_Bytes table, 35 OTV_Validator otvalid ) 36 { 37 FT_Bytes p = table; 38 FT_UInt BaseCoordFormat; 39 40 41 OTV_NAME_ENTER( "BaseCoord" ); 42 43 OTV_LIMIT_CHECK( 4 ); 44 BaseCoordFormat = FT_NEXT_USHORT( p ); 45 p += 2; /* skip Coordinate */ 46 47 OTV_TRACE(( " (format %d)\n", BaseCoordFormat )); 48 49 switch ( BaseCoordFormat ) 50 { 51 case 1: /* BaseCoordFormat1 */ 52 break; 53 54 case 2: /* BaseCoordFormat2 */ 55 OTV_LIMIT_CHECK( 4 ); /* ReferenceGlyph, BaseCoordPoint */ 56 break; 57 58 case 3: /* BaseCoordFormat3 */ 59 OTV_LIMIT_CHECK( 2 ); 60 /* DeviceTable */ 61 otv_Device_validate( table + FT_NEXT_USHORT( p ), otvalid ); 62 break; 63 64 default: 65 FT_INVALID_FORMAT; 66 } 67 68 OTV_EXIT; 69 } 70 71 72 static void otv_BaseTagList_validate(FT_Bytes table,OTV_Validator otvalid)73 otv_BaseTagList_validate( FT_Bytes table, 74 OTV_Validator otvalid ) 75 { 76 FT_Bytes p = table; 77 FT_UInt BaseTagCount; 78 79 80 OTV_NAME_ENTER( "BaseTagList" ); 81 82 OTV_LIMIT_CHECK( 2 ); 83 84 BaseTagCount = FT_NEXT_USHORT( p ); 85 86 OTV_TRACE(( " (BaseTagCount = %d)\n", BaseTagCount )); 87 88 OTV_LIMIT_CHECK( BaseTagCount * 4 ); /* BaselineTag */ 89 90 OTV_EXIT; 91 } 92 93 94 static void otv_BaseValues_validate(FT_Bytes table,OTV_Validator otvalid)95 otv_BaseValues_validate( FT_Bytes table, 96 OTV_Validator otvalid ) 97 { 98 FT_Bytes p = table; 99 FT_UInt BaseCoordCount; 100 101 102 OTV_NAME_ENTER( "BaseValues" ); 103 104 OTV_LIMIT_CHECK( 4 ); 105 106 p += 2; /* skip DefaultIndex */ 107 BaseCoordCount = FT_NEXT_USHORT( p ); 108 109 OTV_TRACE(( " (BaseCoordCount = %d)\n", BaseCoordCount )); 110 111 OTV_LIMIT_CHECK( BaseCoordCount * 2 ); 112 113 /* BaseCoord */ 114 for ( ; BaseCoordCount > 0; BaseCoordCount-- ) 115 otv_BaseCoord_validate( table + FT_NEXT_USHORT( p ), otvalid ); 116 117 OTV_EXIT; 118 } 119 120 121 static void otv_MinMax_validate(FT_Bytes table,OTV_Validator otvalid)122 otv_MinMax_validate( FT_Bytes table, 123 OTV_Validator otvalid ) 124 { 125 FT_Bytes p = table; 126 FT_UInt table_size; 127 FT_UInt FeatMinMaxCount; 128 129 OTV_OPTIONAL_TABLE( MinCoord ); 130 OTV_OPTIONAL_TABLE( MaxCoord ); 131 132 133 OTV_NAME_ENTER( "MinMax" ); 134 135 OTV_LIMIT_CHECK( 6 ); 136 137 OTV_OPTIONAL_OFFSET( MinCoord ); 138 OTV_OPTIONAL_OFFSET( MaxCoord ); 139 FeatMinMaxCount = FT_NEXT_USHORT( p ); 140 141 OTV_TRACE(( " (FeatMinMaxCount = %d)\n", FeatMinMaxCount )); 142 143 table_size = FeatMinMaxCount * 8 + 6; 144 145 OTV_SIZE_CHECK( MinCoord ); 146 if ( MinCoord ) 147 otv_BaseCoord_validate( table + MinCoord, otvalid ); 148 149 OTV_SIZE_CHECK( MaxCoord ); 150 if ( MaxCoord ) 151 otv_BaseCoord_validate( table + MaxCoord, otvalid ); 152 153 OTV_LIMIT_CHECK( FeatMinMaxCount * 8 ); 154 155 /* FeatMinMaxRecord */ 156 for ( ; FeatMinMaxCount > 0; FeatMinMaxCount-- ) 157 { 158 p += 4; /* skip FeatureTableTag */ 159 160 OTV_OPTIONAL_OFFSET( MinCoord ); 161 OTV_OPTIONAL_OFFSET( MaxCoord ); 162 163 OTV_SIZE_CHECK( MinCoord ); 164 if ( MinCoord ) 165 otv_BaseCoord_validate( table + MinCoord, otvalid ); 166 167 OTV_SIZE_CHECK( MaxCoord ); 168 if ( MaxCoord ) 169 otv_BaseCoord_validate( table + MaxCoord, otvalid ); 170 } 171 172 OTV_EXIT; 173 } 174 175 176 static void otv_BaseScript_validate(FT_Bytes table,OTV_Validator otvalid)177 otv_BaseScript_validate( FT_Bytes table, 178 OTV_Validator otvalid ) 179 { 180 FT_Bytes p = table; 181 FT_UInt table_size; 182 FT_UInt BaseLangSysCount; 183 184 OTV_OPTIONAL_TABLE( BaseValues ); 185 OTV_OPTIONAL_TABLE( DefaultMinMax ); 186 187 188 OTV_NAME_ENTER( "BaseScript" ); 189 190 OTV_LIMIT_CHECK( 6 ); 191 OTV_OPTIONAL_OFFSET( BaseValues ); 192 OTV_OPTIONAL_OFFSET( DefaultMinMax ); 193 BaseLangSysCount = FT_NEXT_USHORT( p ); 194 195 OTV_TRACE(( " (BaseLangSysCount = %d)\n", BaseLangSysCount )); 196 197 table_size = BaseLangSysCount * 6 + 6; 198 199 OTV_SIZE_CHECK( BaseValues ); 200 if ( BaseValues ) 201 otv_BaseValues_validate( table + BaseValues, otvalid ); 202 203 OTV_SIZE_CHECK( DefaultMinMax ); 204 if ( DefaultMinMax ) 205 otv_MinMax_validate( table + DefaultMinMax, otvalid ); 206 207 OTV_LIMIT_CHECK( BaseLangSysCount * 6 ); 208 209 /* BaseLangSysRecord */ 210 for ( ; BaseLangSysCount > 0; BaseLangSysCount-- ) 211 { 212 p += 4; /* skip BaseLangSysTag */ 213 214 otv_MinMax_validate( table + FT_NEXT_USHORT( p ), otvalid ); 215 } 216 217 OTV_EXIT; 218 } 219 220 221 static void otv_BaseScriptList_validate(FT_Bytes table,OTV_Validator otvalid)222 otv_BaseScriptList_validate( FT_Bytes table, 223 OTV_Validator otvalid ) 224 { 225 FT_Bytes p = table; 226 FT_UInt BaseScriptCount; 227 228 229 OTV_NAME_ENTER( "BaseScriptList" ); 230 231 OTV_LIMIT_CHECK( 2 ); 232 BaseScriptCount = FT_NEXT_USHORT( p ); 233 234 OTV_TRACE(( " (BaseScriptCount = %d)\n", BaseScriptCount )); 235 236 OTV_LIMIT_CHECK( BaseScriptCount * 6 ); 237 238 /* BaseScriptRecord */ 239 for ( ; BaseScriptCount > 0; BaseScriptCount-- ) 240 { 241 p += 4; /* skip BaseScriptTag */ 242 243 /* BaseScript */ 244 otv_BaseScript_validate( table + FT_NEXT_USHORT( p ), otvalid ); 245 } 246 247 OTV_EXIT; 248 } 249 250 251 static void otv_Axis_validate(FT_Bytes table,OTV_Validator otvalid)252 otv_Axis_validate( FT_Bytes table, 253 OTV_Validator otvalid ) 254 { 255 FT_Bytes p = table; 256 FT_UInt table_size; 257 258 OTV_OPTIONAL_TABLE( BaseTagList ); 259 260 261 OTV_NAME_ENTER( "Axis" ); 262 263 OTV_LIMIT_CHECK( 4 ); 264 OTV_OPTIONAL_OFFSET( BaseTagList ); 265 266 table_size = 4; 267 268 OTV_SIZE_CHECK( BaseTagList ); 269 if ( BaseTagList ) 270 otv_BaseTagList_validate( table + BaseTagList, otvalid ); 271 272 /* BaseScriptList */ 273 otv_BaseScriptList_validate( table + FT_NEXT_USHORT( p ), otvalid ); 274 275 OTV_EXIT; 276 } 277 278 279 FT_LOCAL_DEF( void ) otv_BASE_validate(FT_Bytes table,FT_Validator ftvalid)280 otv_BASE_validate( FT_Bytes table, 281 FT_Validator ftvalid ) 282 { 283 OTV_ValidatorRec otvalidrec; 284 OTV_Validator otvalid = &otvalidrec; 285 FT_Bytes p = table; 286 FT_UInt table_size; 287 FT_UShort version; 288 289 OTV_OPTIONAL_TABLE( HorizAxis ); 290 OTV_OPTIONAL_TABLE( VertAxis ); 291 292 OTV_OPTIONAL_TABLE32( itemVarStore ); 293 294 295 otvalid->root = ftvalid; 296 297 FT_TRACE3(( "validating BASE table\n" )); 298 OTV_INIT; 299 300 OTV_LIMIT_CHECK( 4 ); 301 302 if ( FT_NEXT_USHORT( p ) != 1 ) /* majorVersion */ 303 FT_INVALID_FORMAT; 304 305 version = FT_NEXT_USHORT( p ); /* minorVersion */ 306 307 table_size = 8; 308 switch ( version ) 309 { 310 case 0: 311 OTV_LIMIT_CHECK( 4 ); 312 break; 313 314 case 1: 315 OTV_LIMIT_CHECK( 8 ); 316 table_size += 4; 317 break; 318 319 default: 320 FT_INVALID_FORMAT; 321 } 322 323 OTV_OPTIONAL_OFFSET( HorizAxis ); 324 OTV_SIZE_CHECK( HorizAxis ); 325 if ( HorizAxis ) 326 otv_Axis_validate( table + HorizAxis, otvalid ); 327 328 OTV_OPTIONAL_OFFSET( VertAxis ); 329 OTV_SIZE_CHECK( VertAxis ); 330 if ( VertAxis ) 331 otv_Axis_validate( table + VertAxis, otvalid ); 332 333 if ( version > 0 ) 334 { 335 OTV_OPTIONAL_OFFSET32( itemVarStore ); 336 OTV_SIZE_CHECK32( itemVarStore ); 337 if ( itemVarStore ) 338 OTV_TRACE(( " [omitting itemVarStore validation]\n" )); /* XXX */ 339 } 340 341 FT_TRACE4(( "\n" )); 342 } 343 344 345 /* END */ 346