Home | History | Annotate | Download | only in ftfuzzer
      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