Commit dde84f2539b4244cf3e636bce6f20e38bd390f98

Kostya Serebryany 2015-10-07T22:18:22

[ftfuzzer] Add support for LLVM's LibFuzzer. * src/tools/ftfuzzer/ftfuzzer.cc, src/tools/runinput.cc: New files.

diff --git a/ChangeLog b/ChangeLog
index f076420..5286ee8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2015-10-07  Kostya Serebryany  <kcc@google.com>
+
+	[ftfuzzer] Add support for LLVM's LibFuzzer.
+
+	* src/tools/ftfuzzer/ftfuzzer.cc, src/tools/runinput.cc: New files.
+
 2015-10-01  Alexei Podtelezhnikov  <apodtele@gmail.com>
 
 	[smooth] Faster alternative line renderer.
diff --git a/src/tools/ftfuzzer/ftfuzzer.cc b/src/tools/ftfuzzer/ftfuzzer.cc
new file mode 100644
index 0000000..7b71973
--- /dev/null
+++ b/src/tools/ftfuzzer/ftfuzzer.cc
@@ -0,0 +1,79 @@
+#include <assert.h>
+#include <stdint.h>
+
+#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_CFF_DRIVER_H
+#include FT_TRUETYPE_DRIVER_H
+
+
+  static FT_Library  library;
+  static int         InitResult = FT_Init_FreeType( &library );
+
+
+  extern "C" int
+  LLVMFuzzerTestOneInput( const uint8_t*  data,
+                          size_t          size )
+  {
+    assert( !InitResult );
+
+    if ( size < 1 )
+      return 0;
+
+    FT_Face         face;
+    FT_Int32        load_flags  = FT_LOAD_DEFAULT;
+    FT_Render_Mode  render_mode = FT_RENDER_MODE_NORMAL;
+
+    if ( !FT_New_Memory_Face( library, data, size, 0, &face ) )
+    {
+      unsigned int  first_index = 0;
+
+      for ( unsigned i = first_index;
+            i < (unsigned int)face->num_glyphs;
+            i++ )
+      {
+        if ( FT_Load_Glyph( face, i, load_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/tools/ftfuzzer/runinput.cc b/src/tools/ftfuzzer/runinput.cc
new file mode 100644
index 0000000..9de6fb6
--- /dev/null
+++ b/src/tools/ftfuzzer/runinput.cc
@@ -0,0 +1,44 @@
+#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 */