// ftfuzzer.cc
//
//   A fuzzing function to test FreeType with libFuzzer.
//
// Copyright 2015-2017 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_CFF_DRIVER_H
#include FT_TRUETYPE_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_CFF_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( max_face_cnt, 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( max_instance_cnt, 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
