w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

gxvcommn.c
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * gxvcommn.c
4  *
5  * TrueTypeGX/AAT common tables validation (body).
6  *
7  * Copyright (C) 2004-2020 by
8  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
9  * David Turner, Robert Wilhelm, and Werner Lemberg.
10  *
11  * This file is part of the FreeType project, and may only be used,
12  * modified, and distributed under the terms of the FreeType project
13  * license, LICENSE.TXT. By continuing to use, modify, or distribute
14  * this file you indicate that you have read the license and
15  * understand and accept it fully.
16  *
17  */
18 
19 /****************************************************************************
20  *
21  * gxvalid is derived from both gxlayout module and otvalid module.
22  * Development of gxlayout is supported by the Information-technology
23  * Promotion Agency(IPA), Japan.
24  *
25  */
26 
27 
28 #include "gxvcommn.h"
29 
30 
31  /**************************************************************************
32  *
33  * The macro FT_COMPONENT is used in trace mode. It is an implicit
34  * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
35  * messages during execution.
36  */
37 #undef FT_COMPONENT
38 #define FT_COMPONENT gxvcommon
39 
40 
41  /*************************************************************************/
42  /*************************************************************************/
43  /***** *****/
44  /***** 16bit offset sorter *****/
45  /***** *****/
46  /*************************************************************************/
47  /*************************************************************************/
48 
49  static int
51  FT_UShort* b )
52  {
53  if ( *a < *b )
54  return -1;
55  else if ( *a > *b )
56  return 1;
57  else
58  return 0;
59  }
60 
61 
62  FT_LOCAL_DEF( void )
64  FT_UShort** length,
65  FT_UShort* buff,
66  FT_UInt nmemb,
68  GXV_Validator gxvalid )
69  {
70  FT_UInt i;
71 
72 
73  for ( i = 0; i < nmemb; i++ )
74  *(length[i]) = 0;
75 
76  for ( i = 0; i < nmemb; i++ )
77  buff[i] = offset[i];
78  buff[nmemb] = limit;
79 
80  ft_qsort( buff, ( nmemb + 1 ), sizeof ( FT_UShort ),
81  ( int(*)(const void*, const void*) )gxv_compare_ushort_offset );
82 
83  if ( buff[nmemb] > limit )
85 
86  for ( i = 0; i < nmemb; i++ )
87  {
88  FT_UInt j;
89 
90 
91  for ( j = 0; j < nmemb; j++ )
92  if ( buff[j] == offset[i] )
93  break;
94 
95  if ( j == nmemb )
97 
98  *(length[i]) = (FT_UShort)( buff[j + 1] - buff[j] );
99 
100  if ( 0 != offset[i] && 0 == *(length[i]) )
102  }
103  }
104 
105 
106  /*************************************************************************/
107  /*************************************************************************/
108  /***** *****/
109  /***** 32bit offset sorter *****/
110  /***** *****/
111  /*************************************************************************/
112  /*************************************************************************/
113 
114  static int
116  FT_ULong* b )
117  {
118  if ( *a < *b )
119  return -1;
120  else if ( *a > *b )
121  return 1;
122  else
123  return 0;
124  }
125 
126 
127  FT_LOCAL_DEF( void )
129  FT_ULong** length,
130  FT_ULong* buff,
131  FT_UInt nmemb,
132  FT_ULong limit,
133  GXV_Validator gxvalid)
134  {
135  FT_UInt i;
136 
137 
138  for ( i = 0; i < nmemb; i++ )
139  *(length[i]) = 0;
140 
141  for ( i = 0; i < nmemb; i++ )
142  buff[i] = offset[i];
143  buff[nmemb] = limit;
144 
145  ft_qsort( buff, ( nmemb + 1 ), sizeof ( FT_ULong ),
146  ( int(*)(const void*, const void*) )gxv_compare_ulong_offset );
147 
148  if ( buff[nmemb] > limit )
150 
151  for ( i = 0; i < nmemb; i++ )
152  {
153  FT_UInt j;
154 
155 
156  for ( j = 0; j < nmemb; j++ )
157  if ( buff[j] == offset[i] )
158  break;
159 
160  if ( j == nmemb )
162 
163  *(length[i]) = buff[j + 1] - buff[j];
164 
165  if ( 0 != offset[i] && 0 == *(length[i]) )
167  }
168  }
169 
170 
171  /*************************************************************************/
172  /*************************************************************************/
173  /***** *****/
174  /***** scan value array and get min & max *****/
175  /***** *****/
176  /*************************************************************************/
177  /*************************************************************************/
178 
179 
180  FT_LOCAL_DEF( void )
182  FT_Bytes limit,
183  FT_Byte* min,
184  FT_Byte* max,
185  GXV_Validator gxvalid )
186  {
187  FT_Bytes p = table;
188 
189 
190  *min = 0xFF;
191  *max = 0x00;
192 
193  while ( p < limit )
194  {
195  FT_Byte val;
196 
197 
198  GXV_LIMIT_CHECK( 1 );
199  val = FT_NEXT_BYTE( p );
200 
201  *min = (FT_Byte)FT_MIN( *min, val );
202  *max = (FT_Byte)FT_MAX( *max, val );
203  }
204 
205  gxvalid->subtable_length = (FT_ULong)( p - table );
206  }
207 
208 
209  FT_LOCAL_DEF( void )
211  FT_Bytes limit,
212  FT_UShort* min,
213  FT_UShort* max,
214  GXV_Validator gxvalid )
215  {
216  FT_Bytes p = table;
217 
218 
219  *min = 0xFFFFU;
220  *max = 0x0000;
221 
222  while ( p < limit )
223  {
224  FT_UShort val;
225 
226 
227  GXV_LIMIT_CHECK( 2 );
228  val = FT_NEXT_USHORT( p );
229 
230  *min = (FT_Byte)FT_MIN( *min, val );
231  *max = (FT_Byte)FT_MAX( *max, val );
232  }
233 
234  gxvalid->subtable_length = (FT_ULong)( p - table );
235  }
236 
237 
238  /*************************************************************************/
239  /*************************************************************************/
240  /***** *****/
241  /***** BINSEARCHHEADER *****/
242  /***** *****/
243  /*************************************************************************/
244  /*************************************************************************/
245 
246  typedef struct GXV_BinSrchHeader_
247  {
253 
255 
256 
257  static void
259  GXV_Validator gxvalid )
260  {
261  FT_UShort searchRange;
262  FT_UShort entrySelector;
263  FT_UShort rangeShift;
264 
265 
266  if ( binSrchHeader->unitSize == 0 )
268 
269  if ( binSrchHeader->nUnits == 0 )
270  {
271  if ( binSrchHeader->searchRange == 0 &&
272  binSrchHeader->entrySelector == 0 &&
273  binSrchHeader->rangeShift == 0 )
274  return;
275  else
277  }
278 
279  for ( searchRange = 1, entrySelector = 1;
280  ( searchRange * 2 ) <= binSrchHeader->nUnits &&
281  searchRange < 0x8000U;
282  searchRange *= 2, entrySelector++ )
283  ;
284 
285  entrySelector--;
286  searchRange = (FT_UShort)( searchRange * binSrchHeader->unitSize );
287  rangeShift = (FT_UShort)( binSrchHeader->nUnits * binSrchHeader->unitSize
288  - searchRange );
289 
290  if ( searchRange != binSrchHeader->searchRange ||
291  entrySelector != binSrchHeader->entrySelector ||
292  rangeShift != binSrchHeader->rangeShift )
293  {
294  GXV_TRACE(( "Inconsistency found in BinSrchHeader\n" ));
295  GXV_TRACE(( "originally: unitSize=%d, nUnits=%d, "
296  "searchRange=%d, entrySelector=%d, "
297  "rangeShift=%d\n",
298  binSrchHeader->unitSize, binSrchHeader->nUnits,
299  binSrchHeader->searchRange, binSrchHeader->entrySelector,
300  binSrchHeader->rangeShift ));
301  GXV_TRACE(( "calculated: unitSize=%d, nUnits=%d, "
302  "searchRange=%d, entrySelector=%d, "
303  "rangeShift=%d\n",
304  binSrchHeader->unitSize, binSrchHeader->nUnits,
305  searchRange, entrySelector, rangeShift ));
306 
308  }
309  }
310 
311 
312  /*
313  * parser & validator of BinSrchHeader
314  * which is used in LookupTable format 2, 4, 6.
315  *
316  * Essential parameters (unitSize, nUnits) are returned by
317  * given pointer, others (searchRange, entrySelector, rangeShift)
318  * can be calculated by essential parameters, so they are just
319  * validated and discarded.
320  *
321  * However, wrong values in searchRange, entrySelector, rangeShift
322  * won't cause fatal errors, because these parameters might be
323  * only used in old m68k font driver in MacOS.
324  * -- suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
325  */
326 
327  FT_LOCAL_DEF( void )
329  FT_Bytes limit,
330  FT_UShort* unitSize_p,
331  FT_UShort* nUnits_p,
332  GXV_Validator gxvalid )
333  {
334  FT_Bytes p = table;
335  GXV_BinSrchHeader binSrchHeader;
336 
337 
338  GXV_NAME_ENTER( "BinSrchHeader validate" );
339 
340  if ( *unitSize_p == 0 )
341  {
342  GXV_LIMIT_CHECK( 2 );
343  binSrchHeader.unitSize = FT_NEXT_USHORT( p );
344  }
345  else
346  binSrchHeader.unitSize = *unitSize_p;
347 
348  if ( *nUnits_p == 0 )
349  {
350  GXV_LIMIT_CHECK( 2 );
351  binSrchHeader.nUnits = FT_NEXT_USHORT( p );
352  }
353  else
354  binSrchHeader.nUnits = *nUnits_p;
355 
356  GXV_LIMIT_CHECK( 2 + 2 + 2 );
357  binSrchHeader.searchRange = FT_NEXT_USHORT( p );
358  binSrchHeader.entrySelector = FT_NEXT_USHORT( p );
359  binSrchHeader.rangeShift = FT_NEXT_USHORT( p );
360  GXV_TRACE(( "nUnits %d\n", binSrchHeader.nUnits ));
361 
362  gxv_BinSrchHeader_check_consistency( &binSrchHeader, gxvalid );
363 
364  if ( *unitSize_p == 0 )
365  *unitSize_p = binSrchHeader.unitSize;
366 
367  if ( *nUnits_p == 0 )
368  *nUnits_p = binSrchHeader.nUnits;
369 
370  gxvalid->subtable_length = (FT_ULong)( p - table );
371  GXV_EXIT;
372  }
373 
374 
375  /*************************************************************************/
376  /*************************************************************************/
377  /***** *****/
378  /***** LOOKUP TABLE *****/
379  /***** *****/
380  /*************************************************************************/
381  /*************************************************************************/
382 
383 #define GXV_LOOKUP_VALUE_LOAD( P, SIGNSPEC ) \
384  ( P += 2, gxv_lookup_value_load( P - 2, SIGNSPEC ) )
385 
386  static GXV_LookupValueDesc
388  GXV_LookupValue_SignSpec signspec )
389  {
391 
392 
393  if ( signspec == GXV_LOOKUPVALUE_UNSIGNED )
394  v.u = FT_NEXT_USHORT( p );
395  else
396  v.s = FT_NEXT_SHORT( p );
397 
398  return v;
399  }
400 
401 
402 #define GXV_UNITSIZE_VALIDATE( FORMAT, UNITSIZE, NUNITS, CORRECTSIZE ) \
403  FT_BEGIN_STMNT \
404  if ( UNITSIZE != CORRECTSIZE ) \
405  { \
406  FT_ERROR(( "unitSize=%d differs from" \
407  " expected unitSize=%d" \
408  " in LookupTable %s\n", \
409  UNITSIZE, CORRECTSIZE, FORMAT )); \
410  if ( UNITSIZE != 0 && NUNITS != 0 ) \
411  { \
412  FT_ERROR(( " cannot validate anymore\n" )); \
413  FT_INVALID_FORMAT; \
414  } \
415  else \
416  FT_ERROR(( " forcibly continues\n" )); \
417  } \
418  FT_END_STMNT
419 
420 
421  /* ================= Simple Array Format 0 Lookup Table ================ */
422  static void
424  FT_Bytes limit,
425  GXV_Validator gxvalid )
426  {
427  FT_Bytes p = table;
428  FT_UShort i;
429 
431 
432 
433  GXV_NAME_ENTER( "LookupTable format 0" );
434 
435  GXV_LIMIT_CHECK( 2 * gxvalid->face->num_glyphs );
436 
437  for ( i = 0; i < gxvalid->face->num_glyphs; i++ )
438  {
439  GXV_LIMIT_CHECK( 2 );
440  if ( p + 2 >= limit ) /* some fonts have too-short fmt0 array */
441  {
442  GXV_TRACE(( "too short, glyphs %d - %d are missing\n",
443  i, gxvalid->face->num_glyphs ));
445  break;
446  }
447 
449  gxvalid->lookupval_func( i, &value, gxvalid );
450  }
451 
452  gxvalid->subtable_length = (FT_ULong)( p - table );
453  GXV_EXIT;
454  }
455 
456 
457  /* ================= Segment Single Format 2 Lookup Table ============== */
458  /*
459  * Apple spec says:
460  *
461  * To guarantee that a binary search terminates, you must include one or
462  * more special `end of search table' values at the end of the data to
463  * be searched. The number of termination values that need to be
464  * included is table-specific. The value that indicates binary search
465  * termination is 0xFFFF.
466  *
467  * The problem is that nUnits does not include this end-marker. It's
468  * quite difficult to discriminate whether the following 0xFFFF comes from
469  * the end-marker or some next data.
470  *
471  * -- suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
472  */
473  static void
475  FT_UShort unitSize,
476  GXV_Validator gxvalid )
477  {
478  FT_Bytes p = table;
479 
480 
481  while ( ( p + 4 ) < gxvalid->root->limit )
482  {
483  if ( p[0] != 0xFF || p[1] != 0xFF || /* lastGlyph */
484  p[2] != 0xFF || p[3] != 0xFF ) /* firstGlyph */
485  break;
486  p += unitSize;
487  }
488 
489  gxvalid->subtable_length = (FT_ULong)( p - table );
490  }
491 
492 
493  static void
495  FT_Bytes limit,
496  GXV_Validator gxvalid )
497  {
498  FT_Bytes p = table;
499  FT_UShort gid;
500 
501  FT_UShort unitSize;
502  FT_UShort nUnits;
503  FT_UShort unit;
504  FT_UShort lastGlyph;
505  FT_UShort firstGlyph;
507 
508 
509  GXV_NAME_ENTER( "LookupTable format 2" );
510 
511  unitSize = nUnits = 0;
512  gxv_BinSrchHeader_validate( p, limit, &unitSize, &nUnits, gxvalid );
513  p += gxvalid->subtable_length;
514 
515  GXV_UNITSIZE_VALIDATE( "format2", unitSize, nUnits, 6 );
516 
517  for ( unit = 0, gid = 0; unit < nUnits; unit++ )
518  {
519  GXV_LIMIT_CHECK( 2 + 2 + 2 );
520  lastGlyph = FT_NEXT_USHORT( p );
521  firstGlyph = FT_NEXT_USHORT( p );
523 
524  gxv_glyphid_validate( firstGlyph, gxvalid );
525  gxv_glyphid_validate( lastGlyph, gxvalid );
526 
527  if ( lastGlyph < gid )
528  {
529  GXV_TRACE(( "reverse ordered segment specification:"
530  " lastGlyph[%d]=%d < lastGlyph[%d]=%d\n",
531  unit, lastGlyph, unit - 1 , gid ));
533  }
534 
535  if ( lastGlyph < firstGlyph )
536  {
537  GXV_TRACE(( "reverse ordered range specification at unit %d:",
538  " lastGlyph %d < firstGlyph %d ",
539  unit, lastGlyph, firstGlyph ));
541 
542  if ( gxvalid->root->level == FT_VALIDATE_TIGHT )
543  continue; /* ftxvalidator silently skips such an entry */
544 
545  FT_TRACE4(( "continuing with exchanged values\n" ));
546  gid = firstGlyph;
547  firstGlyph = lastGlyph;
548  lastGlyph = gid;
549  }
550 
551  for ( gid = firstGlyph; gid <= lastGlyph; gid++ )
552  gxvalid->lookupval_func( gid, &value, gxvalid );
553  }
554 
555  gxv_LookupTable_fmt2_skip_endmarkers( p, unitSize, gxvalid );
556  p += gxvalid->subtable_length;
557 
558  gxvalid->subtable_length = (FT_ULong)( p - table );
559  GXV_EXIT;
560  }
561 
562 
563  /* ================= Segment Array Format 4 Lookup Table =============== */
564  static void
566  FT_Bytes limit,
567  GXV_Validator gxvalid )
568  {
569  FT_Bytes p = table;
570  FT_UShort unit;
571  FT_UShort gid;
572 
573  FT_UShort unitSize;
574  FT_UShort nUnits;
575  FT_UShort lastGlyph;
576  FT_UShort firstGlyph;
579 
580 
581  GXV_NAME_ENTER( "LookupTable format 4" );
582 
583  unitSize = nUnits = 0;
584  gxv_BinSrchHeader_validate( p, limit, &unitSize, &nUnits, gxvalid );
585  p += gxvalid->subtable_length;
586 
587  GXV_UNITSIZE_VALIDATE( "format4", unitSize, nUnits, 6 );
588 
589  for ( unit = 0, gid = 0; unit < nUnits; unit++ )
590  {
591  GXV_LIMIT_CHECK( 2 + 2 );
592  lastGlyph = FT_NEXT_USHORT( p );
593  firstGlyph = FT_NEXT_USHORT( p );
594 
595  gxv_glyphid_validate( firstGlyph, gxvalid );
596  gxv_glyphid_validate( lastGlyph, gxvalid );
597 
598  if ( lastGlyph < gid )
599  {
600  GXV_TRACE(( "reverse ordered segment specification:"
601  " lastGlyph[%d]=%d < lastGlyph[%d]=%d\n",
602  unit, lastGlyph, unit - 1 , gid ));
604  }
605 
606  if ( lastGlyph < firstGlyph )
607  {
608  GXV_TRACE(( "reverse ordered range specification at unit %d:",
609  " lastGlyph %d < firstGlyph %d ",
610  unit, lastGlyph, firstGlyph ));
612 
613  if ( gxvalid->root->level == FT_VALIDATE_TIGHT )
614  continue; /* ftxvalidator silently skips such an entry */
615 
616  FT_TRACE4(( "continuing with exchanged values\n" ));
617  gid = firstGlyph;
618  firstGlyph = lastGlyph;
619  lastGlyph = gid;
620  }
621 
622  GXV_LIMIT_CHECK( 2 );
624 
625  for ( gid = firstGlyph; gid <= lastGlyph; gid++ )
626  {
627  value = gxvalid->lookupfmt4_trans( (FT_UShort)( gid - firstGlyph ),
628  &base_value,
629  limit,
630  gxvalid );
631 
632  gxvalid->lookupval_func( gid, &value, gxvalid );
633  }
634  }
635 
636  gxv_LookupTable_fmt2_skip_endmarkers( p, unitSize, gxvalid );
637  p += gxvalid->subtable_length;
638 
639  gxvalid->subtable_length = (FT_ULong)( p - table );
640  GXV_EXIT;
641  }
642 
643 
644  /* ================= Segment Table Format 6 Lookup Table =============== */
645  static void
647  FT_UShort unitSize,
648  GXV_Validator gxvalid )
649  {
650  FT_Bytes p = table;
651 
652 
653  while ( p < gxvalid->root->limit )
654  {
655  if ( p[0] != 0xFF || p[1] != 0xFF )
656  break;
657  p += unitSize;
658  }
659 
660  gxvalid->subtable_length = (FT_ULong)( p - table );
661  }
662 
663 
664  static void
666  FT_Bytes limit,
667  GXV_Validator gxvalid )
668  {
669  FT_Bytes p = table;
670  FT_UShort unit;
671  FT_UShort prev_glyph;
672 
673  FT_UShort unitSize;
674  FT_UShort nUnits;
677 
678 
679  GXV_NAME_ENTER( "LookupTable format 6" );
680 
681  unitSize = nUnits = 0;
682  gxv_BinSrchHeader_validate( p, limit, &unitSize, &nUnits, gxvalid );
683  p += gxvalid->subtable_length;
684 
685  GXV_UNITSIZE_VALIDATE( "format6", unitSize, nUnits, 4 );
686 
687  for ( unit = 0, prev_glyph = 0; unit < nUnits; unit++ )
688  {
689  GXV_LIMIT_CHECK( 2 + 2 );
690  glyph = FT_NEXT_USHORT( p );
692 
693  if ( gxv_glyphid_validate( glyph, gxvalid ) )
694  GXV_TRACE(( " endmarker found within defined range"
695  " (entry %d < nUnits=%d)\n",
696  unit, nUnits ));
697 
698  if ( prev_glyph > glyph )
699  {
700  GXV_TRACE(( "current gid 0x%04x < previous gid 0x%04x\n",
701  glyph, prev_glyph ));
703  }
704  prev_glyph = glyph;
705 
706  gxvalid->lookupval_func( glyph, &value, gxvalid );
707  }
708 
709  gxv_LookupTable_fmt6_skip_endmarkers( p, unitSize, gxvalid );
710  p += gxvalid->subtable_length;
711 
712  gxvalid->subtable_length = (FT_ULong)( p - table );
713  GXV_EXIT;
714  }
715 
716 
717  /* ================= Trimmed Array Format 8 Lookup Table =============== */
718  static void
720  FT_Bytes limit,
721  GXV_Validator gxvalid )
722  {
723  FT_Bytes p = table;
724  FT_UShort i;
725 
727  FT_UShort firstGlyph;
729 
730 
731  GXV_NAME_ENTER( "LookupTable format 8" );
732 
733  /* firstGlyph + glyphCount */
734  GXV_LIMIT_CHECK( 2 + 2 );
735  firstGlyph = FT_NEXT_USHORT( p );
737 
738  gxv_glyphid_validate( firstGlyph, gxvalid );
739  gxv_glyphid_validate( (FT_UShort)( firstGlyph + glyphCount ), gxvalid );
740 
741  /* valueArray */
742  for ( i = 0; i < glyphCount; i++ )
743  {
744  GXV_LIMIT_CHECK( 2 );
746  gxvalid->lookupval_func( (FT_UShort)( firstGlyph + i ), &value, gxvalid );
747  }
748 
749  gxvalid->subtable_length = (FT_ULong)( p - table );
750  GXV_EXIT;
751  }
752 
753 
754  FT_LOCAL_DEF( void )
756  FT_Bytes limit,
757  GXV_Validator gxvalid )
758  {
759  FT_Bytes p = table;
761 
762  GXV_Validate_Func fmt_funcs_table[] =
763  {
765  NULL, /* 1 */
767  NULL, /* 3 */
769  NULL, /* 5 */
771  NULL, /* 7 */
773  };
774 
776 
777 
778  GXV_NAME_ENTER( "LookupTable" );
779 
780  /* lookuptbl_head may be used in fmt4 transit function. */
781  gxvalid->lookuptbl_head = table;
782 
783  /* format */
784  GXV_LIMIT_CHECK( 2 );
785  format = FT_NEXT_USHORT( p );
786  GXV_TRACE(( " (format %d)\n", format ));
787 
788  if ( format > 8 )
790 
791  func = fmt_funcs_table[format];
792  if ( !func )
794 
795  func( p, limit, gxvalid );
796  p += gxvalid->subtable_length;
797 
798  gxvalid->subtable_length = (FT_ULong)( p - table );
799 
800  GXV_EXIT;
801  }
802 
803 
804  /*************************************************************************/
805  /*************************************************************************/
806  /***** *****/
807  /***** Glyph ID *****/
808  /***** *****/
809  /*************************************************************************/
810  /*************************************************************************/
811 
814  GXV_Validator gxvalid )
815  {
816  FT_Face face;
817 
818 
819  if ( gid == 0xFFFFU )
820  {
821  GXV_EXIT;
822  return 1;
823  }
824 
825  face = gxvalid->face;
826  if ( face->num_glyphs < gid )
827  {
828  GXV_TRACE(( " gxv_glyphid_check() gid overflow: num_glyphs %d < %d\n",
829  face->num_glyphs, gid ));
831  }
832 
833  return 0;
834  }
835 
836 
837  /*************************************************************************/
838  /*************************************************************************/
839  /***** *****/
840  /***** CONTROL POINT *****/
841  /***** *****/
842  /*************************************************************************/
843  /*************************************************************************/
844 
845  FT_LOCAL_DEF( void )
847  FT_UShort ctl_point,
848  GXV_Validator gxvalid )
849  {
850  FT_Face face;
851  FT_Error error;
852 
855  FT_UShort n_points;
856 
857 
858  face = gxvalid->face;
859 
861  gid,
863  if ( error )
865 
866  glyph = face->glyph;
867  outline = glyph->outline;
868  n_points = (FT_UShort)outline.n_points;
869 
870  if ( !( ctl_point < n_points ) )
872  }
873 
874 
875  /*************************************************************************/
876  /*************************************************************************/
877  /***** *****/
878  /***** SFNT NAME *****/
879  /***** *****/
880  /*************************************************************************/
881  /*************************************************************************/
882 
883  FT_LOCAL_DEF( void )
885  FT_UShort min_index,
887  GXV_Validator gxvalid )
888  {
890  FT_UInt i;
891  FT_UInt nnames;
892 
893 
894  GXV_NAME_ENTER( "sfntName" );
895 
896  if ( name_index < min_index || max_index < name_index )
898 
899  nnames = FT_Get_Sfnt_Name_Count( gxvalid->face );
900  for ( i = 0; i < nnames; i++ )
901  {
902  if ( FT_Get_Sfnt_Name( gxvalid->face, i, &name ) != FT_Err_Ok )
903  continue;
904 
905  if ( name.name_id == name_index )
906  goto Out;
907  }
908 
909  GXV_TRACE(( " nameIndex = %d (UNTITLED)\n", name_index ));
911  goto Exit; /* make compiler happy */
912 
913  Out:
914  FT_TRACE1(( " nameIndex = %d (", name_index ));
916  FT_TRACE1(( ")\n" ));
917 
918  Exit:
919  GXV_EXIT;
920  }
921 
922 
923  /*************************************************************************/
924  /*************************************************************************/
925  /***** *****/
926  /***** STATE TABLE *****/
927  /***** *****/
928  /*************************************************************************/
929  /*************************************************************************/
930 
931  /* -------------------------- Class Table --------------------------- */
932 
933  /*
934  * highestClass specifies how many classes are defined in this
935  * Class Subtable. Apple spec does not mention whether undefined
936  * holes in the class (e.g.: 0-3 are predefined, 4 is unused, 5 is used)
937  * are permitted. At present, holes in a defined class are not checked.
938  * -- suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
939  */
940 
941  static void
943  FT_UShort* length_p,
944  FT_UShort stateSize,
945  FT_Byte* maxClassID_p,
946  GXV_Validator gxvalid )
947  {
948  FT_Bytes p = table;
949  FT_Bytes limit = table + *length_p;
950  FT_UShort firstGlyph;
951  FT_UShort nGlyphs;
952 
953 
954  GXV_NAME_ENTER( "ClassTable" );
955 
956  *maxClassID_p = 3; /* Classes 0, 2, and 3 are predefined */
957 
958  GXV_LIMIT_CHECK( 2 + 2 );
959  firstGlyph = FT_NEXT_USHORT( p );
960  nGlyphs = FT_NEXT_USHORT( p );
961 
962  GXV_TRACE(( " (firstGlyph = %d, nGlyphs = %d)\n", firstGlyph, nGlyphs ));
963 
964  if ( !nGlyphs )
965  goto Out;
966 
967  gxv_glyphid_validate( (FT_UShort)( firstGlyph + nGlyphs ), gxvalid );
968 
969  {
970  FT_Byte nGlyphInClass[256];
971  FT_Byte classID;
972  FT_UShort i;
973 
974 
975  FT_MEM_ZERO( nGlyphInClass, 256 );
976 
977 
978  for ( i = 0; i < nGlyphs; i++ )
979  {
980  GXV_LIMIT_CHECK( 1 );
981  classID = FT_NEXT_BYTE( p );
982  switch ( classID )
983  {
984  /* following classes should not appear in class array */
985  case 0: /* end of text */
986  case 2: /* out of bounds */
987  case 3: /* end of line */
989  break;
990 
991  case 1: /* out of bounds */
992  default: /* user-defined: 4 - ( stateSize - 1 ) */
993  if ( classID >= stateSize )
994  FT_INVALID_DATA; /* assign glyph to undefined state */
995 
996  nGlyphInClass[classID]++;
997  break;
998  }
999  }
1000  *length_p = (FT_UShort)( p - table );
1001 
1002  /* scan max ClassID in use */
1003  for ( i = 0; i < stateSize; i++ )
1004  if ( ( 3 < i ) && ( nGlyphInClass[i] > 0 ) )
1005  *maxClassID_p = (FT_Byte)i; /* XXX: Check Range? */
1006  }
1007 
1008  Out:
1009  GXV_TRACE(( "Declared stateSize=0x%02x, Used maxClassID=0x%02x\n",
1010  stateSize, *maxClassID_p ));
1011  GXV_EXIT;
1012  }
1013 
1014 
1015  /* --------------------------- State Array ----------------------------- */
1016 
1017  static void
1019  FT_UShort* length_p,
1020  FT_Byte maxClassID,
1021  FT_UShort stateSize,
1022  FT_Byte* maxState_p,
1023  FT_Byte* maxEntry_p,
1024  GXV_Validator gxvalid )
1025  {
1026  FT_Bytes p = table;
1027  FT_Bytes limit = table + *length_p;
1028  FT_Byte clazz;
1029  FT_Byte entry;
1030 
1031  FT_UNUSED( stateSize ); /* for the non-debugging case */
1032 
1033 
1034  GXV_NAME_ENTER( "StateArray" );
1035 
1036  GXV_TRACE(( "parse %d bytes by stateSize=%d maxClassID=%d\n",
1037  (int)(*length_p), stateSize, (int)(maxClassID) ));
1038 
1039  /*
1040  * 2 states are predefined and must be described in StateArray:
1041  * state 0 (start of text), 1 (start of line)
1042  */
1043  GXV_LIMIT_CHECK( ( 1 + maxClassID ) * 2 );
1044 
1045  *maxState_p = 0;
1046  *maxEntry_p = 0;
1047 
1048  /* read if enough to read another state */
1049  while ( p + ( 1 + maxClassID ) <= limit )
1050  {
1051  (*maxState_p)++;
1052  for ( clazz = 0; clazz <= maxClassID; clazz++ )
1053  {
1054  entry = FT_NEXT_BYTE( p );
1055  *maxEntry_p = (FT_Byte)FT_MAX( *maxEntry_p, entry );
1056  }
1057  }
1058  GXV_TRACE(( "parsed: maxState=%d, maxEntry=%d\n",
1059  *maxState_p, *maxEntry_p ));
1060 
1061  *length_p = (FT_UShort)( p - table );
1062 
1063  GXV_EXIT;
1064  }
1065 
1066 
1067  /* --------------------------- Entry Table ----------------------------- */
1068 
1069  static void
1071  FT_UShort* length_p,
1072  FT_Byte maxEntry,
1073  FT_UShort stateArray,
1074  FT_UShort stateArray_length,
1075  FT_Byte maxClassID,
1076  FT_Bytes statetable_table,
1077  FT_Bytes statetable_limit,
1078  GXV_Validator gxvalid )
1079  {
1080  FT_Bytes p = table;
1081  FT_Bytes limit = table + *length_p;
1082  FT_Byte entry;
1083  FT_Byte state;
1084  FT_Int entrySize = 2 + 2 + GXV_GLYPHOFFSET_SIZE( statetable );
1085 
1086  GXV_XStateTable_GlyphOffsetDesc glyphOffset;
1087 
1088 
1089  GXV_NAME_ENTER( "EntryTable" );
1090 
1091  GXV_TRACE(( "maxEntry=%d entrySize=%d\n", maxEntry, entrySize ));
1092 
1093  if ( ( maxEntry + 1 ) * entrySize > *length_p )
1094  {
1096 
1097  /* ftxvalidator and FontValidator both warn and continue */
1098  maxEntry = (FT_Byte)( *length_p / entrySize - 1 );
1099  GXV_TRACE(( "too large maxEntry, shrinking to %d fit EntryTable length\n",
1100  maxEntry ));
1101  }
1102 
1103  for ( entry = 0; entry <= maxEntry; entry++ )
1104  {
1105  FT_UShort newState;
1106  FT_UShort flags;
1107 
1108 
1109  GXV_LIMIT_CHECK( 2 + 2 );
1110  newState = FT_NEXT_USHORT( p );
1111  flags = FT_NEXT_USHORT( p );
1112 
1113 
1114  if ( newState < stateArray ||
1115  stateArray + stateArray_length < newState )
1116  {
1117  GXV_TRACE(( " newState offset 0x%04x is out of stateArray\n",
1118  newState ));
1120  continue;
1121  }
1122 
1123  if ( 0 != ( ( newState - stateArray ) % ( 1 + maxClassID ) ) )
1124  {
1125  GXV_TRACE(( " newState offset 0x%04x is not aligned to %d-classes\n",
1126  newState, 1 + maxClassID ));
1128  continue;
1129  }
1130 
1131  state = (FT_Byte)( ( newState - stateArray ) / ( 1 + maxClassID ) );
1132 
1133  switch ( GXV_GLYPHOFFSET_FMT( statetable ) )
1134  {
1135  case GXV_GLYPHOFFSET_NONE:
1136  glyphOffset.uc = 0; /* make compiler happy */
1137  break;
1138 
1139  case GXV_GLYPHOFFSET_UCHAR:
1140  glyphOffset.uc = FT_NEXT_BYTE( p );
1141  break;
1142 
1143  case GXV_GLYPHOFFSET_CHAR:
1144  glyphOffset.c = FT_NEXT_CHAR( p );
1145  break;
1146 
1148  glyphOffset.u = FT_NEXT_USHORT( p );
1149  break;
1150 
1151  case GXV_GLYPHOFFSET_SHORT:
1152  glyphOffset.s = FT_NEXT_SHORT( p );
1153  break;
1154 
1155  case GXV_GLYPHOFFSET_ULONG:
1156  glyphOffset.ul = FT_NEXT_ULONG( p );
1157  break;
1158 
1159  case GXV_GLYPHOFFSET_LONG:
1160  glyphOffset.l = FT_NEXT_LONG( p );
1161  break;
1162  }
1163 
1164  if ( gxvalid->statetable.entry_validate_func )
1166  flags,
1167  &glyphOffset,
1168  statetable_table,
1169  statetable_limit,
1170  gxvalid );
1171  }
1172 
1173  *length_p = (FT_UShort)( p - table );
1174 
1175  GXV_EXIT;
1176  }
1177 
1178 
1179  /* =========================== State Table ============================= */
1180 
1181  FT_LOCAL_DEF( void )
1183  FT_UShort classTable,
1184  FT_UShort stateArray,
1185  FT_UShort entryTable,
1186  FT_UShort* classTable_length_p,
1187  FT_UShort* stateArray_length_p,
1188  FT_UShort* entryTable_length_p,
1189  GXV_Validator gxvalid )
1190  {
1191  FT_UShort o[3];
1192  FT_UShort* l[3];
1193  FT_UShort buff[4];
1194 
1195 
1196  o[0] = classTable;
1197  o[1] = stateArray;
1198  o[2] = entryTable;
1199  l[0] = classTable_length_p;
1200  l[1] = stateArray_length_p;
1201  l[2] = entryTable_length_p;
1202 
1203  gxv_set_length_by_ushort_offset( o, l, buff, 3, table_size, gxvalid );
1204  }
1205 
1206 
1207  FT_LOCAL_DEF( void )
1209  FT_Bytes limit,
1210  GXV_Validator gxvalid )
1211  {
1212  FT_UShort stateSize;
1213  FT_UShort classTable; /* offset to Class(Sub)Table */
1214  FT_UShort stateArray; /* offset to StateArray */
1215  FT_UShort entryTable; /* offset to EntryTable */
1216 
1217  FT_UShort classTable_length;
1218  FT_UShort stateArray_length;
1219  FT_UShort entryTable_length;
1220  FT_Byte maxClassID;
1221  FT_Byte maxState;
1222  FT_Byte maxEntry;
1223 
1225 
1226  FT_Bytes p = table;
1227 
1228 
1229  GXV_NAME_ENTER( "StateTable" );
1230 
1231  GXV_TRACE(( "StateTable header\n" ));
1232 
1233  GXV_LIMIT_CHECK( 2 + 2 + 2 + 2 );
1234  stateSize = FT_NEXT_USHORT( p );
1235  classTable = FT_NEXT_USHORT( p );
1236  stateArray = FT_NEXT_USHORT( p );
1237  entryTable = FT_NEXT_USHORT( p );
1238 
1239  GXV_TRACE(( "stateSize=0x%04x\n", stateSize ));
1240  GXV_TRACE(( "offset to classTable=0x%04x\n", classTable ));
1241  GXV_TRACE(( "offset to stateArray=0x%04x\n", stateArray ));
1242  GXV_TRACE(( "offset to entryTable=0x%04x\n", entryTable ));
1243 
1244  if ( stateSize > 0xFF )
1246 
1247  if ( gxvalid->statetable.optdata_load_func )
1248  gxvalid->statetable.optdata_load_func( p, limit, gxvalid );
1249 
1250  if ( gxvalid->statetable.subtable_setup_func )
1251  setup_func = gxvalid->statetable.subtable_setup_func;
1252  else
1254 
1255  setup_func( (FT_UShort)( limit - table ),
1256  classTable,
1257  stateArray,
1258  entryTable,
1259  &classTable_length,
1260  &stateArray_length,
1261  &entryTable_length,
1262  gxvalid );
1263 
1264  GXV_TRACE(( "StateTable Subtables\n" ));
1265 
1266  if ( classTable != 0 )
1267  gxv_ClassTable_validate( table + classTable,
1268  &classTable_length,
1269  stateSize,
1270  &maxClassID,
1271  gxvalid );
1272  else
1273  maxClassID = (FT_Byte)( stateSize - 1 );
1274 
1275  if ( stateArray != 0 )
1276  gxv_StateArray_validate( table + stateArray,
1277  &stateArray_length,
1278  maxClassID,
1279  stateSize,
1280  &maxState,
1281  &maxEntry,
1282  gxvalid );
1283  else
1284  {
1285 #if 0
1286  maxState = 1; /* 0:start of text, 1:start of line are predefined */
1287 #endif
1288  maxEntry = 0;
1289  }
1290 
1291  if ( maxEntry > 0 && entryTable == 0 )
1293 
1294  if ( entryTable != 0 )
1295  gxv_EntryTable_validate( table + entryTable,
1296  &entryTable_length,
1297  maxEntry,
1298  stateArray,
1299  stateArray_length,
1300  maxClassID,
1301  table,
1302  limit,
1303  gxvalid );
1304 
1305  GXV_EXIT;
1306  }
1307 
1308 
1309  /* ================= eXtended State Table (for morx) =================== */
1310 
1311  FT_LOCAL_DEF( void )
1313  FT_ULong classTable,
1314  FT_ULong stateArray,
1315  FT_ULong entryTable,
1316  FT_ULong* classTable_length_p,
1317  FT_ULong* stateArray_length_p,
1318  FT_ULong* entryTable_length_p,
1319  GXV_Validator gxvalid )
1320  {
1321  FT_ULong o[3];
1322  FT_ULong* l[3];
1323  FT_ULong buff[4];
1324 
1325 
1326  o[0] = classTable;
1327  o[1] = stateArray;
1328  o[2] = entryTable;
1329  l[0] = classTable_length_p;
1330  l[1] = stateArray_length_p;
1331  l[2] = entryTable_length_p;
1332 
1333  gxv_set_length_by_ulong_offset( o, l, buff, 3, table_size, gxvalid );
1334  }
1335 
1336 
1337  static void
1339  GXV_LookupValueCPtr value_p,
1340  GXV_Validator gxvalid )
1341  {
1342  FT_UNUSED( glyph );
1343 
1344  if ( value_p->u >= gxvalid->xstatetable.nClasses )
1346  if ( value_p->u > gxvalid->xstatetable.maxClassID )
1347  gxvalid->xstatetable.maxClassID = value_p->u;
1348  }
1349 
1350 
1351  /*
1352  +===============+ --------+
1353  | lookup header | |
1354  +===============+ |
1355  | BinSrchHeader | |
1356  +===============+ |
1357  | lastGlyph[0] | |
1358  +---------------+ |
1359  | firstGlyph[0] | | head of lookup table
1360  +---------------+ | +
1361  | offset[0] | -> | offset [byte]
1362  +===============+ | +
1363  | lastGlyph[1] | | (glyphID - firstGlyph) * 2 [byte]
1364  +---------------+ |
1365  | firstGlyph[1] | |
1366  +---------------+ |
1367  | offset[1] | |
1368  +===============+ |
1369  |
1370  .... |
1371  |
1372  16bit value array |
1373  +===============+ |
1374  | value | <-------+
1375  ....
1376  */
1377  static GXV_LookupValueDesc
1379  GXV_LookupValueCPtr base_value_p,
1380  FT_Bytes lookuptbl_limit,
1381  GXV_Validator gxvalid )
1382  {
1383  FT_Bytes p;
1384  FT_Bytes limit;
1385  FT_UShort offset;
1387 
1388  /* XXX: check range? */
1389  offset = (FT_UShort)( base_value_p->u +
1390  relative_gindex * sizeof ( FT_UShort ) );
1391 
1392  p = gxvalid->lookuptbl_head + offset;
1393  limit = lookuptbl_limit;
1394 
1395  GXV_LIMIT_CHECK ( 2 );
1396  value.u = FT_NEXT_USHORT( p );
1397 
1398  return value;
1399  }
1400 
1401 
1402  static void
1404  FT_ULong* length_p,
1405  FT_UShort maxClassID,
1406  FT_ULong stateSize,
1407  FT_UShort* maxState_p,
1408  FT_UShort* maxEntry_p,
1409  GXV_Validator gxvalid )
1410  {
1411  FT_Bytes p = table;
1412  FT_Bytes limit = table + *length_p;
1413  FT_UShort clazz;
1414  FT_UShort entry;
1415 
1416  FT_UNUSED( stateSize ); /* for the non-debugging case */
1417 
1418 
1419  GXV_NAME_ENTER( "XStateArray" );
1420 
1421  GXV_TRACE(( "parse % 3d bytes by stateSize=% 3d maxClassID=% 3d\n",
1422  (int)(*length_p), stateSize, (int)(maxClassID) ));
1423 
1424  /*
1425  * 2 states are predefined and must be described:
1426  * state 0 (start of text), 1 (start of line)
1427  */
1428  GXV_LIMIT_CHECK( ( 1 + maxClassID ) * 2 * 2 );
1429 
1430  *maxState_p = 0;
1431  *maxEntry_p = 0;
1432 
1433  /* read if enough to read another state */
1434  while ( p + ( ( 1 + maxClassID ) * 2 ) <= limit )
1435  {
1436  (*maxState_p)++;
1437  for ( clazz = 0; clazz <= maxClassID; clazz++ )
1438  {
1439  entry = FT_NEXT_USHORT( p );
1440  *maxEntry_p = (FT_UShort)FT_MAX( *maxEntry_p, entry );
1441  }
1442  }
1443  GXV_TRACE(( "parsed: maxState=%d, maxEntry=%d\n",
1444  *maxState_p, *maxEntry_p ));
1445 
1446  *length_p = (FT_ULong)( p - table );
1447 
1448  GXV_EXIT;
1449  }
1450 
1451 
1452  static void
1454  FT_ULong* length_p,
1455  FT_UShort maxEntry,
1456  FT_ULong stateArray_length,
1457  FT_UShort maxClassID,
1458  FT_Bytes xstatetable_table,
1459  FT_Bytes xstatetable_limit,
1460  GXV_Validator gxvalid )
1461  {
1462  FT_Bytes p = table;
1463  FT_Bytes limit = table + *length_p;
1464  FT_UShort entry;
1465  FT_UShort state;
1466  FT_Int entrySize = 2 + 2 + GXV_GLYPHOFFSET_SIZE( xstatetable );
1467 
1468 
1469  GXV_NAME_ENTER( "XEntryTable" );
1470  GXV_TRACE(( "maxEntry=%d entrySize=%d\n", maxEntry, entrySize ));
1471 
1472  if ( ( p + ( maxEntry + 1 ) * entrySize ) > limit )
1474 
1475  for (entry = 0; entry <= maxEntry; entry++ )
1476  {
1477  FT_UShort newState_idx;
1478  FT_UShort flags;
1479  GXV_XStateTable_GlyphOffsetDesc glyphOffset;
1480 
1481 
1482  GXV_LIMIT_CHECK( 2 + 2 );
1483  newState_idx = FT_NEXT_USHORT( p );
1484  flags = FT_NEXT_USHORT( p );
1485 
1486  if ( stateArray_length < (FT_ULong)( newState_idx * 2 ) )
1487  {
1488  GXV_TRACE(( " newState index 0x%04x points out of stateArray\n",
1489  newState_idx ));
1491  }
1492 
1493  state = (FT_UShort)( newState_idx / ( 1 + maxClassID ) );
1494  if ( 0 != ( newState_idx % ( 1 + maxClassID ) ) )
1495  {
1496  FT_TRACE4(( "-> new state = %d (supposed)\n"
1497  "but newState index 0x%04x is not aligned to %d-classes\n",
1498  state, newState_idx, 1 + maxClassID ));
1500  }
1501 
1502  switch ( GXV_GLYPHOFFSET_FMT( xstatetable ) )
1503  {
1504  case GXV_GLYPHOFFSET_NONE:
1505  glyphOffset.uc = 0; /* make compiler happy */
1506  break;
1507 
1508  case GXV_GLYPHOFFSET_UCHAR:
1509  glyphOffset.uc = FT_NEXT_BYTE( p );
1510  break;
1511 
1512  case GXV_GLYPHOFFSET_CHAR:
1513  glyphOffset.c = FT_NEXT_CHAR( p );
1514  break;
1515 
1517  glyphOffset.u = FT_NEXT_USHORT( p );
1518  break;
1519 
1520  case GXV_GLYPHOFFSET_SHORT:
1521  glyphOffset.s = FT_NEXT_SHORT( p );
1522  break;
1523 
1524  case GXV_GLYPHOFFSET_ULONG:
1525  glyphOffset.ul = FT_NEXT_ULONG( p );
1526  break;
1527 
1528  case GXV_GLYPHOFFSET_LONG:
1529  glyphOffset.l = FT_NEXT_LONG( p );
1530  break;
1531 
1532  default:
1534  goto Exit;
1535  }
1536 
1537  if ( gxvalid->xstatetable.entry_validate_func )
1539  flags,
1540  &glyphOffset,
1541  xstatetable_table,
1542  xstatetable_limit,
1543  gxvalid );
1544  }
1545 
1546  Exit:
1547  *length_p = (FT_ULong)( p - table );
1548 
1549  GXV_EXIT;
1550  }
1551 
1552 
1553  FT_LOCAL_DEF( void )
1555  FT_Bytes limit,
1556  GXV_Validator gxvalid )
1557  {
1558  /* StateHeader members */
1559  FT_ULong classTable; /* offset to Class(Sub)Table */
1560  FT_ULong stateArray; /* offset to StateArray */
1561  FT_ULong entryTable; /* offset to EntryTable */
1562 
1563  FT_ULong classTable_length;
1564  FT_ULong stateArray_length;
1565  FT_ULong entryTable_length;
1566  FT_UShort maxState;
1567  FT_UShort maxEntry;
1568 
1570 
1571  FT_Bytes p = table;
1572 
1573 
1574  GXV_NAME_ENTER( "XStateTable" );
1575 
1576  GXV_TRACE(( "XStateTable header\n" ));
1577 
1578  GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 );
1579  gxvalid->xstatetable.nClasses = FT_NEXT_ULONG( p );
1580  classTable = FT_NEXT_ULONG( p );
1581  stateArray = FT_NEXT_ULONG( p );
1582  entryTable = FT_NEXT_ULONG( p );
1583 
1584  GXV_TRACE(( "nClasses =0x%08x\n", gxvalid->xstatetable.nClasses ));
1585  GXV_TRACE(( "offset to classTable=0x%08x\n", classTable ));
1586  GXV_TRACE(( "offset to stateArray=0x%08x\n", stateArray ));
1587  GXV_TRACE(( "offset to entryTable=0x%08x\n", entryTable ));
1588 
1589  if ( gxvalid->xstatetable.nClasses > 0xFFFFU )
1591 
1592  GXV_TRACE(( "StateTable Subtables\n" ));
1593 
1594  if ( gxvalid->xstatetable.optdata_load_func )
1595  gxvalid->xstatetable.optdata_load_func( p, limit, gxvalid );
1596 
1597  if ( gxvalid->xstatetable.subtable_setup_func )
1598  setup_func = gxvalid->xstatetable.subtable_setup_func;
1599  else
1601 
1602  setup_func( (FT_ULong)( limit - table ),
1603  classTable,
1604  stateArray,
1605  entryTable,
1606  &classTable_length,
1607  &stateArray_length,
1608  &entryTable_length,
1609  gxvalid );
1610 
1611  if ( classTable != 0 )
1612  {
1613  gxvalid->xstatetable.maxClassID = 0;
1614  gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED;
1615  gxvalid->lookupval_func = gxv_XClassTable_lookupval_validate;
1616  gxvalid->lookupfmt4_trans = gxv_XClassTable_lookupfmt4_transit;
1617  gxv_LookupTable_validate( table + classTable,
1618  table + classTable + classTable_length,
1619  gxvalid );
1620 #if 0
1621  if ( gxvalid->subtable_length < classTable_length )
1622  classTable_length = gxvalid->subtable_length;
1623 #endif
1624  }
1625  else
1626  {
1627  /* XXX: check range? */
1628  gxvalid->xstatetable.maxClassID =
1629  (FT_UShort)( gxvalid->xstatetable.nClasses - 1 );
1630  }
1631 
1632  if ( stateArray != 0 )
1633  gxv_XStateArray_validate( table + stateArray,
1634  &stateArray_length,
1635  gxvalid->xstatetable.maxClassID,
1636  gxvalid->xstatetable.nClasses,
1637  &maxState,
1638  &maxEntry,
1639  gxvalid );
1640  else
1641  {
1642 #if 0
1643  maxState = 1; /* 0:start of text, 1:start of line are predefined */
1644 #endif
1645  maxEntry = 0;
1646  }
1647 
1648  if ( maxEntry > 0 && entryTable == 0 )
1650 
1651  if ( entryTable != 0 )
1652  gxv_XEntryTable_validate( table + entryTable,
1653  &entryTable_length,
1654  maxEntry,
1655  stateArray_length,
1656  gxvalid->xstatetable.maxClassID,
1657  table,
1658  limit,
1659  gxvalid );
1660 
1661  GXV_EXIT;
1662  }
1663 
1664 
1665  /*************************************************************************/
1666  /*************************************************************************/
1667  /***** *****/
1668  /***** Table overlapping *****/
1669  /***** *****/
1670  /*************************************************************************/
1671  /*************************************************************************/
1672 
1673  static int
1675  FT_ULong table1_length,
1676  FT_Bytes table2_start,
1677  FT_ULong table2_length )
1678  {
1679  if ( table1_start == table2_start )
1680  {
1681  if ( ( table1_length == 0 || table2_length == 0 ) )
1682  goto Out;
1683  }
1684  else if ( table1_start < table2_start )
1685  {
1686  if ( ( table1_start + table1_length ) <= table2_start )
1687  goto Out;
1688  }
1689  else if ( table1_start > table2_start )
1690  {
1691  if ( ( table1_start >= table2_start + table2_length ) )
1692  goto Out;
1693  }
1694  return 1;
1695 
1696  Out:
1697  return 0;
1698  }
1699 
1700 
1701  FT_LOCAL_DEF( void )
1703  FT_ULong length,
1704  const FT_String* name,
1705  GXV_odtect_Range odtect )
1706  {
1707  odtect->range[odtect->nRanges].start = start;
1708  odtect->range[odtect->nRanges].length = length;
1709  odtect->range[odtect->nRanges].name = (FT_String*)name;
1710  odtect->nRanges++;
1711  }
1712 
1713 
1714  FT_LOCAL_DEF( void )
1716  GXV_Validator gxvalid )
1717  {
1718  FT_UInt i, j;
1719 
1720 
1721  GXV_NAME_ENTER( "check overlap among multi ranges" );
1722 
1723  for ( i = 0; i < odtect->nRanges; i++ )
1724  for ( j = 0; j < i; j++ )
1725  if ( 0 != gxv_compare_ranges( odtect->range[i].start,
1726  odtect->range[i].length,
1727  odtect->range[j].start,
1728  odtect->range[j].length ) )
1729  {
1730 #ifdef FT_DEBUG_LEVEL_TRACE
1731  if ( odtect->range[i].name || odtect->range[j].name )
1732  GXV_TRACE(( "found overlap between range %d and range %d\n",
1733  i, j ));
1734  else
1735  GXV_TRACE(( "found overlap between `%s' and `%s\'\n",
1736  odtect->range[i].name,
1737  odtect->range[j].name ));
1738 #endif
1740  }
1741 
1742  GXV_EXIT;
1743  }
1744 
1745 
1746 /* END */
struct @88 table[500]
#define state
Definition: aptex-macros.h:996
#define name
#define b
Definition: jpegint.h:372
int v
Definition: dviconv.c:10
#define error(a)
Definition: dviinfo.c:48
void Exit(int code)
Definition: dvispc.c:374
static char buff[2 *10240]
Definition: genind.c:46
#define a(n)
Definition: gpos-common.c:148
char * base_value
Definition: htex.c:101
#define ft_qsort
Definition: ftstdlib.h:132
#define FT_UNUSED(arg)
FT_Load_Glyph(FT_Face face, FT_UInt glyph_index, FT_Int32 load_flags)
Definition: ftobjs.c:796
#define FT_LOAD_NO_BITMAP
Definition: freetype.h:3025
#define FT_LOAD_IGNORE_TRANSFORM
Definition: freetype.h:3032
FT_Get_Sfnt_Name_Count(FT_Face face)
Definition: ftsnames.c:148
FT_Get_Sfnt_Name(FT_Face face, FT_UInt idx, FT_SfntName *aname)
Definition: ftsnames.c:157
unsigned long FT_ULong
Definition: fttypes.h:253
unsigned char FT_Byte
Definition: fttypes.h:154
int FT_Error
Definition: fttypes.h:299
unsigned short FT_UShort
Definition: fttypes.h:209
char FT_String
Definition: fttypes.h:187
unsigned int FT_UInt
Definition: fttypes.h:231
const FT_Byte * FT_Bytes
Definition: fttypes.h:165
signed int FT_Int
Definition: fttypes.h:220
#define FT_LOCAL_DEF(x)
#define FT_TRACE1(varformat)
Definition: ftdebug.h:188
#define FT_TRACE4(varformat)
Definition: ftdebug.h:191
#define FT_MEM_ZERO(dest, count)
Definition: ftmemory.h:244
#define NULL
Definition: ftobjs.h:61
#define FT_MIN(a, b)
Definition: ftobjs.h:70
#define FT_MAX(a, b)
Definition: ftobjs.h:71
#define FT_NEXT_USHORT(buffer)
Definition: ftstream.h:244
#define FT_NEXT_CHAR(buffer)
Definition: ftstream.h:235
#define FT_NEXT_LONG(buffer)
Definition: ftstream.h:253
#define FT_NEXT_SHORT(buffer)
Definition: ftstream.h:241
#define FT_NEXT_ULONG(buffer)
Definition: ftstream.h:256
#define FT_NEXT_BYTE(buffer)
Definition: ftstream.h:238
#define FT_INVALID_FORMAT
Definition: ftvalid.h:143
@ FT_VALIDATE_TIGHT
Definition: ftvalid.h:74
#define FT_INVALID_TOO_SHORT
Definition: ftvalid.h:135
#define FT_INVALID_OFFSET
Definition: ftvalid.h:139
#define FT_INVALID_DATA
Definition: ftvalid.h:151
#define FT_INVALID_GLYPH_ID
Definition: ftvalid.h:147
small capitals from c petite p
Definition: afcover.h:72
small capitals from c petite p scientific i
Definition: afcover.h:80
sizeof(AF_ModuleRec)
return FT_Err_Ok
Definition: ftbbox.c:526
FT_Face face
Definition: cffdrivr.c:659
gxv_array_getlimits_byte(FT_Bytes table, FT_Bytes limit, FT_Byte *min, FT_Byte *max, GXV_Validator gxvalid)
Definition: gxvcommn.c:181
gxv_ctlPoint_validate(FT_UShort gid, FT_UShort ctl_point, GXV_Validator gxvalid)
Definition: gxvcommn.c:846
gxv_BinSrchHeader_validate(FT_Bytes table, FT_Bytes limit, FT_UShort *unitSize_p, FT_UShort *nUnits_p, GXV_Validator gxvalid)
Definition: gxvcommn.c:328
gxv_array_getlimits_ushort(FT_Bytes table, FT_Bytes limit, FT_UShort *min, FT_UShort *max, GXV_Validator gxvalid)
Definition: gxvcommn.c:210
gxv_StateTable_subtable_setup(FT_UShort table_size, FT_UShort classTable, FT_UShort stateArray, FT_UShort entryTable, FT_UShort *classTable_length_p, FT_UShort *stateArray_length_p, FT_UShort *entryTable_length_p, GXV_Validator gxvalid)
Definition: gxvcommn.c:1182
gxv_set_length_by_ushort_offset(FT_UShort *offset, FT_UShort **length, FT_UShort *buff, FT_UInt nmemb, FT_UShort limit, GXV_Validator gxvalid)
Definition: gxvcommn.c:63
gxv_StateTable_validate(FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid)
Definition: gxvcommn.c:1208
gxv_LookupTable_validate(FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid)
Definition: gxvcommn.c:755
gxv_odtect_add_range(FT_Bytes start, FT_ULong length, const FT_String *name, GXV_odtect_Range odtect)
Definition: gxvcommn.c:1702
gxv_glyphid_validate(FT_UShort gid, GXV_Validator gxvalid)
Definition: gxvcommn.c:813
gxv_XStateTable_subtable_setup(FT_ULong table_size, FT_ULong classTable, FT_ULong stateArray, FT_ULong entryTable, FT_ULong *classTable_length_p, FT_ULong *stateArray_length_p, FT_ULong *entryTable_length_p, GXV_Validator gxvalid)
Definition: gxvcommn.c:1312
gxv_odtect_validate(GXV_odtect_Range odtect, GXV_Validator gxvalid)
Definition: gxvcommn.c:1715
gxv_sfntName_validate(FT_UShort name_index, FT_UShort min_index, FT_UShort max_index, GXV_Validator gxvalid)
Definition: gxvcommn.c:884
struct GXV_BinSrchHeader_ GXV_BinSrchHeader
gxv_set_length_by_ulong_offset(FT_ULong *offset, FT_ULong **length, FT_ULong *buff, FT_UInt nmemb, FT_ULong limit, GXV_Validator gxvalid)
Definition: gxvcommn.c:128
gxv_XStateTable_validate(FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid)
Definition: gxvcommn.c:1554
void(* GXV_Validate_Func)(FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid)
Definition: gxvcommn.h:81
#define GXV_GLYPHOFFSET_FMT(table)
Definition: gxvcommn.h:132
#define GXV_GLYPHOFFSET_SIZE(table)
Definition: gxvcommn.h:135
void(* GXV_XStateTable_Subtable_Setup_Func)(FT_ULong table_size, FT_ULong classTable, FT_ULong stateArray, FT_ULong entryTable, FT_ULong *classTable_length_p, FT_ULong *stateArray_length_p, FT_ULong *entryTable_length_p, GXV_Validator gxvalid)
Definition: gxvcommn.h:197
#define GXV_NAME_ENTER(name)
Definition: gxvcommn.h:300
#define GXV_SET_ERR_IF_PARANOID(err)
Definition: gxvcommn.h:65
@ GXV_LOOKUPVALUE_UNSIGNED
Definition: gxvcommn.h:99
#define GXV_TRACE(s)
Definition: gxvcommn.h:303
enum GXV_LookupValue_SignSpec_ GXV_LookupValue_SignSpec
@ GXV_GLYPHOFFSET_SHORT
Definition: gxvcommn.h:125
@ GXV_GLYPHOFFSET_CHAR
Definition: gxvcommn.h:123
@ GXV_GLYPHOFFSET_USHORT
Definition: gxvcommn.h:124
@ GXV_GLYPHOFFSET_UCHAR
Definition: gxvcommn.h:122
@ GXV_GLYPHOFFSET_NONE
Definition: gxvcommn.h:121
@ GXV_GLYPHOFFSET_LONG
Definition: gxvcommn.h:127
@ GXV_GLYPHOFFSET_ULONG
Definition: gxvcommn.h:126
void(* GXV_StateTable_Subtable_Setup_Func)(FT_UShort table_size, FT_UShort classTable, FT_UShort stateArray, FT_UShort entryTable, FT_UShort *classTable_length_p, FT_UShort *stateArray_length_p, FT_UShort *entryTable_length_p, GXV_Validator gxvalid)
Definition: gxvcommn.h:155
#define GXV_TRACE_HEXDUMP_SFNTNAME(n)
Definition: gxvcommn.h:358
#define GXV_EXIT
Definition: gxvcommn.h:301
#define GXV_LIMIT_CHECK(_count)
Definition: gxvcommn.h:271
#define const
Definition: ftzconf.h:91
int(* setup_func)(struct spc_handler *, struct spc_env *, struct spc_arg *)
Definition: specials.c:534
pdf_obj * entry
Definition: pdfdoc.c:64
#define length(c)
Definition: ctangleboot.c:65
#define root
Definition: ctangleboot.c:69
static luaL_Reg func[]
Definition: except.c:32
int unit
Definition: tfmread.c:8
union value value
Definition: obx.h:44
static int format
Definition: pbmclean.c:15
#define min(a, b)
Definition: pbmplus.h:223
#define max(a, b)
Definition: pbmto4425.c:11
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
static int offset
Definition: ppmtogif.c:642
static void gxv_LookupTable_fmt6_skip_endmarkers(FT_Bytes table, FT_UShort unitSize, GXV_Validator gxvalid)
Definition: gxvcommn.c:646
static void gxv_LookupTable_fmt6_validate(FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid)
Definition: gxvcommn.c:665
static void gxv_LookupTable_fmt0_validate(FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid)
Definition: gxvcommn.c:423
#define GXV_LOOKUP_VALUE_LOAD(P, SIGNSPEC)
Definition: gxvcommn.c:383
static int gxv_compare_ranges(FT_Bytes table1_start, FT_ULong table1_length, FT_Bytes table2_start, FT_ULong table2_length)
Definition: gxvcommn.c:1674
static int gxv_compare_ulong_offset(FT_ULong *a, FT_ULong *b)
Definition: gxvcommn.c:115
static void gxv_XStateArray_validate(FT_Bytes table, FT_ULong *length_p, FT_UShort maxClassID, FT_ULong stateSize, FT_UShort *maxState_p, FT_UShort *maxEntry_p, GXV_Validator gxvalid)
Definition: gxvcommn.c:1403
static void gxv_StateArray_validate(FT_Bytes table, FT_UShort *length_p, FT_Byte maxClassID, FT_UShort stateSize, FT_Byte *maxState_p, FT_Byte *maxEntry_p, GXV_Validator gxvalid)
Definition: gxvcommn.c:1018
static int gxv_compare_ushort_offset(FT_UShort *a, FT_UShort *b)
Definition: gxvcommn.c:50
static void gxv_LookupTable_fmt8_validate(FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid)
Definition: gxvcommn.c:719
static void gxv_LookupTable_fmt2_skip_endmarkers(FT_Bytes table, FT_UShort unitSize, GXV_Validator gxvalid)
Definition: gxvcommn.c:474
static void gxv_BinSrchHeader_check_consistency(GXV_BinSrchHeader *binSrchHeader, GXV_Validator gxvalid)
Definition: gxvcommn.c:258
static void gxv_EntryTable_validate(FT_Bytes table, FT_UShort *length_p, FT_Byte maxEntry, FT_UShort stateArray, FT_UShort stateArray_length, FT_Byte maxClassID, FT_Bytes statetable_table, FT_Bytes statetable_limit, GXV_Validator gxvalid)
Definition: gxvcommn.c:1070
static GXV_LookupValueDesc gxv_XClassTable_lookupfmt4_transit(FT_UShort relative_gindex, GXV_LookupValueCPtr base_value_p, FT_Bytes lookuptbl_limit, GXV_Validator gxvalid)
Definition: gxvcommn.c:1378
static void gxv_ClassTable_validate(FT_Bytes table, FT_UShort *length_p, FT_UShort stateSize, FT_Byte *maxClassID_p, GXV_Validator gxvalid)
Definition: gxvcommn.c:942
#define GXV_UNITSIZE_VALIDATE(FORMAT, UNITSIZE, NUNITS, CORRECTSIZE)
Definition: gxvcommn.c:402
static void gxv_LookupTable_fmt4_validate(FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid)
Definition: gxvcommn.c:565
static GXV_LookupValueDesc gxv_lookup_value_load(FT_Bytes p, GXV_LookupValue_SignSpec signspec)
Definition: gxvcommn.c:387
static void gxv_LookupTable_fmt2_validate(FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid)
Definition: gxvcommn.c:494
static void gxv_XEntryTable_validate(FT_Bytes table, FT_ULong *length_p, FT_UShort maxEntry, FT_ULong stateArray_length, FT_UShort maxClassID, FT_Bytes xstatetable_table, FT_Bytes xstatetable_limit, GXV_Validator gxvalid)
Definition: gxvcommn.c:1453
static void gxv_XClassTable_lookupval_validate(FT_UShort glyph, GXV_LookupValueCPtr value_p, GXV_Validator gxvalid)
Definition: gxvcommn.c:1338
#define flags
FT_Long num_glyphs
Definition: freetype.h:1036
FT_GlyphSlot glyph
Definition: freetype.h:1065
FT_UShort searchRange
Definition: gxvcommn.c:250
FT_UShort rangeShift
Definition: gxvcommn.c:252
FT_UShort nUnits
Definition: gxvcommn.c:249
FT_UShort unitSize
Definition: gxvcommn.c:248
FT_UShort entrySelector
Definition: gxvcommn.c:251
GXV_StateTable_Entry_Validate_Func entry_validate_func
Definition: gxvcommn.h:184
GXV_StateTable_ValidatorRec statetable
Definition: gxvcommn.h:253
GXV_XStateTable_ValidatorRec xstatetable
Definition: gxvcommn.h:254
GXV_Lookup_Fmt4_Transit_Func lookupfmt4_trans
Definition: gxvcommn.h:247
FT_Validator root
Definition: gxvcommn.h:238
FT_Bytes lookuptbl_head
Definition: gxvcommn.h:248
FT_ULong subtable_length
Definition: gxvcommn.h:243
GXV_Lookup_Value_Validate_Func lookupval_func
Definition: gxvcommn.h:246
GXV_LookupValue_SignSpec lookupval_sign
Definition: gxvcommn.h:245
GXV_XStateTable_Entry_Validate_Func entry_validate_func
Definition: gxvcommn.h:225
TT_UShort n_points
Definition: freetype.h:176
Definition: pbmfont.h:4
Definition: table.h:30
Definition: fio.h:71
Definition: strexpr.c:21
int j
Definition: t4ht.c:1589
glyphCount
Definition: tex4ht.c:3600
val
Definition: tex4ht.c:3227
TT_Glyph glyph
Definition: ttf2pfb.c:162
TT_Outline outline
Definition: ttf2pfb.c:167
Definition: obx.h:51
@ start
Definition: preamble.c:52
#define limit(x)
Definition: yuvsplittoppm.c:26