diff options
Diffstat (limited to 'src/3rdparty/freetype/src/tools/ftfuzzer/ftfuzzer.cc')
-rw-r--r-- | src/3rdparty/freetype/src/tools/ftfuzzer/ftfuzzer.cc | 428 |
1 files changed, 0 insertions, 428 deletions
diff --git a/src/3rdparty/freetype/src/tools/ftfuzzer/ftfuzzer.cc b/src/3rdparty/freetype/src/tools/ftfuzzer/ftfuzzer.cc deleted file mode 100644 index acf2bc9820..0000000000 --- a/src/3rdparty/freetype/src/tools/ftfuzzer/ftfuzzer.cc +++ /dev/null @@ -1,428 +0,0 @@ -// 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 <archive.h> -#include <archive_entry.h> - -#include <assert.h> -#include <stdint.h> - -#include <memory> -#include <vector> - - - using namespace std; - - -#include <ft2build.h> - -#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<FT_Byte> *vw ) - { - int r; - const FT_Byte* buff; - size_t size; - int64_t offset; - - for (;;) - { - r = archive_read_data_block( ar, - reinterpret_cast<const void**>( &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<vector<FT_Byte>> - parse_data( const uint8_t* data, - size_t size ) - { - struct archive_entry* entry; - int r; - vector<vector<FT_Byte>> files; - - unique_ptr<struct archive, - decltype ( archive_read_free )*> 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<void*>(static_cast<const void*>( data ) ), - size ) ) ) - { - unique_ptr<struct archive, - decltype ( archive_read_close )*> 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<FT_Byte> 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<FT_MM_Var, - decltype ( free )*> variations( variations_ptr, free ); - vector<FT_Fixed> 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<vector<FT_Byte>>& 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 |