ref: 154832d466ecca1b473816a0c5422d526180c420
parent: 14032290bf9f22afe4cb1cbbc8cfa2ee85a44aee
author: Armin Hasitzka <[email protected]>
date: Fri Jul 20 15:32:13 EDT 2018
Move the legacy fuzz target to the `freetype-testing' repository. It can now be found at https://github.com/freetype/freetype2-testing/tree/master/fuzzing/src/legacy * src/tools/ftfuzzer: Remove this folder and its contents from the repository.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2018-07-20 Armin Hasitzka <[email protected]>
+
+ Move the legacy fuzz target to the `freetype-testing' repository.
+
+ It can now be found at
+
+ https://github.com/freetype/freetype2-testing/tree/master/fuzzing/src/legacy
+
+ * src/tools/ftfuzzer: Remove this folder and its contents from the
+ repository.
+
2018-07-20 Werner Lemberg <[email protected]>
[cff] Avoid left-shift of negative numbers (#54322).
--- a/src/tools/ftfuzzer/README
+++ /dev/null
@@ -1,81 +1,0 @@
-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 ---
--- a/src/tools/ftfuzzer/ftfuzzer.cc
+++ /dev/null
@@ -1,428 +1,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
--- a/src/tools/ftfuzzer/ftmutator.cc
+++ /dev/null
@@ -1,314 +1,0 @@
-// 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 <cstdint>
-#include <cassert>
-#include <cstdio>
-#include <cstdlib>
-#include <cstddef>
-#include <cstring>
-#include <iostream>
-
-#include <memory>
-#include <vector>
-
-#include <archive.h>
-#include <archive_entry.h>
-
-#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<uint8_t> *vw )
- {
- int r;
- const uint8_t* 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<uint8_t>>
- parse_data( const uint8_t* data,
- size_t size )
- {
- struct archive_entry* entry;
- int r;
- vector<vector<uint8_t>> 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<uint8_t> 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<vector<uint8_t>> 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<struct archive,
- decltype ( archive_write_free )*> 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<struct archive,
- decltype ( archive_write_close )*> a_open( a.get(),
- archive_write_close );
-
- int file_index = 0;
- for ( const auto& file : files )
- {
- unique_ptr<struct archive_entry,
- decltype ( archive_entry_free )*>
- 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
--- a/src/tools/ftfuzzer/rasterfuzzer.cc
+++ /dev/null
@@ -1,129 +1,0 @@
-// 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 <stdint.h>
-
-#include <vector>
-
-
- using namespace std;
-
-
-#include <ft2build.h>
-
-#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<FT_Vector*>(
- const_cast<uint8_t*>(
- data ) );
- char* tags = reinterpret_cast<char*>(
- const_cast<uint8_t*>(
- 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
--- a/src/tools/ftfuzzer/runinput.cc
+++ /dev/null
@@ -1,58 +1,0 @@
-// 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 <assert.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-
- 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