1 // rasterfuzzer.cc 2 // 3 // A fuzzing function to test FreeType's rasterizers with libFuzzer. 4 // 5 // Copyright 2016-2018 by 6 // David Turner, Robert Wilhelm, and Werner Lemberg. 7 // 8 // This file is part of the FreeType project, and may only be used, 9 // modified, and distributed under the terms of the FreeType project 10 // license, LICENSE.TXT. By continuing to use, modify, or distribute 11 // this file you indicate that you have read the license and 12 // understand and accept it fully. 13 14 15 #include <stdint.h> 16 17 #include <vector> 18 19 20 using namespace std; 21 22 23 #include <ft2build.h> 24 25 #include FT_FREETYPE_H 26 #include FT_IMAGE_H 27 #include FT_OUTLINE_H 28 29 30 static FT_Library library; 31 static int InitResult; 32 33 34 struct FT_Global { 35 FT_Global() { 36 InitResult = FT_Init_FreeType( &library ); 37 } 38 ~FT_Global() { 39 FT_Done_FreeType( library ); 40 } 41 }; 42 43 FT_Global global_ft; 44 45 46 extern "C" int 47 LLVMFuzzerTestOneInput( const uint8_t* data, 48 size_t size_ ) 49 { 50 unsigned char pixels[4]; 51 52 FT_Bitmap bitmap_mono = { 53 1, // rows 54 1, // width 55 4, // pitch 56 pixels, // buffer 57 2, // num_grays 58 FT_PIXEL_MODE_MONO, // pixel_mode 59 0, // palette_mode 60 NULL // palette 61 }; 62 63 FT_Bitmap bitmap_gray = { 64 1, // rows 65 1, // width 66 4, // pitch 67 pixels, // buffer 68 256, // num_grays 69 FT_PIXEL_MODE_GRAY, // pixel_mode 70 0, // palette_mode 71 NULL // palette 72 }; 73 74 const size_t vsize = sizeof ( FT_Vector ); 75 const size_t tsize = sizeof ( char ); 76 77 // we use the input data for both points and tags 78 short n_points = short( size_ / ( vsize + tsize ) ); 79 if ( n_points <= 2 ) 80 return 0; 81 82 FT_Vector* points = reinterpret_cast<FT_Vector*>( 83 const_cast<uint8_t*>( 84 data ) ); 85 char* tags = reinterpret_cast<char*>( 86 const_cast<uint8_t*>( 87 data + size_t( n_points ) * vsize ) ); 88 89 // to reduce the number of invalid outlines that are immediately 90 // rejected in `FT_Outline_Render', limit values to 2^18 pixels 91 // (i.e., 2^24 bits) 92 for ( short i = 0; i < n_points; i++ ) 93 { 94 if ( points[i].x == LONG_MIN ) 95 points[i].x = 0; 96 else if ( points[i].x < 0 ) 97 points[i].x = -( -points[i].x & 0xFFFFFF ) - 1; 98 else 99 points[i].x = ( points[i].x & 0xFFFFFF ) + 1; 100 101 if ( points[i].y == LONG_MIN ) 102 points[i].y = 0; 103 else if ( points[i].y < 0 ) 104 points[i].y = -( -points[i].y & 0xFFFFFF ) - 1; 105 else 106 points[i].y = ( points[i].y & 0xFFFFFF ) + 1; 107 } 108 109 short contours[1]; 110 contours[0] = n_points - 1; 111 112 FT_Outline outline = 113 { 114 1, // n_contours 115 n_points, // n_points 116 points, // points 117 tags, // tags 118 contours, // contours 119 FT_OUTLINE_NONE // flags 120 }; 121 122 FT_Outline_Get_Bitmap( library, &outline, &bitmap_mono ); 123 FT_Outline_Get_Bitmap( library, &outline, &bitmap_gray ); 124 125 return 0; 126 } 127 128 129 // END 130