From 02280535bea08395871722f733aaaed70c992260 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 10 Dec 2018 14:59:49 +0100 Subject: Update bundled Freetype to 2.9.1 This is required to support the new emoji font on Android 9. [ChangeLog][Freetype] Upgraded bundled Freetype version to 2.9.1. This also adds support for the latest emoji font in use on Android 9. Fixes: QTBUG-70657 Change-Id: I99be72f0d23c20aca122b8fdadd4ded87b2edce1 Reviewed-by: Konstantin Ritt --- src/3rdparty/freetype/src/tools/afblue.pl | 17 +- src/3rdparty/freetype/src/tools/apinames.c | 33 +- .../freetype/src/tools/docmaker/content.py | 66 +++- .../freetype/src/tools/docmaker/docbeauty.py | 18 +- .../freetype/src/tools/docmaker/docmaker.py | 26 +- .../freetype/src/tools/docmaker/formatter.py | 7 +- .../freetype/src/tools/docmaker/sources.py | 34 +- src/3rdparty/freetype/src/tools/docmaker/tohtml.py | 184 +++++---- src/3rdparty/freetype/src/tools/docmaker/utils.py | 2 +- src/3rdparty/freetype/src/tools/ftfuzzer/README | 81 ++++ .../freetype/src/tools/ftfuzzer/ftfuzzer.cc | 428 +++++++++++++++++++++ .../freetype/src/tools/ftfuzzer/ftmutator.cc | 314 +++++++++++++++ .../freetype/src/tools/ftfuzzer/rasterfuzzer.cc | 129 +++++++ .../freetype/src/tools/ftfuzzer/runinput.cc | 58 +++ src/3rdparty/freetype/src/tools/ftrandom/Makefile | 26 +- src/3rdparty/freetype/src/tools/ftrandom/README | 79 ++-- .../freetype/src/tools/ftrandom/ftrandom.c | 161 +++++--- src/3rdparty/freetype/src/tools/glnames.py | 87 ++++- src/3rdparty/freetype/src/tools/no-copyright | 4 + .../freetype/src/tools/update-copyright-year | 2 +- 20 files changed, 1509 insertions(+), 247 deletions(-) create mode 100644 src/3rdparty/freetype/src/tools/ftfuzzer/README create mode 100644 src/3rdparty/freetype/src/tools/ftfuzzer/ftfuzzer.cc create mode 100644 src/3rdparty/freetype/src/tools/ftfuzzer/ftmutator.cc create mode 100644 src/3rdparty/freetype/src/tools/ftfuzzer/rasterfuzzer.cc create mode 100644 src/3rdparty/freetype/src/tools/ftfuzzer/runinput.cc (limited to 'src/3rdparty/freetype/src/tools') diff --git a/src/3rdparty/freetype/src/tools/afblue.pl b/src/3rdparty/freetype/src/tools/afblue.pl index 56b6452348..7c6f1a7df1 100644 --- a/src/3rdparty/freetype/src/tools/afblue.pl +++ b/src/3rdparty/freetype/src/tools/afblue.pl @@ -5,7 +5,7 @@ # # Process a blue zone character data file. # -# Copyright 2013-2015 by +# Copyright 2013-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, @@ -38,7 +38,8 @@ my $curr_max; # Name of the current maximum value. my $curr_enum_element; # Name of the current enumeration element. my $curr_offset; # The offset relative to current aux. variable. -my $curr_elem_size; # The size of the current string or block. +my $curr_elem_size; # The number of non-space characters in the current string or + # the number of elements in the current block. my $have_sections = 0; # Boolean; set if start of a section has been seen. my $have_strings; # Boolean; set if current section contains strings. @@ -159,12 +160,14 @@ sub convert_ascii_chars # A series of ASCII characters in the printable range. my $s = shift; - # We ignore spaces. - $s =~ s/ //g; + # We reduce multiple space characters to a single one. + $s =~ s/ +/ /g; - my $count = $s =~ s/\G(.)/'$1', /g; - $curr_offset += $count; - $curr_elem_size += $count; + # Count all non-space characters. Note that `()' applies a list context + # to the capture that is used to count the elements. + $curr_elem_size += () = $s =~ /[^ ]/g; + + $curr_offset += $s =~ s/\G(.)/'$1', /g; return $s; } diff --git a/src/3rdparty/freetype/src/tools/apinames.c b/src/3rdparty/freetype/src/tools/apinames.c index 9f81b1a6c7..06c3260430 100644 --- a/src/3rdparty/freetype/src/tools/apinames.c +++ b/src/3rdparty/freetype/src/tools/apinames.c @@ -22,7 +22,7 @@ #include #define PROGRAM_NAME "apinames" -#define PROGRAM_VERSION "0.2" +#define PROGRAM_VERSION "0.3" #define LINEBUFF_SIZE 1024 @@ -32,7 +32,8 @@ typedef enum OutputFormat_ OUTPUT_WINDOWS_DEF, /* output a Windows .DEF file for Visual C++ or Mingw */ OUTPUT_BORLAND_DEF, /* output a Windows .DEF file for Borland C++ */ OUTPUT_WATCOM_LBC, /* output a Watcom Linker Command File */ - OUTPUT_NETWARE_IMP /* output a NetWare ImportFile */ + OUTPUT_NETWARE_IMP, /* output a NetWare ImportFile */ + OUTPUT_GNU_VERMAP /* output a version map for GNU or Solaris linker */ } OutputFormat; @@ -90,14 +91,14 @@ names_add( const char* name, max_names += (max_names >> 1) + 4; the_names = (NameRec*)realloc( the_names, sizeof ( the_names[0] ) * max_names ); - if ( the_names == NULL ) + if ( !the_names ) panic( "not enough memory" ); } nm = &the_names[num_names++]; nm->hash = h; nm->name = (char*)malloc( len+1 ); - if ( nm->name == NULL ) + if ( !nm->name ) panic( "not enough memory" ); memcpy( nm->name, name, len ); @@ -159,7 +160,7 @@ names_dump( FILE* out, char temp[512]; - if ( dll_name == NULL ) + if ( !dll_name ) { fprintf( stderr, "you must provide a DLL name with the -d option!\n" ); @@ -168,7 +169,7 @@ names_dump( FILE* out, /* we must omit the .dll suffix from the library name */ dot = strchr( dll_name, '.' ); - if ( dot != NULL ) + if ( dot ) { int len = dot - dll_name; @@ -190,7 +191,7 @@ names_dump( FILE* out, case OUTPUT_NETWARE_IMP: { - if ( dll_name != NULL ) + if ( dll_name ) fprintf( out, " (%s)\n", dll_name ); for ( nn = 0; nn < num_names - 1; nn++ ) fprintf( out, " %s,\n", the_names[nn].name ); @@ -198,6 +199,15 @@ names_dump( FILE* out, } break; + case OUTPUT_GNU_VERMAP: + { + fprintf( out, "{\n\tglobal:\n" ); + for ( nn = 0; nn < num_names; nn++ ) + fprintf( out, "\t\t%s;\n", the_names[nn].name ); + fprintf( out, "\tlocal:\n\t\t*;\n};\n" ); + } + break; + default: /* LIST */ for ( nn = 0; nn < num_names; nn++ ) fprintf( out, "%s\n", the_names[nn].name ); @@ -323,6 +333,7 @@ usage( void ) " -wB : output .DEF file for Borland C++\n" " -wW : output Watcom Linker Response File\n" " -wN : output NetWare Import File\n" + " -wL : output version map for GNU or Solaris linker\n" "\n"; fprintf( stderr, @@ -371,7 +382,7 @@ int main( int argc, const char* const* argv ) arg += 2; out = fopen( arg, "wt" ); - if ( out == NULL ) + if ( !out ) { fprintf( stderr, "could not open '%s' for writing\n", argv[2] ); exit(3); @@ -410,6 +421,10 @@ int main( int argc, const char* const* argv ) format = OUTPUT_NETWARE_IMP; break; + case 'L': + format = OUTPUT_GNU_VERMAP; + break; + case 0: break; @@ -440,7 +455,7 @@ int main( int argc, const char* const* argv ) { FILE* file = fopen( argv[0], "rb" ); - if ( file == NULL ) + if ( !file ) fprintf( stderr, "unable to open '%s'\n", argv[0] ); else { diff --git a/src/3rdparty/freetype/src/tools/docmaker/content.py b/src/3rdparty/freetype/src/tools/docmaker/content.py index 1961878a7d..198780aee4 100644 --- a/src/3rdparty/freetype/src/tools/docmaker/content.py +++ b/src/3rdparty/freetype/src/tools/docmaker/content.py @@ -3,7 +3,7 @@ # # Parse comment blocks to build content blocks (library file). # -# Copyright 2002-2015 by +# Copyright 2002-2018 by # David Turner. # # This file is part of the FreeType project, and may only be used, @@ -46,9 +46,26 @@ re_code_end = re.compile( r"(\s*)}\s*$" ) # -# A regular expression to isolate identifiers from other text. +# A regular expression to isolate identifiers from other text. Two syntax +# forms are supported: # -re_identifier = re.compile( r'((?:\w|-)*)' ) +# +# [] +# +# where both `' and `' consist of alphanumeric characters, `_', +# and `-'. Use `' if there are multiple, valid `' entries; in the +# index, `' will be appended in parentheses. +# +# For example, +# +# stem_darkening[autofit] +# +# becomes `stem_darkening (autofit)' in the index. +# +re_identifier = re.compile( r""" + ((?:\w|-)+ + (?:\[(?:\w|-)+\])?) + """, re.VERBOSE ) # @@ -92,7 +109,7 @@ class DocCode: def dump( self, prefix = "", width = 60 ): lines = self.dump_lines( 0, width ) for l in lines: - print prefix + l + print( prefix + l ) def dump_lines( self, margin = 0, width = 60 ): result = [] @@ -122,7 +139,7 @@ class DocPara: def dump( self, prefix = "", width = 60 ): lines = self.dump_lines( 0, width ) for l in lines: - print prefix + l + print( prefix + l ) def dump_lines( self, margin = 0, width = 60 ): cur = "" # current line @@ -226,13 +243,13 @@ class DocField: def dump( self, prefix = "" ): if self.field: - print prefix + self.field + " ::" + print( prefix + self.field + " ::" ) prefix = prefix + "----" first = 1 for p in self.items: if not first: - print "" + print( "" ) p.dump( prefix ) first = 0 @@ -313,10 +330,10 @@ class DocMarkup: return None def dump( self, margin ): - print " " * margin + "<" + self.tag + ">" + print( " " * margin + "<" + self.tag + ">" ) for f in self.fields: f.dump( " " ) - print " " * margin + "" + print( " " * margin + "" ) ################################################################ @@ -436,15 +453,32 @@ class ContentProcessor: markup_lines = [] first = 1 + margin = -1 + in_code = 0 + for line in content: - found = None - for t in re_markup_tags: - m = t.match( line ) + if in_code: + m = re_code_end.match( line ) + if m and len( m.group( 1 ) ) <= margin: + in_code = 0 + margin = -1 + else: + m = re_code_start.match( line ) if m: - found = string.lower( m.group( 1 ) ) - prefix = len( m.group( 0 ) ) - line = " " * prefix + line[prefix:] # remove markup from line - break + in_code = 1 + margin = len( m.group( 1 ) ) + + found = None + + if not in_code: + for t in re_markup_tags: + m = t.match( line ) + if m: + found = string.lower( m.group( 1 ) ) + prefix = len( m.group( 0 ) ) + # remove markup from line + line = " " * prefix + line[prefix:] + break # is it the start of a new markup section ? if found: diff --git a/src/3rdparty/freetype/src/tools/docmaker/docbeauty.py b/src/3rdparty/freetype/src/tools/docmaker/docbeauty.py index 3ddf4a94a1..0b021fa6c9 100644 --- a/src/3rdparty/freetype/src/tools/docmaker/docbeauty.py +++ b/src/3rdparty/freetype/src/tools/docmaker/docbeauty.py @@ -10,9 +10,7 @@ from sources import * from content import * from utils import * -import utils - -import sys, os, time, string, getopt +import sys, os, string, getopt content_processor = ContentProcessor() @@ -40,13 +38,13 @@ def beautify_block( block ): def usage(): - print "\nDocBeauty 0.1 Usage information\n" - print " docbeauty [options] file1 [file2 ...]\n" - print "using the following options:\n" - print " -h : print this page" - print " -b : backup original files with the 'orig' extension" - print "" - print " --backup : same as -b" + print( "\nDocBeauty 0.1 Usage information\n" ) + print( " docbeauty [options] file1 [file2 ...]\n" ) + print( "using the following options:\n" ) + print( " -h : print this page" ) + print( " -b : backup original files with the 'orig' extension" ) + print( "" ) + print( " --backup : same as -b" ) def main( argv ): diff --git a/src/3rdparty/freetype/src/tools/docmaker/docmaker.py b/src/3rdparty/freetype/src/tools/docmaker/docmaker.py index de82d930f5..eb49afb0a0 100644 --- a/src/3rdparty/freetype/src/tools/docmaker/docmaker.py +++ b/src/3rdparty/freetype/src/tools/docmaker/docmaker.py @@ -4,7 +4,7 @@ # # Convert source code markup to HTML documentation. # -# Copyright 2002-2015 by +# Copyright 2002-2018 by # David Turner. # # This file is part of the FreeType project, and may only be used, @@ -31,21 +31,21 @@ from tohtml import * import utils -import sys, os, time, string, glob, getopt +import sys, glob, getopt def usage(): - print "\nDocMaker Usage information\n" - print " docmaker [options] file1 [file2 ...]\n" - print "using the following options:\n" - print " -h : print this page" - print " -t : set project title, as in '-t \"My Project\"'" - print " -o : set output directory, as in '-o mydir'" - print " -p : set documentation prefix, as in '-p ft2'" - print "" - print " --title : same as -t, as in '--title=\"My Project\"'" - print " --output : same as -o, as in '--output=mydir'" - print " --prefix : same as -p, as in '--prefix=ft2'" + print( "\nDocMaker Usage information\n" ) + print( " docmaker [options] file1 [file2 ...]\n" ) + print( "using the following options:\n" ) + print( " -h : print this page" ) + print( " -t : set project title, as in '-t \"My Project\"'" ) + print( " -o : set output directory, as in '-o mydir'" ) + print( " -p : set documentation prefix, as in '-p ft2'" ) + print( "" ) + print( " --title : same as -t, as in '--title=\"My Project\"'" ) + print( " --output : same as -o, as in '--output=mydir'" ) + print( " --prefix : same as -p, as in '--prefix=ft2'" ) def main( argv ): diff --git a/src/3rdparty/freetype/src/tools/docmaker/formatter.py b/src/3rdparty/freetype/src/tools/docmaker/formatter.py index f0a8808c47..2708fd40d6 100644 --- a/src/3rdparty/freetype/src/tools/docmaker/formatter.py +++ b/src/3rdparty/freetype/src/tools/docmaker/formatter.py @@ -3,7 +3,7 @@ # # Convert parsed content blocks to a structured document (library file). # -# Copyright 2002-2015 by +# Copyright 2002-2018 by # David Turner. # # This file is part of the FreeType project, and may only be used, @@ -56,6 +56,11 @@ class Formatter: self.block_index = self.identifiers.keys() self.block_index.sort( key = index_key ) + # also add section names to dictionary (without making them appear + # in the index) + for section in self.sections: + self.add_identifier( section.name, section ) + def add_identifier( self, name, block ): if name in self.identifiers: # duplicate name! diff --git a/src/3rdparty/freetype/src/tools/docmaker/sources.py b/src/3rdparty/freetype/src/tools/docmaker/sources.py index be38132d1d..e3b95e0faa 100644 --- a/src/3rdparty/freetype/src/tools/docmaker/sources.py +++ b/src/3rdparty/freetype/src/tools/docmaker/sources.py @@ -3,7 +3,7 @@ # # Convert source code comments to multi-line blocks (library file). # -# Copyright 2002-2015 by +# Copyright 2002-2018 by # David Turner. # # This file is part of the FreeType project, and may only be used, @@ -29,7 +29,7 @@ # -import fileinput, re, sys, os, string +import fileinput, re, string ################################################################ @@ -138,12 +138,24 @@ re_markup_tags = [re_markup_tag1, re_markup_tag2] # # A regular expression to detect a cross reference, after markup tags have -# been stripped off. Group 1 is the reference, group 2 the rest of the -# line. +# been stripped off. # -# A cross reference consists of letters, digits, or characters `-' and `_'. +# Two syntax forms are supported: # -re_crossref = re.compile( r'@((?:\w|-)*)(.*)' ) # @foo +# @ +# @[] +# +# where both `' and `' consist of alphanumeric characters, `_', +# and `-'. Use `' if there are multiple, valid `' entries. +# +# Example: @foo[bar] +# +re_crossref = re.compile( r""" + @ + (?P(?:\w|-)+ + (?:\[(?:\w|-)+\])?) + (?P.*) + """, re.VERBOSE ) # # Two regular expressions to detect italic and bold markup, respectively. @@ -159,7 +171,7 @@ re_bold = re.compile( r"\*((?:\w|-)(?:\w|'|-)*)\*(.*)" ) # *bold* # # This regular expression code to identify an URL has been taken from # -# http://mail.python.org/pipermail/tutor/2002-September/017228.html +# https://mail.python.org/pipermail/tutor/2002-September/017228.html # # (with slight modifications). # @@ -284,10 +296,10 @@ class SourceBlock: # debugging only -- not used in normal operations def dump( self ): if self.content: - print "{{{content start---" + print( "{{{content start---" ) for l in self.content: - print l - print "---content end}}}" + print( l ) + print( "---content end}}}" ) return fmt = "" @@ -295,7 +307,7 @@ class SourceBlock: fmt = repr( self.format.id ) + " " for line in self.lines: - print line + print( line ) ################################################################ diff --git a/src/3rdparty/freetype/src/tools/docmaker/tohtml.py b/src/3rdparty/freetype/src/tools/docmaker/tohtml.py index bc6bcf0511..9f318a2a49 100644 --- a/src/3rdparty/freetype/src/tools/docmaker/tohtml.py +++ b/src/3rdparty/freetype/src/tools/docmaker/tohtml.py @@ -3,7 +3,7 @@ # # A sub-class container of the `Formatter' class to produce HTML. # -# Copyright 2002-2015 by +# Copyright 2002-2018 by # David Turner. # # This file is part of the FreeType project, and may only be used, @@ -25,7 +25,7 @@ import time # The following strings define the HTML header used by all generated pages. html_header_1 = """\ +"https://www.w3.org/TR/html4/loose.dtd"> @@ -164,7 +164,8 @@ html_footer = """\ """ # The header and footer used for each section. -section_title_header = "

" +section_title_header1 = '

' section_title_footer = "

" # The header and footer used for code segments. @@ -309,7 +310,14 @@ class HtmlFormatter( Formatter ): def make_block_url( self, block, name = None ): if name == None: name = block.name - return self.make_section_url( block.section ) + "#" + name + + try: + section_url = self.make_section_url( block.section ) + except: + # we already have a section + section_url = self.make_section_url( block ) + + return section_url + "#" + name def make_html_word( self, word ): """Analyze a simple word to detect cross-references and markup.""" @@ -317,11 +325,27 @@ class HtmlFormatter( Formatter ): m = re_crossref.match( word ) if m: try: - name = m.group( 1 ) - rest = m.group( 2 ) + name = m.group( 'name' ) + rest = m.group( 'rest' ) block = self.identifiers[name] url = self.make_block_url( block ) - return '' + name + '' + rest + # display `foo[bar]' as `foo' + name = re.sub( r'\[.*\]', '', name ) + # normalize url, following RFC 3986 + url = string.replace( url, "[", "(" ) + url = string.replace( url, "]", ")" ) + + try: + # for sections, display title + url = ( '‘' + + block.title + '’' + + rest ) + except: + url = ( '' + + name + '' + + rest ) + + return url except: # we detected a cross-reference to an unknown item sys.stderr.write( "WARNING: undefined cross reference" @@ -366,7 +390,7 @@ class HtmlFormatter( Formatter ): """Convert a code sequence to HTML.""" line = code_header + '\n' for l in lines: - line = line + html_quote( l ) + '\n' + line = line + html_quote( l ).rstrip() + '\n' return line + code_footer @@ -382,7 +406,7 @@ class HtmlFormatter( Formatter ): return string.join( lines, '\n' ) def print_html_items( self, items ): - print self.make_html_items( items ) + print( self.make_html_items( items ) ) def print_html_field( self, field ): if field.name: @@ -390,10 +414,10 @@ class HtmlFormatter( Formatter ): + field.name + "" ) - print self.make_html_items( field.items ) + print( self.make_html_items( field.items ) ) if field.name: - print "" + print( "" ) def html_source_quote( self, line, block_name = None ): result = "" @@ -417,16 +441,22 @@ class HtmlFormatter( Formatter ): id = block.name # link to a field ID if possible - for markup in block.markups: - if markup.tag == 'values': - for field in markup.fields: - if field.name: - id = name + try: + for markup in block.markups: + if markup.tag == 'values': + for field in markup.fields: + if field.name: + id = name + + result = ( result + prefix + + '' + name + '' ) + except: + # sections don't have `markups'; however, we don't + # want references to sections here anyway + result = result + html_quote( line[:length] ) - result = ( result + prefix - + '' + name + '' ) else: result = result + html_quote( line[:length] ) @@ -438,14 +468,14 @@ class HtmlFormatter( Formatter ): return result def print_html_field_list( self, fields ): - print '' + print( '
' ) for field in fields: - print ( '" - print "
' - + field.name - + '' ) + print( '
' + + field.name + + '' ) self.print_html_items( field.items ) - print "
" + print( "" ) + print( "" ) def print_html_markup( self, markup ): table_fields = [] @@ -469,7 +499,7 @@ class HtmlFormatter( Formatter ): # formatting the index # def index_enter( self ): - print self.html_index_header + print( self.html_index_header ) self.index_items = {} def index_name_enter( self, name ): @@ -482,7 +512,7 @@ class HtmlFormatter( Formatter ): count = len( self.block_index ) rows = ( count + self.columns - 1 ) // self.columns - print '' + print( '
' ) for r in range( rows ): line = "" for c in range( self.columns ): @@ -490,20 +520,26 @@ class HtmlFormatter( Formatter ): if i < count: bname = self.block_index[r + c * rows] url = self.index_items[bname] + # display `foo[bar]' as `foo (bar)' + bname = string.replace( bname, "[", " (" ) + bname = string.replace( bname, "]", ")" ) + # normalize url, following RFC 3986 + url = string.replace( url, "[", "(" ) + url = string.replace( url, "]", ")" ) line = ( line + '' ) else: line = line + '' line = line + "" - print line + print( line ) - print "
' + bname + '
" + print( "" ) print( index_footer_start + self.file_prefix + "toc.html" + index_footer_end ) - print self.html_footer + print( self.html_footer ) self.index_items = {} @@ -517,25 +553,25 @@ class HtmlFormatter( Formatter ): # formatting the table of contents # def toc_enter( self ): - print self.html_toc_header - print "

Table of Contents

" + print( self.html_toc_header ) + print( "

Table of Contents

" ) def toc_chapter_enter( self, chapter ): - print chapter_header + string.join( chapter.title ) + chapter_inter - print '' + print( chapter_header + string.join( chapter.title ) + chapter_inter ) + print( '
' ) def toc_section_enter( self, section ): - print ( '" + print( "" ) def toc_chapter_exit( self, chapter ): - print "
' ) - print self.make_html_para( section.abstract ) + print( '
' ) + print( self.make_html_para( section.abstract ) ) def toc_section_exit( self, section ): - print "
" - print chapter_footer + print( "" ) + print( chapter_footer ) def toc_index( self, index_filename ): print( chapter_header @@ -547,7 +583,7 @@ class HtmlFormatter( Formatter ): + self.file_prefix + "index.html" + toc_footer_end ) - print self.html_footer + print( self.html_footer ) def toc_dump( self, toc_filename = None, index_filename = None ): if toc_filename == None: @@ -562,9 +598,11 @@ class HtmlFormatter( Formatter ): # formatting sections # def section_enter( self, section ): - print self.html_header + print( self.html_header ) - print section_title_header + section.title + section_title_footer + print( section_title_header1 + section.name + section_title_header2 + + section.title + + section_title_footer ) maxwidth = 0 for b in section.blocks.values(): @@ -574,8 +612,8 @@ class HtmlFormatter( Formatter ): width = 70 # XXX magic number if maxwidth > 0: # print section synopsis - print section_synopsis_header - print '' + print( section_synopsis_header ) + print( '
' ) columns = width // maxwidth if columns < 1: @@ -601,26 +639,38 @@ class HtmlFormatter( Formatter ): # even omit it completely) line = line + " " else: - line = ( line + '' + url = name + # display `foo[bar]' as `foo' + name = re.sub( r'\[.*\]', '', name ) + # normalize url, following RFC 3986 + url = string.replace( url, "[", "(" ) + url = string.replace( url, "]", ")" ) + line = ( line + '' + name + '' ) line = line + '' line = line + "" - print line + print( line ) - print "
" - print section_synopsis_footer + print( "" ) + print( section_synopsis_footer ) - print description_header - print self.make_html_items( section.description ) - print description_footer + print( description_header ) + print( self.make_html_items( section.description ) ) + print( description_footer ) def block_enter( self, block ): - print block_header + print( block_header ) # place html anchor if needed if block.name: - print( '

' + block.name + '

' ) + url = block.name + # display `foo[bar]' as `foo' + name = re.sub( r'\[.*\]', '', block.name ) + # normalize url, following RFC 3986 + url = string.replace( url, "[", "(" ) + url = string.replace( url, "]", ")" ) + print( '

' + name + '

' ) # dump the block C source lines now if block.code: @@ -636,28 +686,28 @@ class HtmlFormatter( Formatter ): # + " '" + block.source.filename + "'.\n" ) if header: - print ( header_location_header - + 'Defined in ' + header + '.' - + header_location_footer ) + print( header_location_header + + 'Defined in ' + header + '.' + + header_location_footer ) - print source_header + print( source_header ) for l in block.code: - print self.html_source_quote( l, block.name ) - print source_footer + print( self.html_source_quote( l, block.name ) ) + print( source_footer ) def markup_enter( self, markup, block ): if markup.tag == "description": - print description_header + print( description_header ) else: - print marker_header + markup.tag + marker_inter + print( marker_header + markup.tag + marker_inter ) self.print_html_markup( markup ) def markup_exit( self, markup, block ): if markup.tag == "description": - print description_footer + print( description_footer ) else: - print marker_footer + print( marker_footer ) def block_exit( self, block ): print( block_footer_start + self.file_prefix + "index.html" @@ -665,7 +715,7 @@ class HtmlFormatter( Formatter ): + block_footer_end ) def section_exit( self, section ): - print html_footer + print( html_footer ) def section_dump_all( self ): for section in self.sections: diff --git a/src/3rdparty/freetype/src/tools/docmaker/utils.py b/src/3rdparty/freetype/src/tools/docmaker/utils.py index 254083e92e..f40f1674a0 100644 --- a/src/3rdparty/freetype/src/tools/docmaker/utils.py +++ b/src/3rdparty/freetype/src/tools/docmaker/utils.py @@ -3,7 +3,7 @@ # # Auxiliary functions for the `docmaker' tool (library file). # -# Copyright 2002-2015 by +# Copyright 2002-2018 by # David Turner. # # This file is part of the FreeType project, and may only be used, diff --git a/src/3rdparty/freetype/src/tools/ftfuzzer/README b/src/3rdparty/freetype/src/tools/ftfuzzer/README new file mode 100644 index 0000000000..09d8e9f325 --- /dev/null +++ b/src/3rdparty/freetype/src/tools/ftfuzzer/README @@ -0,0 +1,81 @@ +ftfuzzer +======== + + +ftfuzzer.cc +----------- + +This file contains a target function for FreeType fuzzing. It can be +used with libFuzzer (https://llvm.org/docs/LibFuzzer.html) or +potentially any other similar fuzzer. + +Usage: + + 1. Build `libfreetype.a' and `ftfuzzer.cc' using the most recent + clang compiler with these flags: + + # for fuzzer coverage feedback + -fsanitize-coverage=edge,8bit-counters + # for bug checking + -fsanitize=address,signed-integer-overflow,shift + + You also need the header files from the `libarchive' library + (https://www.libarchive.org/) for handling tar files (see file + `ftmutator.cc' below for more). + + 2. Link with `libFuzzer' (it contains `main') and `libarchive'. + + 3. Run the fuzzer on some test corpus. + +The exact flags and commands may vary. + + https://github.com/google/oss-fuzz/tree/master/projects/freetype2 + +There is a continuous fuzzing bot that runs ftfuzzer. + + https://oss-fuzz.com + +(You need an account to be able to see coverage reports and the like +on oss-fuzz.com.) + +Check the bot configuration for the most current settings. + + +ftmutator.cc +------------ + +FreeType has the ability to `attach' auxiliary files to a font file, +providing additional information. The main usage is to load AFM files +for PostScript Type 1 fonts. + +However, libFuzzer currently only supports mutation of a single input +file. For this reason, `ftmutator.cc' contains a custom fuzzer +mutator that uses an uncompressed tar file archive as the input. The +first file in such a tarball gets opened by FreeType as a font, all +other files are treated as input for `FT_Attach_Stream'. + +Compilation is similar to `ftfuzzer.c'. + + +runinput.cc +----------- + +To run the target function on a set of input files, this file contains +a convenience `main' function. Link it with `ftfuzzer.cc', +`libfreetype.a', and `libarchive' and run like + + ./a.out my_tests_inputs/* + +---------------------------------------------------------------------- + +Copyright 2015-2018 by +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. + + +--- end of README --- diff --git a/src/3rdparty/freetype/src/tools/ftfuzzer/ftfuzzer.cc b/src/3rdparty/freetype/src/tools/ftfuzzer/ftfuzzer.cc new file mode 100644 index 0000000000..acf2bc9820 --- /dev/null +++ b/src/3rdparty/freetype/src/tools/ftfuzzer/ftfuzzer.cc @@ -0,0 +1,428 @@ +// ftfuzzer.cc +// +// A fuzzing function to test FreeType with libFuzzer. +// +// Copyright 2015-2018 by +// 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. + + +// we use `unique_ptr', `decltype', and other gimmicks defined since C++11 +#if __cplusplus < 201103L +# error "a C++11 compiler is needed" +#endif + +#include +#include + +#include +#include + +#include +#include + + + using namespace std; + + +#include + +#include FT_FREETYPE_H +#include FT_GLYPH_H +#include FT_CACHE_H +#include FT_CACHE_CHARMAP_H +#include FT_CACHE_IMAGE_H +#include FT_CACHE_SMALL_BITMAPS_H +#include FT_SYNTHESIS_H +#include FT_ADVANCES_H +#include FT_OUTLINE_H +#include FT_BBOX_H +#include FT_MODULE_H +#include FT_DRIVER_H +#include FT_MULTIPLE_MASTERS_H + + + static FT_Library library; + static int InitResult; + + + struct FT_Global + { + FT_Global() + { + InitResult = FT_Init_FreeType( &library ); + if ( InitResult ) + return; + + // try to activate Adobe's CFF engine; it might not be the default + unsigned int cff_hinting_engine = FT_HINTING_ADOBE; + FT_Property_Set( library, + "cff", + "hinting-engine", &cff_hinting_engine ); + } + + ~FT_Global() + { + FT_Done_FreeType( library ); + } + }; + + FT_Global global_ft; + + + // We want to select n values at random (without repetition), + // with 0 < n <= N. The algorithm is taken from TAoCP, Vol. 2 + // (Algorithm S, selection sampling technique) + struct Random + { + int n; + int N; + + int t; // total number of values so far + int m; // number of selected values so far + + uint32_t r; // the current pseudo-random number + + Random( int n_, + int N_ ) + : n( n_ ), + N( N_ ) + { + t = 0; + m = 0; + + // Ideally, this should depend on the input file, + // for example, taking the sha256 as input; + // however, this is overkill for fuzzying tests. + r = 12345; + } + + int get() + { + if ( m >= n ) + return -1; + + Redo: + // We can't use `rand': different C libraries might provide + // different implementations of this function. As a replacement, + // we use a 32bit version of the `xorshift' algorithm. + r ^= r << 13; + r ^= r >> 17; + r ^= r << 5; + + double U = double( r ) / UINT32_MAX; + + if ( ( N - t ) * U >= ( n - m ) ) + { + t++; + goto Redo; + } + + t++; + m++; + + return t; + } + }; + + + static int + archive_read_entry_data( struct archive *ar, + vector *vw ) + { + int r; + const FT_Byte* buff; + size_t size; + int64_t offset; + + for (;;) + { + r = archive_read_data_block( ar, + reinterpret_cast( &buff ), + &size, + &offset ); + if ( r == ARCHIVE_EOF ) + return ARCHIVE_OK; + if ( r != ARCHIVE_OK ) + return r; + + vw->insert( vw->end(), buff, buff + size ); + } + } + + + static vector> + parse_data( const uint8_t* data, + size_t size ) + { + struct archive_entry* entry; + int r; + vector> files; + + unique_ptr a( archive_read_new(), + archive_read_free ); + + // activate reading of uncompressed tar archives + archive_read_support_format_tar( a.get() ); + + // the need for `const_cast' was removed with libarchive commit be4d4dd + if ( !( r = archive_read_open_memory( + a.get(), + const_cast(static_cast( data ) ), + size ) ) ) + { + unique_ptr a_open( a.get(), + archive_read_close ); + + // read files contained in archive + for (;;) + { + r = archive_read_next_header( a_open.get(), &entry ); + if ( r == ARCHIVE_EOF ) + break; + if ( r != ARCHIVE_OK ) + break; + + vector entry_data; + r = archive_read_entry_data( a.get(), &entry_data ); + if ( r != ARCHIVE_OK ) + break; + + files.push_back( move( entry_data ) ); + } + } + + if ( files.size() == 0 ) + files.emplace_back( data, data + size ); + + return files; + } + + + static void + setIntermediateAxis( FT_Face face ) + { + // only handle Multiple Masters and GX variation fonts + if ( !FT_HAS_MULTIPLE_MASTERS( face ) ) + return; + + // get variation data for current instance + FT_MM_Var* variations_ptr = nullptr; + if ( FT_Get_MM_Var( face, &variations_ptr ) ) + return; + + unique_ptr variations( variations_ptr, free ); + vector coords( variations->num_axis ); + + // select an arbitrary instance + for ( unsigned int i = 0; i < variations->num_axis; i++ ) + coords[i] = ( variations->axis[i].minimum + + variations->axis[i].def ) / 2; + + if ( FT_Set_Var_Design_Coordinates( face, + FT_UInt( coords.size() ), + coords.data() ) ) + return; + } + + + // the interface function to the libFuzzer library + extern "C" int + LLVMFuzzerTestOneInput( const uint8_t* data, + size_t size_ ) + { + assert( !InitResult ); + + if ( size_ < 1 ) + return 0; + + const vector>& files = parse_data( data, size_ ); + + FT_Face face; + FT_Int32 load_flags = FT_LOAD_DEFAULT; +#if 0 + FT_Render_Mode render_mode = FT_RENDER_MODE_NORMAL; +#endif + + // We use a conservative approach here, at the cost of calling + // `FT_New_Face' quite often. The idea is that the fuzzer should be + // able to try all faces and named instances of a font, expecting that + // some faces don't work for various reasons, e.g., a broken subfont, or + // an unsupported NFNT bitmap font in a Mac dfont resource that holds + // more than a single font. + + // get number of faces + if ( FT_New_Memory_Face( library, + files[0].data(), + (FT_Long)files[0].size(), + -1, + &face ) ) + return 0; + long num_faces = face->num_faces; + FT_Done_Face( face ); + + // loop over up to 20 arbitrarily selected faces + // from index range [0;num-faces-1] + long max_face_cnt = num_faces < 20 + ? num_faces + : 20; + + Random faces_pool( (int)max_face_cnt, (int)num_faces ); + + for ( long face_cnt = 0; + face_cnt < max_face_cnt; + face_cnt++ ) + { + long face_index = faces_pool.get() - 1; + + // get number of instances + if ( FT_New_Memory_Face( library, + files[0].data(), + (FT_Long)files[0].size(), + -( face_index + 1 ), + &face ) ) + continue; + long num_instances = face->style_flags >> 16; + FT_Done_Face( face ); + + // loop over the face without instance (index 0) + // and up to 20 arbitrarily selected instances + // from index range [1;num_instances] + long max_instance_cnt = num_instances < 20 + ? num_instances + : 20; + + Random instances_pool( (int)max_instance_cnt, (int)num_instances ); + + for ( long instance_cnt = 0; + instance_cnt <= max_instance_cnt; + instance_cnt++ ) + { + long instance_index = 0; + + if ( !instance_cnt ) + { + if ( FT_New_Memory_Face( library, + files[0].data(), + (FT_Long)files[0].size(), + face_index, + &face ) ) + continue; + } + else + { + instance_index = instances_pool.get(); + + if ( FT_New_Memory_Face( library, + files[0].data(), + (FT_Long)files[0].size(), + ( instance_index << 16 ) + face_index, + &face ) ) + continue; + } + + // if we have more than a single input file coming from an archive, + // attach them (starting with the second file) using the order given + // in the archive + for ( size_t files_index = 1; + files_index < files.size(); + files_index++ ) + { + FT_Open_Args open_args = {}; + open_args.flags = FT_OPEN_MEMORY; + open_args.memory_base = files[files_index].data(); + open_args.memory_size = (FT_Long)files[files_index].size(); + + // the last archive element will be eventually used as the + // attachment + FT_Attach_Stream( face, &open_args ); + } + + // loop over an arbitrary size for outlines + // and up to ten arbitrarily selected bitmap strike sizes + // from the range [0;num_fixed_sizes - 1] + int max_size_cnt = face->num_fixed_sizes < 10 + ? face->num_fixed_sizes + : 10; + + Random sizes_pool( max_size_cnt, face->num_fixed_sizes ); + + for ( int size_cnt = 0; + size_cnt <= max_size_cnt; + size_cnt++ ) + { + FT_Int32 flags = load_flags; + + int size_index = 0; + + if ( !size_cnt ) + { + // set up 20pt at 72dpi as an arbitrary size + if ( FT_Set_Char_Size( face, 20 * 64, 20 * 64, 72, 72 ) ) + continue; + flags |= FT_LOAD_NO_BITMAP; + } + else + { + // bitmap strikes are not active for font variations + if ( instance_index ) + continue; + + size_index = sizes_pool.get() - 1; + + if ( FT_Select_Size( face, size_index ) ) + continue; + flags |= FT_LOAD_COLOR; + } + + // test MM interface only for a face without a selected instance + // and without a selected bitmap strike + if ( !instance_index && !size_cnt ) + setIntermediateAxis( face ); + + // loop over all glyphs + for ( unsigned int glyph_index = 0; + glyph_index < (unsigned int)face->num_glyphs; + glyph_index++ ) + { + if ( FT_Load_Glyph( face, glyph_index, flags ) ) + continue; + + // Rendering is the most expensive and the least interesting part. + // + // if ( FT_Render_Glyph( face->glyph, render_mode) ) + // continue; + // FT_GlyphSlot_Embolden( face->glyph ); + +#if 0 + FT_Glyph glyph; + if ( !FT_Get_Glyph( face->glyph, &glyph ) ) + FT_Done_Glyph( glyph ); + + FT_Outline* outline = &face->glyph->outline; + FT_Matrix rot30 = { 0xDDB4, -0x8000, 0x8000, 0xDDB4 }; + + FT_Outline_Transform( outline, &rot30 ); + + FT_BBox bbox; + FT_Outline_Get_BBox( outline, &bbox ); +#endif + } + } + FT_Done_Face( face ); + } + } + + return 0; + } + + +// END diff --git a/src/3rdparty/freetype/src/tools/ftfuzzer/ftmutator.cc b/src/3rdparty/freetype/src/tools/ftfuzzer/ftmutator.cc new file mode 100644 index 0000000000..ae4b140404 --- /dev/null +++ b/src/3rdparty/freetype/src/tools/ftfuzzer/ftmutator.cc @@ -0,0 +1,314 @@ +// ftmutator.cc +// +// A custom fuzzer mutator to test for FreeType with libFuzzer. +// +// Copyright 2015-2018 by +// 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. + + +// Since `tar' is not a valid format for input to FreeType, treat any input +// that looks like `tar' as multiple files and mutate them separately. +// +// In the future, a variation of this may be used to guide mutation on a +// logically higher level. + + +// we use `unique_ptr', `decltype', and other gimmicks defined since C++11 +#if __cplusplus < 201103L +# error "a C++11 compiler is needed" +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "FuzzerInterface.h" + + + using namespace std; + + + // This function should be defined by `ftfuzzer.cc'. + extern "C" int + LLVMFuzzerTestOneInput( const uint8_t* Data, + size_t Size ); + + + static void + check_result( struct archive* a, + int r ) + { + if ( r == ARCHIVE_OK ) + return; + + const char* m = archive_error_string( a ); + write( 1, m, strlen( m ) ); + exit( 1 ); + } + + + static int + archive_read_entry_data( struct archive *ar, + vector *vw ) + { + int r; + const uint8_t* buff; + size_t size; + int64_t offset; + + for (;;) + { + r = archive_read_data_block( ar, + reinterpret_cast( &buff ), + &size, + &offset ); + if ( r == ARCHIVE_EOF ) + return ARCHIVE_OK; + if ( r != ARCHIVE_OK ) + return r; + + vw->insert( vw->end(), buff, buff + size ); + } + } + + + static vector> + parse_data( const uint8_t* data, + size_t size ) + { + struct archive_entry* entry; + int r; + vector> files; + + unique_ptr a( archive_read_new(), + archive_read_free ); + + // activate reading of uncompressed tar archives + archive_read_support_format_tar( a.get() ); + + // the need for `const_cast' was removed with libarchive commit be4d4dd + if ( !( r = archive_read_open_memory( + a.get(), + const_cast(static_cast( data ) ), + size ) ) ) + { + unique_ptr a_open( a.get(), + archive_read_close ); + + // read files contained in archive + for (;;) + { + r = archive_read_next_header( a_open.get(), &entry ); + if ( r == ARCHIVE_EOF ) + break; + if ( r != ARCHIVE_OK ) + break; + + vector entry_data; + r = archive_read_entry_data( a.get(), &entry_data ); + if ( entry_data.size() == 0 ) + continue; + + files.push_back( move( entry_data ) ); + if ( r != ARCHIVE_OK ) + break; + } + } + + return files; + } + + + class FTFuzzer + : public fuzzer::UserSuppliedFuzzer + { + + public: + FTFuzzer( fuzzer::FuzzerRandomBase* Rand ) + : fuzzer::UserSuppliedFuzzer( Rand ) {} + + + int + TargetFunction( const uint8_t* Data, + size_t Size ) + { + return LLVMFuzzerTestOneInput( Data, Size ); + } + + + // Custom mutator. + virtual size_t + Mutate( uint8_t* Data, + size_t Size, + size_t MaxSize ) + { + vector> files = parse_data( Data, Size ); + + // If the file was not recognized as a tar file, treat it as non-tar. + if ( files.size() == 0 ) + return fuzzer::UserSuppliedFuzzer::Mutate( Data, Size, MaxSize ); + + // This is somewhat `white box' on tar. The tar format uses 512 byte + // blocks. One block as header for each file, two empty blocks of 0's + // at the end. File data is padded to fill its last block. + size_t used_blocks = files.size() + 2; + for ( const auto& file : files ) + used_blocks += ( file.size() + 511 ) / 512; + + size_t max_blocks = MaxSize / 512; + + // If the input is big, it will need to be downsized. If the original + // tar file was too big, it may have been clipped to fit. In this + // case it may not be possible to properly write out the data, as + // there may not be enough space for the trailing two blocks. Start + // dropping file data or files from the end. + for ( size_t i = files.size(); + i-- > 1 && used_blocks > max_blocks; ) + { + size_t blocks_to_free = used_blocks - max_blocks; + size_t blocks_currently_used_by_file_data = + ( files[i].size() + 511 ) / 512; + + if ( blocks_currently_used_by_file_data >= blocks_to_free ) + { + files[i].resize( ( blocks_currently_used_by_file_data - + blocks_to_free ) * 512 ); + used_blocks -= blocks_to_free; + continue; + } + + files.pop_back(); + used_blocks -= blocks_currently_used_by_file_data + 1; + } + + // If we get down to one file, don't use tar. + if ( files.size() == 1 ) + { + memcpy( Data, files[0].data(), files[0].size() ); + return fuzzer::UserSuppliedFuzzer::Mutate( Data, + files[0].size(), + MaxSize ); + } + + size_t free_blocks = max_blocks - used_blocks; + + // Allow each file to use up as much of the currently available space + // it can. If it uses or gives up blocks, add them or remove them + // from the pool. + for ( auto&& file : files ) + { + size_t blocks_currently_used_by_file = ( file.size() + 511 ) / 512; + size_t blocks_available = blocks_currently_used_by_file + + free_blocks; + size_t max_size = blocks_available * 512; + size_t data_size = file.size(); + + file.resize( max_size ); + file.resize( fuzzer::UserSuppliedFuzzer::Mutate( file.data(), + data_size, + max_size ) ); + + size_t blocks_now_used_by_file = ( file.size() + 511 ) / 512; + free_blocks = free_blocks + + blocks_currently_used_by_file - + blocks_now_used_by_file; + } + + unique_ptr a( archive_write_new(), + archive_write_free ); + + check_result( a.get(), archive_write_add_filter_none( a.get() ) ); + check_result( a.get(), archive_write_set_format_ustar( a.get() ) ); + + // `used' may not be correct until after the archive is closed. + size_t used = 0xbadbeef; + check_result( a.get(), archive_write_open_memory( a.get(), + Data, + MaxSize, + &used ) ); + + { + unique_ptr a_open( a.get(), + archive_write_close ); + + int file_index = 0; + for ( const auto& file : files ) + { + unique_ptr + e( archive_entry_new2( a_open.get() ), + archive_entry_free ); + + char name_buffer[100]; + snprintf( name_buffer, 100, "file%d", file_index++ ); + + archive_entry_set_pathname( e.get(), name_buffer ); + archive_entry_set_size( e.get(), file.size() ); + archive_entry_set_filetype( e.get(), AE_IFREG ); + archive_entry_set_perm( e.get(), 0644 ); + + check_result( a_open.get(), + archive_write_header( a_open.get(), e.get() ) ); + archive_write_data( a_open.get(), file.data(), file.size() ); + check_result( a_open.get(), + archive_write_finish_entry( a_open.get() ) ); + } + } + + return used; + } + + + // Cross `Data1' and `Data2', write up to `MaxOutSize' bytes into `Out', + // return the number of bytes written, which should be positive. + virtual size_t + CrossOver( const uint8_t* Data1, + size_t Size1, + const uint8_t* Data2, + size_t Size2, + uint8_t* Out, + size_t MaxOutSize ) + { + return fuzzer::UserSuppliedFuzzer::CrossOver( Data1, + Size1, + Data2, + Size2, + Out, + MaxOutSize ); + } + + }; // end of FTFuzzer class + + + int + main( int argc, + char* *argv ) + { + fuzzer::FuzzerRandomLibc Rand( 0 ); + FTFuzzer F( &Rand ); + + fuzzer::FuzzerDriver( argc, argv, F ); + } + + +// END diff --git a/src/3rdparty/freetype/src/tools/ftfuzzer/rasterfuzzer.cc b/src/3rdparty/freetype/src/tools/ftfuzzer/rasterfuzzer.cc new file mode 100644 index 0000000000..c69b95ea0f --- /dev/null +++ b/src/3rdparty/freetype/src/tools/ftfuzzer/rasterfuzzer.cc @@ -0,0 +1,129 @@ +// rasterfuzzer.cc +// +// A fuzzing function to test FreeType's rasterizers with libFuzzer. +// +// Copyright 2016-2018 by +// 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. + + +#include + +#include + + + using namespace std; + + +#include + +#include FT_FREETYPE_H +#include FT_IMAGE_H +#include FT_OUTLINE_H + + + static FT_Library library; + static int InitResult; + + + struct FT_Global { + FT_Global() { + InitResult = FT_Init_FreeType( &library ); + } + ~FT_Global() { + FT_Done_FreeType( library ); + } + }; + + FT_Global global_ft; + + + extern "C" int + LLVMFuzzerTestOneInput( const uint8_t* data, + size_t size_ ) + { + unsigned char pixels[4]; + + FT_Bitmap bitmap_mono = { + 1, // rows + 1, // width + 4, // pitch + pixels, // buffer + 2, // num_grays + FT_PIXEL_MODE_MONO, // pixel_mode + 0, // palette_mode + NULL // palette + }; + + FT_Bitmap bitmap_gray = { + 1, // rows + 1, // width + 4, // pitch + pixels, // buffer + 256, // num_grays + FT_PIXEL_MODE_GRAY, // pixel_mode + 0, // palette_mode + NULL // palette + }; + + const size_t vsize = sizeof ( FT_Vector ); + const size_t tsize = sizeof ( char ); + + // we use the input data for both points and tags + short n_points = short( size_ / ( vsize + tsize ) ); + if ( n_points <= 2 ) + return 0; + + FT_Vector* points = reinterpret_cast( + const_cast( + data ) ); + char* tags = reinterpret_cast( + const_cast( + data + size_t( n_points ) * vsize ) ); + + // to reduce the number of invalid outlines that are immediately + // rejected in `FT_Outline_Render', limit values to 2^18 pixels + // (i.e., 2^24 bits) + for ( short i = 0; i < n_points; i++ ) + { + if ( points[i].x == LONG_MIN ) + points[i].x = 0; + else if ( points[i].x < 0 ) + points[i].x = -( -points[i].x & 0xFFFFFF ) - 1; + else + points[i].x = ( points[i].x & 0xFFFFFF ) + 1; + + if ( points[i].y == LONG_MIN ) + points[i].y = 0; + else if ( points[i].y < 0 ) + points[i].y = -( -points[i].y & 0xFFFFFF ) - 1; + else + points[i].y = ( points[i].y & 0xFFFFFF ) + 1; + } + + short contours[1]; + contours[0] = n_points - 1; + + FT_Outline outline = + { + 1, // n_contours + n_points, // n_points + points, // points + tags, // tags + contours, // contours + FT_OUTLINE_NONE // flags + }; + + FT_Outline_Get_Bitmap( library, &outline, &bitmap_mono ); + FT_Outline_Get_Bitmap( library, &outline, &bitmap_gray ); + + return 0; + } + + +// END diff --git a/src/3rdparty/freetype/src/tools/ftfuzzer/runinput.cc b/src/3rdparty/freetype/src/tools/ftfuzzer/runinput.cc new file mode 100644 index 0000000000..2b02f57580 --- /dev/null +++ b/src/3rdparty/freetype/src/tools/ftfuzzer/runinput.cc @@ -0,0 +1,58 @@ +// runinput.cc +// +// A `main' function for fuzzers like `ftfuzzer.cc'. +// +// Copyright 2015-2018 by +// 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. + + +#include +#include +#include +#include +#include + + + extern "C" void + LLVMFuzzerTestOneInput( const uint8_t* data, + size_t size ); + + + unsigned char a[1 << 24]; + + + int + main( int argc, + char* *argv ) + { + assert( argc >= 2 ); + + for ( int i = 1; i < argc; i++ ) + { + fprintf( stderr, "%s\n", argv[i] ); + + FILE* f = fopen( argv[i], "r" ); + assert( f ); + + size_t n = fread( a, 1, sizeof ( a ), f ); + fclose( f ); + if ( !n ) + continue; + + unsigned char* b = (unsigned char*)malloc( n ); + memcpy( b, a, n ); + + LLVMFuzzerTestOneInput( b, n ); + + free( b ); + } + } + + +// END diff --git a/src/3rdparty/freetype/src/tools/ftrandom/Makefile b/src/3rdparty/freetype/src/tools/ftrandom/Makefile index 2e619299cd..24dc49c563 100644 --- a/src/3rdparty/freetype/src/tools/ftrandom/Makefile +++ b/src/3rdparty/freetype/src/tools/ftrandom/Makefile @@ -5,7 +5,12 @@ TOP_DIR ?= ../../.. OBJ_DIR ?= $(TOP_DIR)/objs -# The setup below is for gcc on a Unix-like platform. +# The setup below is for gcc on a Unix-like platform, +# where FreeType has been set up to create a static library +# (which is the default). + +VPATH = $(OBJ_DIR) \ + $(OBJ_DIR)/.libs SRC_DIR = $(TOP_DIR)/src/tools/ftrandom @@ -20,16 +25,21 @@ WFLAGS = -Wmissing-prototypes \ -Wchar-subscripts \ -Wsequence-point CFLAGS = $(WFLAGS) \ - -g \ - -I $(TOP_DIR)/include + -g +INCLUDES = -I $(TOP_DIR)/include +LDFLAGS = LIBS = -lm \ - -L $(OBJ_DIR) \ - -lfreetype \ - -lz + -lz \ + -lpng \ + -lbz2 \ + -lharfbuzz all: $(OBJ_DIR)/ftrandom -$(OBJ_DIR)/ftrandom: $(SRC_DIR)/ftrandom.c $(OBJ_DIR)/libfreetype.a - $(CC) -o $(OBJ_DIR)/ftrandom $(CFLAGS) $(SRC_DIR)/ftrandom.c $(LIBS) +$(OBJ_DIR)/ftrandom.o: $(SRC_DIR)/ftrandom.c + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $< + +$(OBJ_DIR)/ftrandom: $(OBJ_DIR)/ftrandom.o libfreetype.a + $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) # EOF diff --git a/src/3rdparty/freetype/src/tools/ftrandom/README b/src/3rdparty/freetype/src/tools/ftrandom/README index 71bf05323d..7c610864b6 100644 --- a/src/3rdparty/freetype/src/tools/ftrandom/README +++ b/src/3rdparty/freetype/src/tools/ftrandom/README @@ -1,48 +1,69 @@ ftrandom --------- +======== This program expects a set of directories containing good fonts, and a set of extensions of fonts to be tested. It will randomly pick a font, copy it, -introduce and error and then test it. +introduce an error and then test it. -The FreeType tests are quite basic: +The FreeType tests are quite basic; for each erroneous font ftrandom - For each erroneous font it - forks off a new tester; - initializes the library; - opens each font in the file; - loads each glyph; - (optionally reviewing the contours of the glyph) - (optionally rasterizing) - closes the face. + . forks off a new tester, + . initializes the library, + . opens each font in the file, + . loads each glyph, + . optionally reviews the contours of the glyph, + . optionally rasterizes the glyph, and + . closes the face. -If the tester exits with a signal, or takes longer than 20 seconds then -ftrandom saves the erroneous font and continues. If the tester exits -normally or with an error, then the superstructure removes the test font and -continues. +If a tester takes longer than 20 seconds, ftrandom saves the erroneous font +and continues. If the tester exits normally or with an error, then the +superstructure removes the test font and continues. -Arguments are: + +Command line options +-------------------- --all Test every font in the directory(ies) no matter - what its extension (some CID-keyed fonts have no - extension). - --check-outlines Call FT_Outline_Decompose on each glyph. + what its extension. + --check-outlines Call `FT_Outline_Decompose' on each glyph. --dir Append to the list of directories to search - for good fonts. + for good fonts. No recursive search. --error-count Introduce single-byte errors into the - erroneous fonts. + erroneous fonts (default: 1). --error-fraction Multiply the file size of the font by and introduce that many errors into the erroneous - font file. - --ext Add to the set of font types tested. Known - extensions are `ttf', `otf', `ttc', `cid', `pfb', - `pfa', `bdf', `pcf', `pfr', `fon', `otb', and - `cff'. + font file. should be in the range [0;1] + (default: 0.0). + --ext Add to the set of font types tested. --help Print out this list of options. --nohints Specify FT_LOAD_NO_HINTING when loading glyphs. - --rasterize Call FT_Render_Glyph as well as loading it. + --rasterize Call `FT_Render_Glyph' as well as loading it. --result This is the directory in which test files are placed. --test Run a single test on a pre-generated testcase. - Done in the current process so it can be debugged - more easily. + This is done in the current process so it can be + debugged more easily. + +The default font extensions tested by ftrandom are + + .ttf .otf .ttc .cid .pfb .pfa .bdf .pcf .pfr .fon .otb .cff + +The default font directory is controlled by the macro `GOOD_FONTS_DIR' in +the source code (and can be thus specified during compilation); its default +value is + + /usr/local/share/fonts + +The default result directory is `results' (in the current directory). + + +Compilation +----------- + +Two possible solutions. + +. Run ftrandom within a debugging tool like `valgrind' to catch various + memory issues. + +. Compile FreeType with sanitizer flags as provided by gcc or clang, for + example, then link it with ftrandom. diff --git a/src/3rdparty/freetype/src/tools/ftrandom/ftrandom.c b/src/3rdparty/freetype/src/tools/ftrandom/ftrandom.c index 9a5b632673..ab5cfc98b6 100644 --- a/src/3rdparty/freetype/src/tools/ftrandom/ftrandom.c +++ b/src/3rdparty/freetype/src/tools/ftrandom/ftrandom.c @@ -29,6 +29,9 @@ /* This file is now part of the FreeType library */ +#define _XOPEN_SOURCE 500 /* for `kill', `strdup', `random', and `srandom' */ + + #include #include #include @@ -38,7 +41,6 @@ #include #include #include -#include #include #include @@ -56,7 +58,7 @@ static int rasterize = false; static char* results_dir = "results"; -#define GOOD_FONTS_DIR "/home/wl/freetype-testfonts" +#define GOOD_FONTS_DIR "/usr/local/share/fonts" static char* default_dir_list[] = { @@ -81,28 +83,31 @@ NULL }; - static int error_count = 1; - static int error_fraction = 0; + static unsigned int error_count = 1; + static double error_fraction = 0.0; static FT_F26Dot6 font_size = 12 * 64; static struct fontlist { char* name; - int len; + long len; unsigned int isbinary: 1; unsigned int isascii: 1; unsigned int ishex: 1; } *fontlist; - static int fcnt; + static unsigned int fcnt; static int FT_MoveTo( const FT_Vector *to, void *user ) { + FT_UNUSED( to ); + FT_UNUSED( user ); + return 0; } @@ -111,6 +116,9 @@ FT_LineTo( const FT_Vector *to, void *user ) { + FT_UNUSED( to ); + FT_UNUSED( user ); + return 0; } @@ -120,6 +128,10 @@ const FT_Vector *to, void *user ) { + FT_UNUSED( _cp ); + FT_UNUSED( to ); + FT_UNUSED( user ); + return 0; } @@ -130,6 +142,11 @@ const FT_Vector *to, void *user ) { + FT_UNUSED( cp1 ); + FT_UNUSED( cp2 ); + FT_UNUSED( to ); + FT_UNUSED( user ); + return 0; } @@ -147,8 +164,8 @@ static void TestFace( FT_Face face ) { - int gid; - int load_flags = FT_LOAD_DEFAULT; + unsigned int gid; + int load_flags = FT_LOAD_DEFAULT; if ( check_outlines && @@ -160,7 +177,7 @@ FT_Set_Char_Size( face, 0, font_size, 72, 72 ); - for ( gid = 0; gid < face->num_glyphs; ++gid ) + for ( gid = 0; gid < face->num_glyphs; gid++ ) { if ( check_outlines && FT_IS_SCALABLE( face ) ) @@ -202,19 +219,21 @@ TestFace( face ); else { - int i, num; + long i, num; num = face->num_faces; FT_Done_Face( face ); - for ( i = 0; i < num; ++i ) + for ( i = 0; i < num; i++ ) { if ( !FT_New_Face( context, testfont, i, &face ) ) TestFace( face ); } } + FT_Done_FreeType( context ); + exit( 0 ); } @@ -227,16 +246,16 @@ char* pt; - if ( extensions == NULL ) + if ( !extensions ) return true; pt = strrchr( filename, '.' ); - if ( pt == NULL ) + if ( !pt ) return false; if ( pt < strrchr( filename, '/' ) ) return false; - for ( i = 0; extensions[i] != NULL; ++i ) + for ( i = 0; extensions[i] != NULL; i++ ) if ( strcasecmp( pt + 1, extensions[i] ) == 0 || strcasecmp( pt, extensions[i] ) == 0 ) return true; @@ -254,7 +273,7 @@ item->isbinary = item->isascii = item->ishex = false; foo = fopen( item->name, "rb" ); - if ( foo != NULL ) + if ( foo ) { /* Try to guess the file type from the first few characters... */ int ch1 = getc( foo ); @@ -281,8 +300,8 @@ else if ( ch1 == '%' && ch2 == '!' ) { /* Random PostScript */ - if ( strstr( item->name, ".pfa" ) != NULL || - strstr( item->name, ".PFA" ) != NULL ) + if ( strstr( item->name, ".pfa" ) || + strstr( item->name, ".PFA" ) ) item->ishex = true; else item->isascii = true; @@ -329,22 +348,23 @@ FindFonts( char** fontdirs, char** extensions ) { - int i, max; - char buffer[1025]; - struct stat statb; + int i; + unsigned int max; + char buffer[1025]; + struct stat statb; max = 0; fcnt = 0; - for ( i = 0; fontdirs[i] != NULL; ++i ) + for ( i = 0; fontdirs[i] != NULL; i++ ) { DIR* examples; struct dirent* ent; examples = opendir( fontdirs[i] ); - if ( examples == NULL ) + if ( !examples ) { fprintf( stderr, "Can't open example font directory `%s'\n", @@ -358,13 +378,13 @@ "%s/%s", fontdirs[i], ent->d_name ); if ( stat( buffer, &statb ) == -1 || S_ISDIR( statb.st_mode ) ) continue; - if ( extensions == NULL || extmatch( buffer, extensions ) ) + if ( !extensions || extmatch( buffer, extensions ) ) { if ( fcnt >= max ) { max += 100; fontlist = realloc( fontlist, max * sizeof ( struct fontlist ) ); - if ( fontlist == NULL ) + if ( !fontlist ) { fprintf( stderr, "Can't allocate memory\n" ); exit( 1 ); @@ -375,7 +395,7 @@ fontlist[fcnt].len = statb.st_size; figurefiletype( &fontlist[fcnt] ); - ++fcnt; + fcnt++; } } @@ -392,13 +412,13 @@ } - static int + static unsigned int getErrorCnt( struct fontlist* item ) { - if ( error_count == 0 && error_fraction == 0 ) + if ( error_count == 0 && error_fraction == 0.0 ) return 0; - return error_count + ceil( error_fraction * item->len ); + return error_count + (unsigned int)( error_fraction * item->len ); } @@ -417,21 +437,21 @@ copyfont( struct fontlist* item, char* newfont ) { - static char buffer[8096]; - FILE *good, *new; - int len; - int i, err_cnt; + static char buffer[8096]; + FILE *good, *newf; + size_t len; + unsigned int i, err_cnt; good = fopen( item->name, "r" ); - if ( good == NULL ) + if ( !good ) { fprintf( stderr, "Can't open `%s'\n", item->name ); return false; } - new = fopen( newfont, "w+" ); - if ( new == NULL ) + newf = fopen( newfont, "w+" ); + if ( !newf ) { fprintf( stderr, "Can't create temporary output file `%s'\n", newfont ); @@ -439,19 +459,19 @@ } while ( ( len = fread( buffer, 1, sizeof ( buffer ), good ) ) > 0 ) - fwrite( buffer, 1, len, new ); + fwrite( buffer, 1, len, newf ); fclose( good ); err_cnt = getErrorCnt( item ); - for ( i = 0; i < err_cnt; ++i ) + for ( i = 0; i < err_cnt; i++ ) { - fseek( new, getRandom( 0, item->len - 1 ), SEEK_SET ); + fseek( newf, getRandom( 0, (int)( item->len - 1 ) ), SEEK_SET ); if ( item->isbinary ) - putc( getRandom( 0, 0xFF ), new ); + putc( getRandom( 0, 0xFF ), newf ); else if ( item->isascii ) - putc( getRandom( 0x20, 0x7E ), new ); + putc( getRandom( 0x20, 0x7E ), newf ); else { int hex = getRandom( 0, 15 ); @@ -462,18 +482,18 @@ else hex += 'A' - 10; - putc( hex, new ); + putc( hex, newf ); } } - if ( ferror( new ) ) + if ( ferror( newf ) ) { - fclose( new ); + fclose( newf ); unlink( newfont ); return false; } - fclose( new ); + fclose( newf ); return true; } @@ -484,6 +504,8 @@ static void abort_test( int sig ) { + FT_UNUSED( sig ); + /* If a time-out happens, then kill the child */ kill( child_pid, SIGFPE ); write( 2, "Timeout... ", 11 ); @@ -493,7 +515,7 @@ static void do_test( void ) { - int i = getRandom( 0, fcnt - 1 ); + int i = getRandom( 0, (int)( fcnt - 1 ) ); static int test_num = 0; char buffer[1024]; @@ -534,22 +556,42 @@ usage( FILE* out, char* name ) { + char** d = default_dir_list; + char** e = default_ext_list; + + fprintf( out, "%s [options] -- Generate random erroneous fonts\n" " and attempt to parse them with FreeType.\n\n", name ); fprintf( out, " --all All non-directory files are assumed to be fonts.\n" ); fprintf( out, " --check-outlines Make sure we can parse the outlines of each glyph.\n" ); - fprintf( out, " --dir Append to list of font search directories.\n" ); - fprintf( out, " --error-count Introduce single byte errors into each font.\n" ); + fprintf( out, " --dir Append to list of font search directories\n" + " (no recursive search).\n" ); + fprintf( out, " --error-count Introduce single byte errors into each font\n" + " (default: 1)\n" ); fprintf( out, " --error-fraction Introduce *filesize single byte errors\n" - " into each font.\n" ); + " into each font (default: 0.0).\n" ); fprintf( out, " --ext Add to list of extensions indicating fonts.\n" ); fprintf( out, " --help Print this.\n" ); fprintf( out, " --nohints Turn off hinting.\n" ); fprintf( out, " --rasterize Attempt to rasterize each glyph.\n" ); - fprintf( out, " --results Directory in which to place the test fonts.\n" ); + fprintf( out, " --results Place the created test fonts into \n" + " (default: `results')\n" ); fprintf( out, " --size Use the given font size for the tests.\n" ); fprintf( out, " --test Run a single test on an already existing file.\n" ); + fprintf( out, "\n" ); + + fprintf( out, "Default font extensions:\n" ); + fprintf( out, " " ); + while ( *e ) + fprintf( out, " .%s", *e++ ); + fprintf( out, "\n" ); + + fprintf( out, "Default font directories:\n" ); + fprintf( out, " " ); + while ( *d ) + fprintf( out, " %s", *d++ ); + fprintf( out, "\n" ); } @@ -564,17 +606,17 @@ char* testfile = NULL; - dirs = calloc( argc + 1, sizeof ( char ** ) ); - exts = calloc( argc + 1, sizeof ( char ** ) ); + dirs = calloc( (size_t)( argc + 1 ), sizeof ( char ** ) ); + exts = calloc( (size_t)( argc + 1 ), sizeof ( char ** ) ); - for ( i = 1; i < argc; ++i ) + for ( i = 1; i < argc; i++ ) { char* pt = argv[i]; char* end; if ( pt[0] == '-' && pt[1] == '-' ) - ++pt; + pt++; if ( strcmp( pt, "-all" ) == 0 ) allexts = true; @@ -585,9 +627,9 @@ else if ( strcmp( pt, "-error-count" ) == 0 ) { if ( !rset ) - error_fraction = 0; + error_fraction = 0.0; rset = true; - error_count = strtol( argv[++i], &end, 10 ); + error_count = (unsigned int)strtoul( argv[++i], &end, 10 ); if ( *end != '\0' ) { fprintf( stderr, "Bad value for error-count: %s\n", argv[i] ); @@ -605,6 +647,11 @@ fprintf( stderr, "Bad value for error-fraction: %s\n", argv[i] ); exit( 1 ); } + if ( error_fraction < 0.0 || error_fraction > 1.0 ) + { + fprintf( stderr, "error-fraction must be in the range [0;1]\n" ); + exit( 1 ); + } } else if ( strcmp( pt, "-ext" ) == 0 ) exts[ecnt++] = argv[++i]; @@ -654,11 +701,11 @@ dirs = default_dir_list; } - if ( testfile != NULL ) + if ( testfile ) ExecuteTest( testfile ); /* This should never return */ time( &now ); - srandom( now ); + srandom( (unsigned int)now ); FindFonts( dirs, exts ); mkdir( results_dir, 0755 ); diff --git a/src/3rdparty/freetype/src/tools/glnames.py b/src/3rdparty/freetype/src/tools/glnames.py index 0ad554c72d..b048d29364 100644 --- a/src/3rdparty/freetype/src/tools/glnames.py +++ b/src/3rdparty/freetype/src/tools/glnames.py @@ -6,7 +6,7 @@ # -# Copyright 1996-2015 by +# Copyright 1996-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -151,7 +151,7 @@ mac_standard_names = \ # The list of standard `SID' glyph names. For the official list, # see Annex A of document at # -# http://partners.adobe.com/public/developer/en/font/5176.CFF.pdf . +# https://www.adobe.com/content/dam/acom/en/devnet/font/pdfs/5176.CFF.pdf . # sid_standard_names = \ [ @@ -415,7 +415,7 @@ t1_expert_encoding = \ # This data has been taken literally from the files `glyphlist.txt' # and `zapfdingbats.txt' version 2.0, Sept 2002. It is available from # -# http://sourceforge.net/adobe/aglfn/ +# https://github.com/adobe-type-tools/agl-aglfn # adobe_glyph_list = """\ A;0041 @@ -4920,8 +4920,17 @@ class StringTable: def dump( self, file ): write = file.write - write( " static const char " + self.master_table + - "[" + repr( self.total ) + "] =\n" ) + write( "#ifndef DEFINE_PS_TABLES_DATA\n" ) + write( "#ifdef __cplusplus\n" ) + write( ' extern "C"\n' ) + write( "#else\n" ) + write( " extern\n" ) + write( "#endif\n" ) + write( "#endif\n" ) + write( " const char " + self.master_table + + "[" + repr( self.total ) + "]\n" ) + write( "#ifdef DEFINE_PS_TABLES_DATA\n" ) + write( " =\n" ) write( " {\n" ) line = "" @@ -4930,7 +4939,10 @@ class StringTable: line += string.join( ( re.findall( ".", name ) ), "','" ) line += "', 0,\n" - write( line + " };\n\n\n" ) + write( line ) + write( " }\n" ) + write( "#endif /* DEFINE_PS_TABLES_DATA */\n" ) + write( " ;\n\n\n" ) def dump_sublist( self, file, table_name, macro_name, sublist ): write = file.write @@ -4938,8 +4950,17 @@ class StringTable: write( " /* Values are offsets into the `" + self.master_table + "' table */\n\n" ) - write( " static const short " + table_name + - "[" + macro_name + "] =\n" ) + write( "#ifndef DEFINE_PS_TABLES_DATA\n" ) + write( "#ifdef __cplusplus\n" ) + write( ' extern "C"\n' ) + write( "#else\n" ) + write( " extern\n" ) + write( "#endif\n" ) + write( "#endif\n" ) + write( " const short " + table_name + + "[" + macro_name + "]\n" ) + write( "#ifdef DEFINE_PS_TABLES_DATA\n" ) + write( " =\n" ) write( " {\n" ) line = " " @@ -4955,7 +4976,11 @@ class StringTable: col = 0 comma = ",\n " - write( line + "\n };\n\n\n" ) + write( line ) + write( "\n" ) + write( " }\n" ) + write( "#endif /* DEFINE_PS_TABLES_DATA */\n" ) + write( " ;\n\n\n" ) # We now store the Adobe Glyph List in compressed form. The list is put @@ -5188,8 +5213,17 @@ def dump_encoding( file, encoding_name, encoding_list ): write = file.write write( " /* the following are indices into the SID name table */\n" ) - write( " static const unsigned short " + encoding_name + - "[" + repr( len( encoding_list ) ) + "] =\n" ) + write( "#ifndef DEFINE_PS_TABLES_DATA\n" ) + write( "#ifdef __cplusplus\n" ) + write( ' extern "C"\n' ) + write( "#else\n" ) + write( " extern\n" ) + write( "#endif\n" ) + write( "#endif\n" ) + write( " const unsigned short " + encoding_name + + "[" + repr( len( encoding_list ) ) + "]\n" ) + write( "#ifdef DEFINE_PS_TABLES_DATA\n" ) + write( " =\n" ) write( " {\n" ) line = " " @@ -5204,14 +5238,27 @@ def dump_encoding( file, encoding_name, encoding_list ): col = 0 comma = ",\n " - write( line + "\n };\n\n\n" ) + write( line ) + write( "\n" ) + write( " }\n" ) + write( "#endif /* DEFINE_PS_TABLES_DATA */\n" ) + write( " ;\n\n\n" ) def dump_array( the_array, write, array_name ): """dumps a given encoding""" - write( " static const unsigned char " + array_name + - "[" + repr( len( the_array ) ) + "L] =\n" ) + write( "#ifndef DEFINE_PS_TABLES_DATA\n" ) + write( "#ifdef __cplusplus\n" ) + write( ' extern "C"\n' ) + write( "#else\n" ) + write( " extern\n" ) + write( "#endif\n" ) + write( "#endif\n" ) + write( " const unsigned char " + array_name + + "[" + repr( len( the_array ) ) + "L]\n" ) + write( "#ifdef DEFINE_PS_TABLES_DATA\n" ) + write( " =\n" ) write( " {\n" ) line = "" @@ -5232,7 +5279,11 @@ def dump_array( the_array, write, array_name ): write( line ) line = "" - write( line + "\n };\n\n\n" ) + write( line ) + write( "\n" ) + write( " }\n" ) + write( "#endif /* DEFINE_PS_TABLES_DATA */\n" ) + write( " ;\n\n\n" ) def main(): @@ -5242,7 +5293,7 @@ def main(): print __doc__ % sys.argv[0] sys.exit( 1 ) - file = open( sys.argv[1], "w\n" ) + file = open( sys.argv[1], "wb" ) write = file.write count_sid = len( sid_standard_names ) @@ -5267,7 +5318,7 @@ def main(): write( "/* */\n" ) write( "/* PostScript glyph names. */\n" ) write( "/* */\n" ) - write( "/* Copyright 2005-2015 by */\n" ) + write( "/* Copyright 2005-2018 by */\n" ) write( "/* David Turner, Robert Wilhelm, and Werner Lemberg. */\n" ) write( "/* */\n" ) write( "/* This file is part of the FreeType project, and may only be used, */\n" ) @@ -5327,6 +5378,7 @@ def main(): # write the lookup routine now # write( """\ +#ifdef DEFINE_PS_TABLES /* * This function searches the compressed table efficiently. */ @@ -5421,6 +5473,7 @@ def main(): NotFound: return 0; } +#endif /* DEFINE_PS_TABLES */ #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ diff --git a/src/3rdparty/freetype/src/tools/no-copyright b/src/3rdparty/freetype/src/tools/no-copyright index 5011e3fb62..d639aa4a84 100644 --- a/src/3rdparty/freetype/src/tools/no-copyright +++ b/src/3rdparty/freetype/src/tools/no-copyright @@ -14,6 +14,9 @@ builds/unix/pkg.m4 docs/FTL.TXT docs/GPLv2.TXT # +include/freetype/internal/fthash.h +# +src/base/fthash.c src/base/md5.c src/base/md5.h # @@ -56,6 +59,7 @@ src/gzip/zlib.h src/gzip/zutil.c src/gzip/zutil.h # +src/tools/apinames.c src/tools/ftrandom/ftrandom.c # # EOF diff --git a/src/3rdparty/freetype/src/tools/update-copyright-year b/src/3rdparty/freetype/src/tools/update-copyright-year index 107754183d..934f11cf02 100644 --- a/src/3rdparty/freetype/src/tools/update-copyright-year +++ b/src/3rdparty/freetype/src/tools/update-copyright-year @@ -2,7 +2,7 @@ eval '(exit $?0)' && eval 'exec perl -wS -i "$0" ${1+"$@"}' & eval 'exec perl -wS -i "$0" $argv:q' if 0; -# Copyright 2015 by +# Copyright 2015-2018 by # Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, -- cgit v1.2.3