hackedteam/fuzzer-windows

View on GitHub
fontfuzzer/parsers/TTF.py

Summary

Maintainability
F
1 mo
Test Coverage
import os
import sys
import math
import mmap
import random
import string
import logging
import subprocess

from struct import *


def getLogger():
    # logging settings
    logger = logging.getLogger('TTF')
    logger.setLevel(logging.INFO)

    ch = logging.StreamHandler()
    ch.setLevel(logging.INFO)

    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    ch.setFormatter(formatter)

    logger.addHandler(ch)

    return logger


LOGGER = getLogger()




"""
N.B *DirectoryOffset is supposed to TableOffset instead..
"""


class TTFont():

    REQUIRED_TABLES = [ 'cmap',  'head', 'hhea', 'hmtx' ,
                        'maxp', 'name', 'post', 'OS/2'  ]

    TTF_TABLES = ['cvt ', 'fpgm', 'glyf', 'loca', 'prep']


    POSTSCRIPT_TABLES = ['CFF ', 'VORG']


    BITMAP_TABLES = ['EBDT', 'EBLC', 'EBSC', ]


    OPTIONAL_TABLES = [ 'gasp', 'hdmx', 'kern', 'LTSH', 
                        'PCLT', 'VDMX', 'vhea', 'vmtx' ]


    def __init__(self, filename, simpleParsing = False):
        font_handle = open(filename,'rb')
        self.filename = filename
        self.fontOffsetTable = FontOffsetTable(font_handle)
        self.fontOffsetTableLength = font_handle.tell()
        self.simpleParsing = simpleParsing # when a fuzzed font is parsed it might raise exceptions
                                  # simple parsing tries to parse only necessary stuff


        # k: tag => v: FontTableDirectory entry
        self.fontTableDirectories = {}

        # read all the tables
        for i in range(0, int(self.fontOffsetTable.numTables)):
            table  = FontTableDirectory(font_handle, self.fontTableDirectories)
            self.fontTableDirectories[table.tag] = table

        self.fontTableDirectoriesLength = font_handle.tell() - self.fontOffsetTableLength

        # calculate checksum
        for t in sorted( self.fontTableDirectories.keys() ):


            # checksum for 'head' table is different
            if( self.fontTableDirectories[t].tag == 'head' ):
                self.fontTableDirectories[t].doHeadChecksum(font_handle)
            else:
                self.fontTableDirectories[t].doChecksum(font_handle)


        # parse required font tables (for both ttf and otf)

        LOGGER.debug('[*] >> Parsing required tables <<')

        # HEAD
        LOGGER.debug('[*] Parsing table head')
        font_handle.seek(self.fontTableDirectories['head'].offset)
        self.fontTableDirectories['head'].table = HeadTable(font_handle)

        # MAXP
        LOGGER.debug('[*] Parsing table maxp')
        font_handle.seek(self.fontTableDirectories['maxp'].offset)
        self.fontTableDirectories['maxp'].table = MaxpTable(font_handle)

        # CMAP
        LOGGER.debug('[*] Parsing table cmap')
        # FIXME: handle is set within constructor, change it
        self.fontTableDirectories['cmap'].table = CmapTable(font_handle, self.fontTableDirectories['cmap'])

        # HHEA
        LOGGER.debug('parsing table hhea')
        font_handle.seek(self.fontTableDirectories['hhea'].offset)
        self.fontTableDirectories['hhea'].table = HheaTable(font_handle, self.fontTableDirectories['hhea'])

        # HMTX
        LOGGER.debug('parsing table hmtx')
        font_handle.seek(self.fontTableDirectories['hmtx'].offset)
        numberOfHMetrics = self.fontTableDirectories['hhea'].table.numberOfHMetrics
        numGlyphs = self.fontTableDirectories['maxp'].table.numGlyphs
        self.fontTableDirectories['hmtx'].table = HmtxTable(font_handle, self.fontTableDirectories['hmtx'], numberOfHMetrics, numGlyphs )


        # POST
        LOGGER.debug('parsing table post')
        font_handle.seek(self.fontTableDirectories['post'].offset)
        self.fontTableDirectories['post'].table = PostTable(font_handle)    

        # either ttf (glyf) or otf (cff)
        if 'glyf' in self.fontTableDirectories and not self.simpleParsing:

            # LOCA (required by GLYF)
            isLong = self.fontTableDirectories['head'].table.indexToLocFormat

            numberOfGlyphs = self.fontTableDirectories['maxp'].table.numGlyphs + 1
            nor = self.fontTableDirectories['loca'].length / 4 if isLong else self.fontTableDirectories['loca'].length / 2

            if nor != numberOfGlyphs:
                LOGGER.info('weird number of Glyphs: {} vs {}'.format(nor, numberOfGlyphs))

            LOGGER.debug( '[D] \t Number of glyphs {}'.format(numberOfGlyphs) )

            LOGGER.debug( '[*] Parsing loca table' )
            font_handle.seek(self.fontTableDirectories['loca'].offset)
            self.fontTableDirectories['loca'].table = LocaTable(font_handle, isLong, numberOfGlyphs)



            # GLYF

            # glyph font table is a list of glyph structures
            LOGGER.debug( '[*] Parsing table glyf' )

            self.fontTableDirectories['glyf'].table = []

            # must set the handle offset before calling the constructor
            startOffset = self.fontTableDirectories['glyf'].offset 
            endOffset   = self.fontTableDirectories['glyf'].length + startOffset


            # loca table contains the offsets of the glyphs relative to the
            # beginning of glyphData table

            font_handle.seek(startOffset)

            offsets = self.fontTableDirectories['loca'].table.offsets
            if len(offsets) != self.fontTableDirectories['maxp'].table.numGlyphs + 1:
                LOGGER.warn('Weird number of glyph offsets: loca {} vs maxp {}'.format(len(offsets), self.fontTableDirectories['maxp'].table.numGlyphs + 1) )



            for i in range(0, self.fontTableDirectories['maxp'].table.numGlyphs + 1):

                currentOffset = offsets[i]
                font_handle.seek(startOffset + currentOffset)

                #print '[*]\t {}: reading table at {}'.format( i, font_handle.tell() )
                self.fontTableDirectories['glyf'].table.append( GlyphTable(font_handle) )





        elif 'CFF ' in self.fontTableDirectories:

            # CFF
            LOGGER.debug( '[*] Parsing table CFF' )

            font_handle.seek(self.fontTableDirectories['CFF '].offset)
            self.fontTableDirectories['CFF '].table = CFFTable(font_handle)

        else:
            if not simpleParsing:
                raise Exception('Can\'t find glyf nor CFF table')


        LOGGER.debug( '[*] >> Finished parsing required tables <<' )
        LOGGER.debug( '[*] >> Parsing optional tables <<' )

        # parse non required tables
        for t in sorted( self.fontTableDirectories.keys() ):

            # CVT 
            if t == 'cvt ':
                LOGGER.debug( '[*] Parsing table CVT ' )
                font_handle.seek(self.fontTableDirectories['cvt '].offset)
                self.fontTableDirectories['cvt '].table = CVTTable(font_handle, self.fontTableDirectories['cvt '].length / 2 )   


            # prep
            if t == 'prep':
                LOGGER.debug( '[*] Parsing table prep' )
                font_handle.seek(self.fontTableDirectories['prep'].offset)
                self.fontTableDirectories['prep'].table = PrepTable(font_handle, self.fontTableDirectories['prep'].length)   

            if t == 'EBDT':
                LOGGER.debug( '[*] Parsing table EBDT' )
                font_handle.seek(self.fontTableDirectories['EBDT'].offset)
                self.fontTableDirectories['EBDT'].table = EBDTTable(font_handle)   


            if t == 'EBLC':
                LOGGER.debug( '[*] Parsing table EBLC' )
                font_handle.seek(self.fontTableDirectories['EBLC'].offset)
                self.fontTableDirectories['EBLC'].table = EBLCTable(font_handle)   



            if t == 'EBSC':
                LOGGER.debug( '[*] Parsing table EBSC' )
                font_handle.seek(self.fontTableDirectories['EBSC'].offset)
                self.fontTableDirectories['EBSC'].table = EBSCTable(font_handle)   



            if t == 'fpgm':
                LOGGER.debug( '[*] Parsing table fpgm' )
                font_handle.seek(self.fontTableDirectories['fpgm'].offset)
                self.fontTableDirectories['fpgm'].table = FpgmTable(font_handle, self.fontTableDirectories['fpgm'].length)   

            if t == 'kern':
                LOGGER.debug('parsing table kern')
                font_handle.seek(self.fontTableDirectories['kern'].offset)
                self.fontTableDirectories['kern'].table = KernTable(font_handle)   

            if t == 'name':
                LOGGER.debug('parsing table name')
                font_handle.seek(self.fontTableDirectories['name'].offset)
                self.fontTableDirectories['name'].table = NameTable(font_handle)   


            if t == 'OS/2':

                # Some fonts have this table truncated

                LOGGER.debug('parsing table OS/2')
                font_handle.seek(self.fontTableDirectories['OS/2'].offset)

                try:
                    self.fontTableDirectories['OS/2'].table = OS2Table(font_handle)   
                except error as e:
                    LOGGER.error('\tOS/2 error: {}'.format( e ))



        LOGGER.debug( '[*] >> Finished parsing optional tables <<' )



    def dump(self):

        self.fontOffsetTable.dump()


        for i in sorted(self.fontTableDirectories.keys()):
            self.fontTableDirectories[i].dump()






    '''
    Rebuild the font with newTagTable as the new table
    for tag 'tag'
    '''
    def rebuildFont(self, tag, newTagTable, originalFontBuffer):


        assert len(originalFontBuffer) % 4 == 0, 'File must be 4 byte aligned'
        assert len(newTagTable) % 4 == 0, 'New table must be 4 byte aligned'


        newFont = []

        # only the tables that start after the one we're updating
        # need to be moved
        tagStartOffset = self.fontTableDirectories[tag].offset

        directories = self.fontTableDirectories.copy()
        directories.pop(tag)

        dirToRebase = {}
        for d in directories:
            if tagStartOffset < directories[d].offset:
                dirToRebase[d] =  directories[d] 


        dirToPlainCopy = list( set( self.fontTableDirectories.keys() ) - set( dirToRebase.keys() ) - set([tag]) )

        LOGGER.debug('rebuilding font, new table for: {}'.format( tag) ) 
        LOGGER.debug('rebuilding font, copying tables: {}'.format( ', '.join(dirToPlainCopy)  ) )
        LOGGER.debug('rebuilding font, rebasing tables: {}'.format( ', '.join(dirToRebase.keys() ) ) )


        # 1] copy font offset table
        newFont =  originalFontBuffer[:self.fontOffsetTableLength]

        # 2] copy font table directories, we'll fix checkSum, offset, length later
        newFont += originalFontBuffer[self.fontOffsetTableLength:self.fontTableDirectoriesLength + self.fontOffsetTableLength]

        assert len(newFont) %4 == 0, 'WTF -5'

        # 3] copy the tables that don't need to be rebased


        # copy the tables in order
        offsetLength = {}
        for d in dirToPlainCopy:

            offset = self.fontTableDirectories[d].offset
            tmpLength = self.fontTableDirectories[d].length


            if (tmpLength % 4) !=0:
                tmpLength = tmpLength + ( 4 - tmpLength  % 4)


            offsetLength[offset] = tmpLength





        keys = sorted(offsetLength.keys())

        for k in keys:
            newFont += originalFontBuffer[k:offsetLength[k] + k]
            #print k, Utils.doBufferChecksum(originalFontBuffer[k:offsetLength[k] + k])

        assert len(newFont) %4 == 0, 'WTF -4'



        # 4] copy the new table
        newFont  += ''.join(newTagTable)

        assert len(newFont) %4 == 0, 'WTF -3'


        # fix checksum and length in the font table directory for new table tag
        checksumOffsetWithinFontDirectoryTable = self.fontTableDirectories[tag].fontDirectoryOffsetWithinTheFile + 4
        lengthOffsetWithinFontDirectoryTable = self.fontTableDirectories[tag].fontDirectoryOffsetWithinTheFile + 12

        newChecksum = hex(Utils.doBufferChecksum(''.join(newTagTable)) ).replace('0x', '').replace('L', '')

        # dbg
        while len(newChecksum) < 8:
            newChecksum = '0' + newChecksum

        newChecksum = [ pack('>B', int(newChecksum[i:i+2],16) ) for i in range(0, len(newChecksum), 2) ]

        oldLength = len(newFont)

        assert len(newFont) %4 == 0, 'WTF -2'


        # update checksum
        newFont = list(newFont[:checksumOffsetWithinFontDirectoryTable]) + \
            newChecksum + \
            list(newFont[checksumOffsetWithinFontDirectoryTable+4:])

        newFont = ''.join(newFont)

        assert  oldLength == len(newFont)

        # update length
        newLength = pack('>L', len(newTagTable) ) 

        newTableOldLength = unpack('>L', originalFontBuffer[lengthOffsetWithinFontDirectoryTable:lengthOffsetWithinFontDirectoryTable+4])[0]
        lengthDelta = len(newTagTable) - newTableOldLength 

        LOGGER.debug('rebuilding font, length delta: {}'.format( lengthDelta ))

        assert len(newFont) %4 == 0, 'WTF -1'

        newFont = newFont[:lengthOffsetWithinFontDirectoryTable] + \
            newLength + \
            newFont[lengthOffsetWithinFontDirectoryTable+4:]

        assert  oldLength == len(newFont)

        assert len(newFont) %4 == 0, 'WTF 0'

        # 5] rebase the remaining tables in order
        offsetLength = {}
        for d in dirToRebase:
            offset = self.fontTableDirectories[d].offset
            length = self.fontTableDirectories[d].length


            if (length % 4) !=0:
                length = length + ( 4 - length  % 4)


            offsetLength[offset] = length


        keys = sorted(offsetLength)


        assert len(newFont) %4 == 0, 'WTF 1'

        # a] copy tables
        for k in keys:

            newFont += originalFontBuffer[k:offsetLength[k] + k]

        assert len(newFont) %4 == 0, 'WTF 2'

        # b] update offsets field within font table directory
        for d in dirToRebase:
            offsetOffsetWithinFontDirectoryTable = self.fontTableDirectories[d].fontDirectoryOffsetWithinTheFile + 8

            newLength = lengthDelta + unpack('>L', originalFontBuffer[offsetOffsetWithinFontDirectoryTable:offsetOffsetWithinFontDirectoryTable+4])[0]
            newLength = pack('>L', newLength)

            oldLength = len(newFont)

            newFont = newFont[:offsetOffsetWithinFontDirectoryTable] + \
                newLength + \
                newFont[offsetOffsetWithinFontDirectoryTable+4:]

            assert oldLength == len(newFont)


        # 6] update head checksum
        headFontDirectoryTableOffset = self.fontTableDirectories['head'].fontDirectoryOffsetWithinTheFile
        headChecksumOffsetWithinFontDirectoryTable = headFontDirectoryTableOffset - 4

        oldLength = len(newFont)
        newFont = Utils.doBufferHeadChecksum(newFont, headFontDirectoryTableOffset)

        assert oldLength == len(newFont)


        return newFont


# Start fuzzing methods


    '''
    bit flip the glyfs 
    return fileInMemory, isFontFuzzed, numberOfBytesChanged
    '''
    def fuzzGlyfsBitFlipping(self):
        LOGGER.debug('GlyfsBitFlipping')
        glyfsTable = self.fontTableDirectories['glyf'].table
        LOGGER.debug('\tnumber of glyf to fuzz: {}'.format(len( glyfsTable )))
        
        offsets = {}
        for t in glyfsTable:
            offsets[t.positionWithinFile] = t.positionWithinFile + t.length

        LOGGER.debug('\tnumber of regions actually fuzzed: {}'.format( len( offsets.keys()) ) )
        
        fileInMemory = open(self.filename, 'rb').read()
                
        oldsize = len(fileInMemory)
        numberOfChanges = 0
       
        for i in offsets:
            replacement, numwrites = Utils.fuzzBufferBitFlipping(fileInMemory[i:offsets[i]], fuzzFactor=20, maxWrites=100 )
            assert len(replacement) != i - offsets[i], 'buffer size changed'
            fileInMemory = fileInMemory[:i] + replacement + fileInMemory[offsets[i]:]
            numberOfChanges += numwrites
                                                      
        return fileInMemory, True, numberOfChanges

    '''
    benfuzzer harness
    '''
    def fuzzBenStyle(self, table, fuzzFactor):
        fileInMemory = open(self.filename, 'rb').read()

        # fuzz table table
        tableDirTable  = self.fontTableDirectories[table]
        tableOffset = tableDirTable.offset
        tableLength = tableDirTable.length

        newtableTable, numberOfChanges = Utils.fuzzBufferBenFuzz(fileInMemory[tableOffset:tableOffset+tableLength], fuzzFactor)

        # only to test rebuildFont
        #newtableTable = fileInMemory[tableOffset:tableOffset+tableLength]
        #while (len(newtableTable) % 4) != 0:
        #    newtableTable += chr(0x0)

        assert len(fileInMemory) % 4 == 0, 'Fuzz Ben style issues'
        assert len(newtableTable) % 4 == 0, 'Fuzz Ben style issues'

        newFont = self.rebuildFont(table, newtableTable, fileInMemory)
        
        return newFont, True, numberOfChanges

    '''
    Loop through each table, whether its content
    is fuzzed or not is probabilistic
    '''
    def fuzzFullTablesPayload(self):
        pass


    def fuzzDirectoriesRadamsa(self):

        # read the whole file
        fileInMemory = open(self.filename, 'rb').read()

        # fuzz directories content
        fileMod = fileInMemory
        for i in sorted(self.fontTableDirectories.keys()):
            table = self.fontTableDirectories[i]


            if table.tag == 'glyf':
                LOGGER.INFO( '[*] Fuzzing directory {}'.format(table.tag) )
                fileMod = table.fuzzDirectory(fileMod)

                # update checksum
                fileMod = table.doFileBufferChecksum(fileMod)
                fileMod = table.doFileBufferHeadChecksum(fileMod)




        # write fuzzed font disk
        fname = 'testcases//' + \
            os.path.basename(self.filename).split('.ttf')[0] + \
            '-' + \
            ''.join( random.choice(string.ascii_lowercase + string.digits) for x in range(8) ) + \
            '.ttf'



        open(fname, 'wb').write(fileMod)


    


    def fuzzFontBytecode(self):

        # read the whole file
        fileInMemory = open(self.filename, 'rb').read()

        # fuzz bytecode within certain tables
        fileMod = fileInMemory

        # this font may not contain the table we want to fuzz, return true if we changed something
        # within the font
        isFontFuzzed = False

        for i in sorted(self.fontTableDirectories.keys()):
            table = self.fontTableDirectories[i]


            # fuzz the bytcode within each glyf
            if table.tag == 'glyf':
                LOGGER.INFO( '[*] Fuzzing bytecode found in directory {}'.format(table.tag) )

                # fetch offset, fuzz that buffer then join the whole file back
                LOGGER.INFO( table.offset, '-', table.length + table.offset )
                buffer = fileInMemory[table.offset:table.length + table.offset]

                buffer, numberOfBytesChanged = Utils.fuzzBufferBitFlipping(buffer)
                isFontFuzzed = True

                fileMod = fileInMemory[0:table.offset] + buffer + fileInMemory[table.length + table.offset:]
                #print len(fileInMemory), 'vs', len(fileMod)

                # update checksum
                fileMod = table.doFileBufferChecksum(fileMod)
                fileMod = table.doFileBufferHeadChecksum(fileMod)





        # write fuzzed font disk
        #fname = 'testcases//' + \
        #         os.path.basename(self.filename).split('.otf')[0] + \
        #        '-' + \
        #        ''.join( random.choice(string.ascii_lowercase + string.digits) for x in range(8) ) + \
        #        '.otf3'

        #open(fname, 'wb').write(fileMod)

        return fileMod, isFontFuzzed, numberOfBytesChanged



    def fuzzCffTableBitFlipping(self):

        assert 'CFF ' in self.fontTableDirectories, '[E] No CFF table found'

        # 1] read file in memory
        fileInMemory = list(open(self.filename, 'rb').read())

        # 2] flip some bytes within cff table range
        start = self.fontTableDirectories['CFF '].offset
        end   = start + self.fontTableDirectories['CFF '].length

        print '[D] CFF range is {} <-> {}'.format(start, end)

        FuzzFactor = random.random() * random.random() * 500
        numwrites = random.randrange( math.ceil( (float(end-start) / FuzzFactor) ) ) +1

        print 'Changing {} bytes out of {}'.format(numwrites, end-start)

        # bit flip
        for j in range(numwrites):
            rbyte = random.randrange(256)
            rn = random.randrange(end-start)
            fileInMemory[start+rn] = "%c"%(rbyte);

        fileInMemory = ''.join(fileInMemory)


        # 3] checksum cff table and head
        fileInMemory = self.fontTableDirectories['CFF '].doFileBufferChecksum(fileInMemory)

        # pure crap
        fileInMemory = self.fontTableDirectories['CFF '].doFileBufferHeadChecksum(fileInMemory)

        # 4] write to disk
        #fname = 'testcases//' + \
        #        os.path.basename(self.filename).split('.otf')[0] + \
        #        '-' + \
        #        ''.join( random.choice(string.ascii_lowercase + string.digits) for x in range(8) ) + \
        #'.ttf'

        #open(fname, 'wb').write(fileInMemory)
        return fileInMemory


    def fuzzDirectoriesBitFlipping(self):
        fileInMemory = list(open(self.filename, 'rb').read())

        FuzzFactor = random.random() * random.random() * 500
        numwrites = random.randrange( math.ceil( (float(len(fileInMemory)) / FuzzFactor) ) ) +1

        print 'Changing {} bytes out of {}'.format(numwrites, len(fileInMemory))

        # bit flip
        for j in range(numwrites):
            rbyte = random.randrange(256)
            rn = random.randrange(len(fileInMemory))
            fileInMemory[rn] = "%c"%(rbyte);


        fileInMemory = ''.join(fileInMemory)

        # update checksums
        for i in sorted(self.fontTableDirectories.keys()):
            table = self.fontTableDirectories[i]

            fileInMemory = table.doFileBufferChecksum(fileInMemory)

        # table ?!
        fileInMemory = table.doFileBufferHeadChecksum(fileInMemory)


        # write file to disk
        fname = 'testcases//' + \
            os.path.basename(self.filename).split('.ttf')[0] + \
            '-' + \
            ''.join( random.choice(string.ascii_lowercase + string.digits) for x in range(8) ) + \
            '.ttf'

        open(fname, 'wb').write(fileInMemory)



# End fuzzing methods

"""
FIXED    32bit signed fixed-point number 16.16

"""

class FontOffsetTable():

    def __init__(self, handle):

        # sfnt stands for spline font
        self.SFNT_Version = handle.read(4)
        self.numTables = unpack(">H", handle.read(2) )[0]
        self.searchRange = handle.read(2)
        self.entrySelector = handle.read(2)
        self.rangeShift = handle.read(2)

    def dump(self):

        print 'FontOffsetTable:'
        print '\tSFNT_Version\t {}'.format( unpack(">i", self.SFNT_Version )[0] )
        print '\tnumTables\t {}'.format(  self.numTables )
        print '\tsearchRange\t {}'.format( unpack(">H", self.searchRange)[0] )
        print '\tentrySelector\t {}'.format( unpack(">H", self.entrySelector)[0] )
        print '\trangeShift\t {}'.format( unpack(">H", self.rangeShift)[0] )


# TODO: redesign this class
class FontTableDirectory():

    def __init__(self, handle, fontTableDirectories):

        self.fontDirectoryOffsetWithinTheFile = handle.tell()

        self.tag = handle.read(4)
        self.checksum = unpack('>L', handle.read(4))[0]
        self.offset = unpack('>L', handle.read(4) )[0]
        self.length = unpack('>L', handle.read(4) )[0]

        # the FontTable object this directory element points to
        self.table = None

        # awful abstraction
        self.fontTableDirectories = fontTableDirectories

    """
    fuzzDirectory changes the payload of the directory, keeping the
    same offset and length, but updating the checksum
    """
    def fuzzDirectory(self, fileInMemory):

        assert self.table != None, '[E] No table for this directory'

        # a] write the table to file, then fuzz it
        file_name = 'tmp_table'
        t = open(file_name, 'wb')

        data = fileInMemory[self.offset:self.offset+self.length]

        assert len(data) == self.length, "Couldn't read enough bytes"

        t.write(data)

        t.close()

        output = subprocess.check_output(['radamsa-0.3.exe', file_name])[:len(data)]

        # pad with 0xf atm
        while len(output) < len(data):
            output += pack('>b', 0xf)


        final_data = fileInMemory[0:self.offset] + output + fileInMemory[self.offset+self.length:]

        assert len(final_data) == len(fileInMemory)

        return final_data 


    def doChecksum(self, handle):
        total_data = 0

        handle.seek(self.offset)

        # round length
        checksumLength = (self.length + 3 ) & ~3

        #print 'Reading for {} bytes rather than {}'.format(checksumLength, self.length)

        table = handle.read(checksumLength)
        #print 'Read {} bytes from table {}'.format(len(table), self.tag)

        for i in range(0, len(table), 4):
            data = unpack('>I', table[i:i+4] ) [0]
            total_data += data

        final_data = 0xffffffff & total_data

        if final_data != self.checksum:
            LOGGER.debug( '\n\tChecksum error, calculated: {} - read: {}'.format(final_data, self.checksum) )

        LOGGER.debug( '[*]\t checksum: {}'.format(final_data) )

        return final_data


    def doFileBufferChecksum(self, fileInMemory):
        total_data = 0

        # round length
        checksumLength = (self.length + 3 ) & ~3

        table = fileInMemory[self.offset:self.offset+checksumLength]

        for i in range(0, len(table), 4):
            data = unpack('>I', table[i:i+4] ) [0]
            total_data += data

        new_checksum = 0xffffffff & total_data

        print '[*]\t New checksum {}'.format(new_checksum)

        # update the buffer
        newFileInMemory = fileInMemory[0:self.fontDirectoryOffsetWithinTheFile + 4] +  pack('>L', new_checksum) + \
            fileInMemory[self.fontDirectoryOffsetWithinTheFile + 8:]

        assert len(newFileInMemory) == len(fileInMemory)

        return newFileInMemory




    # TODO: wrong class for this function 
    def doFileBufferHeadChecksum(self, fileInMemory):

        # these var names are actually inverted..
        headDirectoryOffsetWithinTheFile = self.fontTableDirectories['head'].fontDirectoryOffsetWithinTheFile
        headTableOffset = self.fontTableDirectories['head'].offset

        LOGGER.debug( '[D] Head headDirectoryOffsetWithinTheFile {} - headTableOffset {}'.format(headDirectoryOffsetWithinTheFile, headTableOffset) )

        total_data = 0

        # round length
        checksumLength = (self.fontTableDirectories['head'].length + 3 ) & ~3

        # set checkSumAdjustement to 0 in the read buffer
        fileInMemory = fileInMemory[:headTableOffset + 8] + pack('>I', 0 ) + \
            fileInMemory[headTableOffset  + 12:]

        table = fileInMemory[headTableOffset:headTableOffset+checksumLength]

        LOGGER.debug( '[D] table size {}'.format(len(table)) )

        for i in range(0, len(table), 4):
            if i == 8:    # actually useless
                data = 0  # set checkSumAdjustement to 0 in the read buffer
                checkSumAdjustement = unpack('>I', table[i:i+4] ) [0]
            else:
                data = unpack('>I', table[i:i+4] ) [0]

            total_data += data

        headTableChecksum = 0xffffffff & total_data

        # head table checksum done, update checksum field in memory
        newFileInMemory = fileInMemory[0:headDirectoryOffsetWithinTheFile + 4] +  pack('>L', headTableChecksum) + \
            fileInMemory[headDirectoryOffsetWithinTheFile + 8:]

        LOGGER.debug( '[D] head table checksum {} @ {}'.format(headTableChecksum, headDirectoryOffsetWithinTheFile + 4) )

        # now, calculate entire font checksum
        total_data = 0

        # calculate new checkSumAdjustement value
        for i in range(0, len(newFileInMemory), 4):
            data = unpack('>I', newFileInMemory[i:i+4])[0]
            total_data += data

        newCheckSumAdjustement = total_data & 0xffffffff 
        newCheckSumAdjustement = (0xb1b0afba - newCheckSumAdjustement ) & 0xffffffff 

        LOGGER.debug( '[D] head newCheckSumAdjustement {}'.format(newCheckSumAdjustement) )


        # update
        newFileInMemory = newFileInMemory[:headTableOffset + 8] + pack('>I',newCheckSumAdjustement ) + \
            newFileInMemory[headTableOffset  + 12:]


        LOGGER.debug( '[D] updating newCheckSumAdjustement {} @ {}'.format(newCheckSumAdjustement, headTableOffset + 8 ) )


        return newFileInMemory




    def doHeadChecksum(self, handle):
        """
        To calculate the checkSum for the 'head' table which itself includes the checkSumAdjustment entry for the entire font, do the following:

        1] Set the checkSumAdjustment to 0.
        2] Calculate the checksum for all the tables including the 'head' table and enter that value into the table directory.
        3] Calculate the checksum for the entire font.
        4] Subtract that value from the hex value B1B0AFBA.
        5] Store the result in checkSumAdjustment.

        The checkSum for the head table which includes the checkSumAdjustment entry for the entire font is now incorrect.
        That is not a problem. Do not change it. An application attempting to verify that the 'head' table has not changed 
        should calculate the checkSum for that table by not including the checkSumAdjustment value, and compare the result 
        with the entry in the table directory. 
        """

        assert self.tag == 'head', 'Trying to calculate the head checksum for a non-head table'

        total_data = 0

        handle.seek(self.offset)

        # round length
        checksumLength = (self.length + 3 ) & ~3


        table = handle.read(checksumLength)


        for i in range(0, len(table), 4):
            if i == 8:
                data = 0
                checkSumAdjustement = unpack('>I', table[i:i+4] ) [0]
            else:
                data = unpack('>I', table[i:i+4] ) [0]

            total_data += data

        final_data = 0xffffffff & total_data

        if final_data != self.checksum:
            LOGGER.debug( 'checksum error, calculated: {} - read: {}'.format(final_data, self.checksum) )

        # head table checksum done
        LOGGER.debug( '[*]\t checksum: {}'.format(final_data) )



        # now, calculate entire font checksum
        handle.seek(0,2)
        end_of_file = handle.tell()

        handle.seek(0)

        total_data = 0
        font = handle.read(end_of_file)

        # set checkSumAdjustement to 0 in the read buffer
        font = font[:self.offset + 8] + pack('>I', 0) + font[self.offset + 12:]


        #print 'Read {} bytes for checkSumAdjustement'.format(len(font))

        for i in range(0, len(font), 4):
            data = unpack('>I', font[i:i+4] ) [0]
            total_data += data

        final_data =  total_data & 0xffffffff 

        final_data =  (0xb1b0afba - final_data) & 0xffffffff 

        if final_data != checkSumAdjustement:
            LOGGER.debug( 'checkSumAdjustement error, calculated {} - read: {}'.format(final_data, checkSumAdjustement ) )


        return final_data


    def dump(self, index=''):

        print 'FontTableDirectory {}'.format(index)
        print '\ttag\t {}'.format(self.tag)
        print '\tchecksum {}'.format(self.checksum)
        print '\toffset\t {}'.format(self.offset)
        print '\tlength\t {}'.format(self.length)


"""
Superclass for all the tables
"""
class FontTable():
    pass



class CFFTable(FontTable):

    def __init__(self, handle):

        # 1 header
        self.headerMajor    = unpack('>B', handle.read(1))[0]
        self.headerMinor    = unpack('>B', handle.read(1))[0]
        self.headerHdrSize  = unpack('>B', handle.read(1))[0]

        # The offSize field specifies the size of all offsets(0) relative to the
        # start of CFF data
        self.headerOffSize  = unpack('>B', handle.read(1))[0]


        '''
        This contains the PostScript language names (FontName or
        CIDFontName) of all the fonts in the FontSet

        For compatibility with client software, such as PostScript
        interpreters and Acrobat , font names should be no longer
        than 127 characters and should not contain any of the following
        ASCII characters: [, ], (, ), {, }, <, >, /, %, null (NUL), space, tab,
        carriage return, line feed, form feed. It is recommended that
        font names be restricted to the printable ASCII subset, codes 33
        through 126. Adobe Type Manager  software imposes a further restriction on the font
        name length of 63 characters
        '''

        # 2
        self.name = self.Index(handle)

        for n in self.name.data:
            print '[D] \tPS name: {}'.format(n)

        '''
        top-level DICTs of all the fonts in the FontSet
        stored in an INDEX structure.

        Objects contained within this INDEX correspond to those 
        in the Name INDEX in both order and number. Each object 
        is a DICT structure that corresponds to
        the top-level dictionary of a PostScript font.
        A font is identified by an entry in the Name INDEX and its data
        is accessed via the corresponding Top DICT
        '''

        # 3
        self.topDictIndex = self.Index(handle)


        # 4
        self.stringIndex = self.Index(handle)

        for n in self.stringIndex.data:
            print '[D] \tString name: {}'.format(n)


        # 5 Global Subr INDEX


    class Dict():


        def __init__(self, handle):
            pass


    class Index():

        def __init__(self, handle):

            self.count          = unpack('>H', handle.read(2))[0]
            #print 'Count {}'.format(self.count)

            self.offSize        = unpack('>B', handle.read(1))[0]
            #print 'offSize {}'.format(self.offSize)

            self.offsetArray = []

            for i in range(0, self.count + 1):

                if self.offSize == 1:
                    self.offsetArray.append( unpack('>B', handle.read(1))[0])

                elif self.offSize == 2:
                    self.offsetArray.append( unpack('>H', handle.read(2))[0])         

                elif self.offSize == 3:
                    raise Exception('TODO: unpack 3 bytes')

                elif self.offSize == 4:
                    self.offsetArray.append( unpack('>I', handle.read(4))[0])

                else:
                    raise Exception('Invalid offSize')

            # Offsets in the offset array are relative to the byte that precedes
            # the object data
            self.startOffset    = handle.tell() - 1

            # read elements
            self.data = []

            for i in range(0, self.count):

                # seek to the correct offset, i.e. start of index struct + offsetArray[i]
                handle.seek(self.startOffset + self.offsetArray[i])
                size = self.offsetArray[i+1] - self.offsetArray[i]

                self.data.append( handle.read(size) )

            # seek handle to the end of the index
            first = handle.tell()
            handle.seek( self.offsetArray[len(self.offsetArray)-1] + self.startOffset )
            assert handle.tell() == first, 'offsets screwed'




class FpgmTable(FontTable):

    def __init__(self, handle, numberOfInstructions):
        self.instructions = []
        for i in range(0, numberOfInstructions):
            self.instructions.append( unpack('>B', handle.read(1))[0])





"""
Collection of bitmap data, according
to info of EBLC table
"""
class EBDTTable(FontTable):

    def __init__(self, handle):
        self.version = unpack('>l', handle.read(4))[0]
        assert self.version == 0x20000, '[E] Wrong version for EBDT table: {}'.format(self.version)


"""
Embedded bitmap locators
"""
class EBLCTable(FontTable):

    def __init__(self, handle):
        self.version    = unpack('>l', handle.read(4))[0]
        assert self.version == 0x20000, '[E] Wrong version for EBLC table: {}'.format(self.version)
        self.numSizes   = unpack('>L', handle.read(4))[0]

        self.bitmapSizeTables = []


    class BitmapSizeTable():

        def __init__(self, handle):
            self.indexSubTableArrayOffset = unpack('>L', handle.read(4))[0]
            self.indexTablesSize          = unpack('>L', handle.read(4))[0]
            self.numberOfIndexSubTables   = unpack('>L', handle.read(4))[0]
            self.colorRef                 = unpack('>L', handle.read(4))[0]

            self.hori                     = SbitLineMetrics(handle)
            self.vert                     = SbitLineMetrics(handle)

            self.startGlyphIndex          = unpack('>W', handle.read(2))[0]
            self.endGlyphIndex            = unpack('>W', handle.read(2))[0]

            self.ppemX                    = unpack('>B', handle.read(1))[0]
            self.ppemY                    = unpack('>B', handle.read(1))[0]
            self.bitDepth                 = unpack('>B', handle.read(1))[0]
            self.flags                    = unpack('>B', handle.read(1))[0]




class EBSCTable(FontTable):


    def __init__(self):
        self.version    = unpack('>l', handle.read(4))[0]
        assert self.version == 0x20000, '[E] Wrong version for EBLC table: {}'.format(self.version)
        self.numSizes   = unpack('>L', handle.read(4))[0]

        self.bitmapScaleTable = []
        for i in range(0, self.numSizes):
            self.bitmapScaleTable.append( BitmapScaleTable(handle) )


    class BitmapScaleTable():

        def __init__(self, handle):
            self.hori           = SbitLineMetrics(handle)
            self.vert           = SbitLineMetrics(handle)

            self.ppemX          = unpack(handle.read('>B', handle.read(1) ) )[0]         
            self.ppemY          = unpack(handle.read('>B', handle.read(1) ) )[0]
            self.substitutePpemX          = unpack(handle.read('>B', handle.read(1) ) )[0]
            self.substitutePpemY          = unpack(handle.read('>B', handle.read(1) ) )[0]




class SbitLineMetrics():

    def __init__(self):
        self.ascender = unpack('>b', handle.read(1))[0]
        self.descender = unpack('>b', handle.read(1))[0]
        self.widthMax = unpack('>B', handle.read(1))[0]

        self.caretSlopeNumerator = unpack('>b', handle.read(1))[0]
        self.caretSlopeDenominator = unpack('>b', handle.read(1))[0]

        self.caretOffset = unpack('>b', handle.read(1))[0]
        self.minOriginSB = unpack('>b', handle.read(1))[0]
        self.minAdvancedSB = unpack('>b', handle.read(1))[0]
        self.maxBeforeBL = unpack('>b', handle.read(1))[0]
        self.minAfterBL = unpack('>b', handle.read(1))[0]
        self.pad1 = unpack('>b', handle.read(1))[0]
        self.pad2 = unpack('>b', handle.read(1))[0]


"""
provides a mechanism for describing embedded bitmaps
which are created by scaling other embedded bitmaps

"""



"""
Index to Location
"""
class LocaTable(FontTable):

    """
    Offsets are relative to the beginning of the glyphData.
    In order to compute the length of the last glyph element, 
    there is an extra entry after the last valid index.

    Index zero is the missing character
    """
    def __init__(self, handle, isLong, numberOfRecords):

        # 0 for short offsets, 1 for long
        self.isLong = isLong

        self.offsets = []

        if self.isLong:
            for i in range(0, numberOfRecords):
                self.offsets.append( unpack('>L', handle.read(4) ) [0] )
        else:
            for i in range(0, numberOfRecords):
                self.offsets.append( unpack('>H', handle.read(2) ) [0] * 2 )



    def fuzz(self):
        # WTF: screw indexes
        pass


"""
List of values that can be referenced by instructions
"""
class CVTTable(FontTable):

    def __init__(self, handle, numberOfElements):

        self.values = []
        for i in range(0, numberOfElements):
            self.values.append( unpack('>h', handle.read(2) ) )




"""
Set of TrueType instructions that will be executed 
whenever the font or point size or transformation matrix 
change and before each glyph is interpreted
"""
class PrepTable(FontTable):

    def __init__(self, handle, numberOfInstructions):
        self.instructions = []

        for i in range(0, numberOfInstructions):
            self.instructions.append(unpack('>B', handle.read(1)))


    def fuzz(self):
        pass


class MaxpTable(FontTable):

    def __init__(self, handle):

        self.tableVersionNumber = unpack('>l', handle.read(4) )[0]
        self.numGlyphs          = unpack('>H', handle.read(2) )[0]
        self.maxPoints          = unpack('>H', handle.read(2) )[0]
        self.maxContours        = unpack('>H', handle.read(2) )[0]
        self.maxCompositePoints = unpack('>H', handle.read(2) )[0]
        self.maxCompositeContours = unpack('>H', handle.read(2) )[0]
        self.maxZones           = unpack('>H', handle.read(2) )[0]
        self.maxTwilightPoints  = unpack('>H', handle.read(2) )[0]
        self.maxStorage         = unpack('>H', handle.read(2) )[0]
        self.maxFunctionDefs    = unpack('>H', handle.read(2) )[0]
        self.maxInstructionDefs = unpack('>H', handle.read(2) )[0]
        self.maxStackElements   = unpack('>H', handle.read(2) )[0]
        self.maxSizeOfInstructions = unpack('>H', handle.read(2) )[0]
        self.maxComponentElements  = unpack('>H', handle.read(2) )[0]
        self.maxComponentDepth     = unpack('>H', handle.read(2) )[0]


    def fuzze(self):
        #WTF: fuzz all the values
        pass

class HeadTable(FontTable):

    def __init__(self, handle):

        self.tableVersionNumber = unpack('>l', handle.read(4) )[0]
        self.fontRevision       = unpack('>l', handle.read(4) )[0]
        self.checkSumAdjustement= unpack('>L', handle.read(4) )[0]
        self.magicNumber        = unpack('>L', handle.read(4) )[0]
        self.flags              = unpack('>H', handle.read(2) )[0]
        self.unitsPerEm         = unpack('>H', handle.read(2) )[0]
        self.created            = unpack('>Q', handle.read(8) )[0]
        self.modified           = unpack('>Q', handle.read(8) )[0]
        self.xMin               = unpack('>h', handle.read(2) )[0]
        self.yMin               = unpack('>h', handle.read(2) )[0]
        self.xMax               = unpack('>h', handle.read(2) )[0]
        self.yMax               = unpack('>h', handle.read(2) )[0]
        self.macStyle           = unpack('>H', handle.read(2) )[0]
        self.lowestRecPPEM      = unpack('>H', handle.read(2) )[0]
        self.fontDirectionHint  = unpack('>h', handle.read(2) )[0]
        self.indexToLocFormat   = unpack('>h', handle.read(2) )[0]
        self.glyphDataFormat    = unpack('>h', handle.read(2) )[0]

    def fuzz(self):
        pass
        # WTF:
        # screw flags value
        # unitsPerEm range is 16-16384



"""
caller must set the handle offset before
"""
class GlyphTable(FontTable):

    def __init__(self, handle):


        self.positionWithinFile = handle.tell()
        
        # FOLLOWING CODE when called on fuzzed samples (i.e. native_glyf.shortNameMine) gives
        # exceptions obviously
        self.header = self.GlyphTableHeader(handle)


        # if a glyph has zero contours, it need not have any glyph data
        # should happen only with the last 'fake' glyph
        if self.header.numberOfCountours == 0: 
            #print '[*] \t\t last'
            self.glyph = None
        elif self.header.numberOfCountours < 0:
            #print '[*] \t\t composite'
            self.glyph = self.CompositeGlyph(handle, self.header)
        else:
            #print '[*] \t\t simple'
            self.glyph = self.SimpleGlyph(handle, self.header)


        self.length = handle.tell() - self.positionWithinFile

    """
    Fuzz bytecode of the glyph table, return a buffer with the fuzzed table
    """
    def fuzzBytecode(self, fileInMemory):

        print '[DD] Start fuzz GLYPH'

        if self.glyph.bytecodeStartFileOffset is None or self.glyph.bytecodeEndFileOffset is None:
            #print '[D] \t Found no bytecode'
            return fileInMemory


        # find bytecode offset within font file
        startOffset = self.glyph.bytecodeStartFileOffset
        endOffset = self.glyph.bytecodeEndFileOffset


        print '[D] \t fuzzing between offsets {} and {}'.format(startOffset, endOffset)



        data = fileInMemory[startOffset:endOffset]
        assert len(data) == endOffset - startOffset, "Couldn't read enough bytes"


        radamsa = False
        if radamsa:
            # write the table to file, then fuzz it
            file_name = 'tmp_table'
            t = open(file_name, 'wb')
            t.write(data)
            t.close()
            output = subprocess.check_output(['radamsa-0.3.exe', file_name])[:len(data)]


            # pad with 0xf atm
            while len(output) < len(data):
                output += pack('>b', 0xf)

        else:

            output = []
            l = len(data)
            i = 0

            byteCopied = 0
            byteRandom = 0

            while i < l:

                if (random.randrange(256) % 3) == 0 and bool(random.getrandbits(1)) :

                    # copy a random chunk of bytes from existing buffer into randomized one
                    t = random.randrange(l-i)
                    for j in range(0, t):
                        output.append( data[i+j] )

                    i+=t
                    byteCopied += t

                else:
                    e = pack('>B', random.randrange(256) )
                    output.append( e  )

                    i+=1
                    byteRandom += 1

            assert len(data) == byteRandom + byteCopied
            print '[D] \t bytecode size {} - random {} copied {}'.format(len(data), byteRandom, byteCopied)

            assert len(data) == len(output), 'data: {} output: {}'.format(len(data), len(output))
            output = ''.join(output)






        final_data = fileInMemory[0:startOffset] + output + fileInMemory[endOffset:]

        assert len(final_data) == len(fileInMemory)

        print '[DD] Return fuzz glyph'

        return final_data




    class GlyphTableHeader():

        def __init__(self, handle):

            # if negative -> composite glyph
            # if >=0      -> single glyph
            self.numberOfCountours      = unpack('>h', handle.read(2) )[0]
            
            LOGGER.debug('\tnumber of countour: {}'.format(self.numberOfCountours))

            # glyph's bounding box
            self.xMin                   = unpack('>h', handle.read(2) )[0]
            self.yMin                   = unpack('>h', handle.read(2) )[0]
            self.xMax                   = unpack('>h', handle.read(2) )[0]
            self.yMax                   = unpack('>h', handle.read(2) )[0]
            
            LOGGER.debug('\tglyph box: ({},{}) ({},{})'.format(self.xMin, self.yMin, self.xMax, self.yMax))
                                                               


    class CompositeGlyph():


        # a composite glyph is apparently composed by
        # some components and instructions
        def __init__(self, handle, header):

            self.bytecodeStartFileOffset = None
            self.bytecodeEndFileOffset   = None 


            self.components = []
            while True:
                component = self.CompositeGlyphComponent(handle)
                
                self.components.append( component )

                if not component.moreComponents():
                    # Following the last component are
                    # instructions for the composite
                    # character

                    if component.weHaveInstructions():
                        self.numInstr = unpack('>H', handle.read(2) )[0]

                        LOGGER.debug('[D]\tnumber of instruction {}'.format(self.numInstr))

                        if self.numInstr > 0:
                            self.bytecodeStartFileOffset = handle.tell()

                        self.instr = []
                        try:
                            for i in range(0, self.numInstr):
                                self.instr.append( unpack('>b', handle.read(1) ) [0] )

                        except Exception as e:
                            LOGGER.error( '[E]\tProbably read a wrong instruction number: {}'.format(e) )
                            print handle.tell()

                        if self.numInstr > 0:
                            self.bytecodeEndFileOffset = handle.tell()


                        break




        class CompositeGlyphComponent():

            def __init__(self, handle):
                self.flags          = unpack( '>H', handle.read(2) )[0]

                # index of the first contour
                self.glyphIndex     = unpack( '>H', handle.read(2) )[0]

                # data varies according to flags, see page 69
                if self.arg1And2AreWords():
                    self.argument1  = unpack('>h', handle.read(2) )[0]
                    self.argument2  = unpack('>h', handle.read(2) )[0]
                else:
                    # ( arg1 << 8 ) | arg2
                    self.arg1and2   = unpack('>H', handle.read(2) )[0] 

                if self.weHaveAScale():
                    self.scale      = unpack('>h', handle.read(2) )[0]

                elif self.weHaveAnXAndYScale():
                    self.xscale      = unpack('>h', handle.read(2) )[0]
                    self.yscale      = unpack('>h', handle.read(2) )[0]

                elif self.weHaveATwoByTwo():
                    self.xscale      = unpack('>h', handle.read(2) )[0]
                    self.scale01     = unpack('>h', handle.read(2) )[0]
                    self.scale10     = unpack('>h', handle.read(2) )[0]
                    self.yscale      = unpack('>h', handle.read(2) )[0]


            """
            If this is set, the arguments are words;
            otherwise, they are bytes
            """
            def arg1And2AreWords(self):
                return (self.flags & 1) != 0 


            """
            If this is set, the arguments are xy
            values; otherwise, they are points
            """
            def argsAreXYValues(self):
                return (self.flags & 2) != 0 

            """
            For the xy values if the preceding is
            true
            """
            def roundXYToGrid(self):
                return (self.flags & 4) != 0 

            """
            This indicates that there is a simple
            scale for the component. Otherwise,
            scale = 1.0
            """
            def weHaveAScale(self):
                return (self.flags & 8) != 0  


            """
            Indicates at least one more glyph after
            this one
            """
            def moreComponents(self):
                return (self.flags & 32) != 0  

            """
            The x direction will use a different
            scale from the y direction
            """
            def weHaveAnXAndYScale(self):
                return (self.flags & 64) != 0  


            """
            There is a 2 by 2 transformation that
            will be used to scale the component
            """
            def weHaveATwoByTwo(self):
                return (self.flags & 128) != 0 


            """
            Following the last component are
            instructions for the composite character
            """
            def weHaveInstructions(self):
                return (self.flags & 256) != 0

            """
            If set, this forces the aw and lsb (and rsb)
            for the composite to be equal to those from this original glyph. This
            works for hinted and unhinted characters
            """
            def useMyMetrics(self):
                return (self.flags & 512) != 0




    class SimpleGlyph():

        def __init__(self, handle, header):
            self.endPtsOfCountour = []
            for i in range(0, header.numberOfCountours):
                self.endPtsOfCountour.append( unpack('>H', handle.read(2))[0] )
            #    LOGGER.debug('\tend of countours: {}'.format(self.endPtsOfCountour[-1]) )

            

            # total number of bytes for instructions
            self.instructionLength = unpack('>H', handle.read(2))[0]

            self.bytecodeStartFileOffset = None
            self.bytecodeEndFileOffset   = None 

            if self.instructionLength > 0:
                self.bytecodeStartFileOffset = handle.tell()


            self.instructions = []

            for i in range(0, self.instructionLength):
                self.instructions.append( unpack('>B', handle.read(1) ) [0] )


            if len(self.instructions) > 0:
                self.bytecodeEndFileOffset = handle.tell()
                LOGGER.debug('\tnumber of instructions: {}'.format(len(self.instructions)))    
            

            # array of flags for each coordinate in outline
            self.glyphFlags = []
            initialNumberOfFlag = self.endPtsOfCountour[-1] + 1
            
            i = 0
            while i < initialNumberOfFlag:
                flags = GlyphTable.GlyphFlags(handle)

                # If set, the next byte specifies the number of additional
                # times this set of flags is to be repeated. In this way,
                # the number of flags listed can be smaller than the
                # number of points in a character.
                if flags.isRepeatSet():
                    LOGGER.debug('\trepeat {}'.format( flags.numberOfRepetition) )
                    i += flags.numberOfRepetition
                    
                self.glyphFlags.append( flags )
            
            #LOGGER.debug('\tnumber of coordinates: {} '.format(len(self.glyphFlags)))

           

            self.xCoordinates = []
            for i in range(0, len(self.glyphFlags) ):

                if self.glyphFlags[i].isXshortVectorSet():
                    self.xCoordinates.append( unpack('>B', handle.read(1)) [0] )
                else:
                    self.xCoordinates.append( unpack('>h', handle.read(2)) [0] )
                    
            self.yCoordinates = []
            for i in range(0, len(self.glyphFlags) ):

                if self.glyphFlags[i].isYshortVectorSet():
                    self.yCoordinates.append( unpack('>B', handle.read(1)) [0] )
                else:
                    self.yCoordinates.append( unpack('>h', handle.read(2)) [0] )



            #for i in range(0, len(self.glyphFlags) ):
            #    LOGGER.debug('\tcoords delta: ({}, {})'.format(self.xCoordinates[i], self.yCoordinates[i]))


    class GlyphFlags():

        def __init__(self, handle):

            self.flagAsByte = unpack('>B', handle.read(1) )[0]

            # if repeat is set the next byte is the number of repetition
            if self.isRepeatSet() == 1:
                self.numberOfRepetition = unpack('>B', handle.read(1) )[0]

        def numberOfRepetition(self):
            return self.numberOfRepetition

        

        def isOnCurveSet(self):
            return (self.flagAsByte & 1) != 0 


        """
        if set read 1 byte, else 2 bytes
        """
        def isXshortVectorSet(self):
            return (self.flagAsByte & 2) != 0

        """
        if set read 1 byte, else 2 bytes
        """
        def isYshortVectorSet(self):
            return (self.flagAsByte & 4) != 0

        """
        If set, the next byte specifies the number of additional
        times this set of flags is to be repeated. In this way,
        the number of flags listed can be smaller than the
        number of points in a character.
        """
        def isRepeatSet(self):
            return (self.flagAsByte & 8) != 0


        def isPositiveXshortVectorSet(self):
            return (self.flagAsByte & 16) != 0

        def isPositiveYshortVectorSet(self):
            return (self.flagAsByte & 32) != 0







'''
This table defines the mapping of character codes to the glyph index values
used in the font. It may contain more than one subtable, in order to support
more than one character encoding scheme


Character codes that do not correspond to any glyph 
in the font should be mapped to glyph index 0 (missing character)

'''
class CmapTable(FontTable):

    def __init__(self, handle, fontTableDirectory):

        handle.seek(fontTableDirectory.offset)

        self.cmapOffsetWithinFile = handle.tell()
        self.table = fontTableDirectory

        self.header = self.CmapTableHeader(handle)
        self.subTables = []

        LOGGER.debug('\tcmap: table version number {}'.format(self.header.tableVersionNumber))
        LOGGER.debug('\tcmap: number of encoding tables {}'.format(self.header.numberOfEncodingTables))

        for i in range(self.header.numberOfEncodingTables):
            #position = handle.tell()
            self.subTables.append( self.CmapSubTable(handle, self.cmapOffsetWithinFile ) )
            #handle.seek(position + 8)

    class CmapTableHeader():

        def __init__(self, handle):

            self.tableVersionNumber     = unpack('>H', handle.read(2) )[0]
            self.numberOfEncodingTables = unpack('>H', handle.read(2) )[0]

        def getContent(self):
            return pack('>H', self.tableVersionNumber) + pack('>H', self.numberOfEncodingTables)



    class CmapSubTable():

        def __init__(self, handle, cmapOffsetWithinFile):

            self.startOfTableOffset = handle.tell()
            self.cmapOffsetWithinFile = cmapOffsetWithinFile

            self.platformId = unpack('>H', handle.read(2) )[0]
            self.platformSpecificEncoding = unpack('>H', handle.read(2) )[0]
            self.byteOffset = unpack('>L', handle.read(4) )[0] # this offset is from startOfTableOffset


            # Format subtables might point to the same data

            # read at byteOffset to understand which Format is used
            savedHandle =  handle.tell()
            handle.seek( self.cmapOffsetWithinFile + self.byteOffset)
            fmt = unpack('>H', handle.read(2) )[0]
            LOGGER.debug('\tcmap: format {}'.format(fmt) )

            handle.seek( handle.tell() - 2)
            if fmt == 0:
                formatTable = self.Format0(handle)
            elif fmt == 4:
                formatTable = self.Format4(handle)
            elif fmt == 6:
                formatTable = self.Format6(handle)
            else:
                LOGGER.debug('\tcmap: Format table not parsed')
                raise Exception('Unknown format table')

            self.formatTable = formatTable

            handle.seek(savedHandle)






        def getContent(self):
            return pack('>H', self.platformId) + \
                   pack('>H', self.platformSpecificEncoding) + \
                   pack('>H', self.byteOffset)



        """
        a subtable can either be:
        - format 0
        - format 2
        - format 4
        """

        class Format0():

            def __init__(self, handle):
                self.offsetWithinFile = handle.tell()
                self.fmt = unpack('>H', handle.read(2) )[0]
                self.length = unpack('>H', handle.read(2) )[0]
                self.version = unpack('>H', handle.read(2) )[0]

                self.glyphIdArray = []
                for i in range(0, 256):
                    self.glyphIdArray.append( unpack('>B', handle.read(1))[0] )


        class Format4():

            def __init__(self, handle):

                self.offsetWithinFile = handle.tell()
                self.fmt = unpack('>H', handle.read(2) )[0]
                self.length = unpack('>H', handle.read(2) )[0]
                self.version = unpack('>H', handle.read(2) )[0]

                # 2 x segCount
                self.segCountX2 = unpack('>H', handle.read(2) )[0]

                self.searchRange = unpack('>H', handle.read(2) )[0]
                self.entrySelector = unpack('>H', handle.read(2) )[0]
                self.rangeShift = unpack('>H', handle.read(2) )[0]

                # WTF: end USHORT for *Count is 0xffff
                self.endCount = []
                for i in range(0, self.segCountX2 / 2 ):
                    self.endCount.append(unpack('>H', handle.read(2) )[0])

                # WTF: set to 0
                self.reservedPad = unpack('>H', handle.read(2) )[0]

                self.startCount = []
                for i in range(0, self.segCountX2 / 2 ):
                    self.startCount.append(unpack('>H', handle.read(2) )[0])

                self.idDelta = []
                for i in range(0, self.segCountX2 / 2 ):
                    self.idDelta.append(unpack('>H', handle.read(2) )[0])

                self.idRangeOffset = []
                for i in range(0, self.segCountX2 / 2 ):
                    self.idRangeOffset.append(unpack('>H', handle.read(2) )[0])

                self.glyphIdArray = []
                for i in range(0, (self.length - (handle.tell() - self.offsetWithinFile ) ) /2 ):
                    self.glyphIdArray.append (unpack('>H', handle.read(2) )[0])


        class Format6():

            def __init__(self, handle):
                self.offsetWithinFile = handle.tell()
                self.fmt = unpack('>H', handle.read(2) )[0]
                self.length = unpack('>H', handle.read(2) )[0]
                self.version = unpack('>H', handle.read(2) )[0]
                self.firstCode = unpack('>H', handle.read(2) )[0]
                self.entryCount = unpack('>H', handle.read(2) )[0]


                self.glyphIdArray = []
                for i in range(0, self.entryCount):
                    self.glyphIdArray.append( unpack('>H', handle.read(2))[0] )            


    # FIXME: Format stuff
    def getContent(self):
        data = self.header.getContent()

        for t in self.subTables:
            data += t.getContent()

        #print len(data), self.table.length

        assert len(data) == self.table.length, '[E] Length of content data != table length'

        return data


    def fuzz():
        pass

class HmtxTable(FontTable):


    def __init__(self, handle, fontTableDirectory, numberOfHMetrics, numGlyphs):

        self.hMetrics = []
        for i in range(0, numberOfHMetrics):
            self.hMetrics.append( self.LongHorMetric(handle) )


        self.leftSideBearing = []
        for i in range(0, numGlyphs - numberOfHMetrics):
            self.leftSideBearing.append( unpack('>h', handle.read(2))[0] )


    class LongHorMetric():

        def __init__(self, handle):
            self.advanceWidth = unpack('>H', handle.read(2))[0]
            self.lsb = unpack('>h', handle.read(2))[0]




class HheaTable(FontTable):


    def __init__(self, handle, fontTableDirectory):

        self.tableVersionNumber = unpack('>l', handle.read(4) )[0]
        self.ascender = unpack('>h', handle.read(2) )[0]
        self.descender = unpack('>h', handle.read(2) )[0]
        self.lineGap = unpack('>h', handle.read(2) )[0]
        self.advanceWidthMax = unpack('>H', handle.read(2) )[0]
        self.minLeftSideBearing = unpack('>h', handle.read(2) )[0]
        self.minRightSideBearing = unpack('>h', handle.read(2) )[0]
        self.xMaxExtent = unpack('>h', handle.read(2) )[0]
        self.caretSlopeRise = unpack('>h', handle.read(2) )[0]
        self.caretSlopeRun = unpack('>h', handle.read(2) )[0]
        self.reserved0 = unpack('>h', handle.read(2) )[0]
        self.reserved1 = unpack('>h', handle.read(2) )[0]
        self.reserved2 = unpack('>h', handle.read(2) )[0]
        self.reserved3 = unpack('>h', handle.read(2) )[0]
        self.reserved4 = unpack('>h', handle.read(2) )[0]
        self.metricDataFormat = unpack('>h', handle.read(2) )[0]
        self.numberOfHMetrics = unpack('>H', handle.read(2) )[0]



    def fuzz(self):
        #WTF: screw numberOfHMetrics
        pass


class KernTable(FontTable):

    def __init__(self, handle):

        self.version = unpack('>H', handle.read(2) )[0]
        self.nTables = unpack('>H', handle.read(2) )[0]

        self.subTables = []

        for i in range(0, self.nTables):

            fmt = unpack('>H', handle.read(2) )[0]
            handle.seek(handle.tell() - 2)

            LOGGER.debug('\tkern: subtable {}'.format(fmt))
            if fmt == 0:
                self.subTables.append(self.Format0(handle))
            elif fmt == 2:
                LOGGER.warn('\tkern: format2 subtable parser not completed')
                self.subTables.append(self.Format2(handle))                
            else:
                LOGGER.error('\tkern: unknown subtable {}'.format(fmt))
                raise Exception('kern: unknown subtable {}'.format(fmt))


    class Format0():

        def __init__(self, handle):
            self.offsetWithinFile = handle.tell()

            self.version = unpack('>H', handle.read(2) )[0]
            self.length = unpack('>H', handle.read(2) )[0]
            self.coverage = unpack('>H', handle.read(2) )[0]

            self.nPairs = unpack('>H', handle.read(2) )[0]
            self.searchRange = unpack('>H', handle.read(2) )[0]
            self.entrySelector = unpack('>H', handle.read(2) )[0]
            self.rangeShift = unpack('>H', handle.read(2) )[0]

            self.kerningPairs = []
            for i in range(0, self.nPairs):
                self.kerningPairs.append( self.KerningPair(handle) )


        class KerningPair():

            def __init__(self, handle):
                self.left = unpack('>H', handle.read(2) )[0]
                self.right = unpack('>H', handle.read(2) )[0]
                self.value = unpack('>h', handle.read(2) )[0]


    class Format2():


        def __init__(self, handle):
            self.offsetWithinFile = handle.tell()

            self.version = unpack('>H', handle.read(2) )[0]
            self.length = unpack('>H', handle.read(2) )[0]
            self.coverage = unpack('>H', handle.read(2) )[0]

            self.rowWitdh = unpack('>H', handle.read(2) )[0]
            self.leftClassTable = unpack('>H', handle.read(2) )[0]
            self.rightClassTable = unpack('>H', handle.read(2) )[0]
            self.array = unpack('>H', handle.read(2) )[0]


        class ClassTable():

            def __init__(self, handle):

                self.firstGlyph = unpack('>H', handle.read(2) )[0]
                self.nGlyphs = unpack('>H', handle.read(2) )[0]

    def fuzz(self):
        # WTF: fuzz format0 values
        pass


class NameTable(FontTable):

    def __init__(self, handle):

        self.offsetWithinFile = handle.tell()

        self.formatSelector = unpack('>H', handle.read(2) )[0]
        self.numberOfNameRecords = unpack('>H', handle.read(2) )[0]
        self.offsetToStartOfStringStorage = unpack('>H', handle.read(2) )[0]

        self.nameRecords = []
        for i in range(0, self.numberOfNameRecords):
            self.nameRecords.append( self.NameRecord( handle ) )


    class NameRecord():

        def __init__(self, handle):

            self.platformId = unpack('>H', handle.read(2) )[0]
            self.encodingId = unpack('>H', handle.read(2) )[0]
            self.languageId = unpack('>H', handle.read(2) )[0]
            self.nameId = unpack('>H', handle.read(2) )[0]
            self.stringLength = unpack('>H', handle.read(2) )[0]
            self.stringOffsetFromStartOfStorage = unpack('>H', handle.read(2) )[0]



    def fuzz(self):
        # fuzz offsets
        pass



class OS2Table(FontTable):

    def __init__(self, handle):

        self.version = unpack('>H', handle.read(2) )[0]
        self.xAvgCharWidth = unpack('>h', handle.read(2) )[0]
        self.usWeightClass = unpack('>H', handle.read(2) )[0]
        self.usWidthClass = unpack('>H', handle.read(2) )[0]
        self.fsType = unpack('>h', handle.read(2) )[0]
        self.ySubscriptXSize = unpack('>h', handle.read(2) )[0]
        self.ySubscriptYSize = unpack('>h', handle.read(2) )[0]
        self.ySubscriptXOffset = unpack('>h', handle.read(2) )[0]
        self.ySubscriptYOffset = unpack('>h', handle.read(2) )[0]
        self.ySuperscriptXSize = unpack('>h', handle.read(2) )[0]
        self.ySuperscriptYSize = unpack('>h', handle.read(2) )[0]
        self.ySuperscriptXOffset = unpack('>h', handle.read(2) )[0]
        self.ySuperscriptYOffset = unpack('>h', handle.read(2) )[0]
        self.yStrikeoutSize = unpack('>h', handle.read(2) )[0]
        self.yStrikeoutPosition = unpack('>h', handle.read(2) )[0]
        self.sFamilyClass = unpack('>h', handle.read(2) )[0]
        self.panose = unpack('>BBBBBBBBBB', handle.read(10) )
        self.ulUnicodeRange1  = unpack('>L', handle.read(4) )[0]
        self.ulUnicodeRange2  = unpack('>L', handle.read(4) )[0]
        self.ulUnicodeRange3  = unpack('>L', handle.read(4) )[0]
        self.ulUnicodeRange4  = unpack('>L', handle.read(4) )[0]

        self.achVendID = ''.join(unpack('>cccc', handle.read(4) ) )
        LOGGER.debug( self.achVendID  )
        self.fsSelection = unpack('>H', handle.read(2) )[0]
        self.usFirstCharIndex = unpack('>H', handle.read(2) )[0]
        self.usLastCharIndex = unpack('>H', handle.read(2) )[0]
        self.sTypoAscender = unpack('>H', handle.read(2) )[0]
        self.sTypoDescender = unpack('>H', handle.read(2) )[0]
        self.sTypoLineGap = unpack('>H', handle.read(2) )[0]
        self.usWinAscent = unpack('>H', handle.read(2) )[0]
        self.usWinDescent = unpack('>H', handle.read(2) )[0]

        # commented, some fonts don't follow the spec..
        #self.ulCodePageRange1 = unpack('>L', handle.read(4) )[0]
        #self.ulCodePageRange2 = unpack('>L', handle.read(4) )[0]


    def fuzz(self):
        # WTF: fuzz the whole table
        pass

class PostTable(FontTable):

    def __init__(self, handle):

        self.formatType = unpack('>l', handle.read(4) )[0]
        self.italicAngle = unpack('>l', handle.read(4) )[0]
        self.underlinePosition = unpack('>h', handle.read(2) )[0]
        self.underlineThickness = unpack('>h', handle.read(2) )[0]
        self.isFixedPitch = unpack('L', handle.read(4) )[0]
        self.minMemType42 = unpack('L', handle.read(4) )[0]
        self.maxMemType42 = unpack('L', handle.read(4) )[0]
        self.minMemType1 = unpack('L', handle.read(4) )[0]
        self.maxMemType1 = unpack('L', handle.read(4) )[0]


        # If the format is 1.0 or 3.0, the table ends here.
        if self.formatType != 0x10000 and self.formatType != 0x30000:

            if self.formatType == 0x20000:
                self.format2 = self.Format2(handle)

            else:
                LOGGER.error('\tpost: unknown table format {}'.format(self.formatType) )

    class Format2():

        def __init__(self, handle):

            self.numGlyphs = unpack('>H', handle.read(2) )[0]

            # glyph name array maps the glyphs in this font to name index
            # 
            # If the name index is between 258 and
            # 32767, then subtract 258 and use that to index into the list of Pascal strings at
            # the end of the table.

            self.glyphNameIndex = []
            for i in range(0, self.numGlyphs):
                self.glyphNameIndex.append( unpack('>H', handle.read(2) )[0] )


            self.postName = []
            for i in self.glyphNameIndex:

                if i >= 258:

                    # read a p-string
                    self.postName.append( PostTable.Pstring(handle) )

    class Pstring():

        def __init__(self, handle):


            self.length = unpack('>B', handle.read(1) ) [0]

            self.string = []
            for i in range(0, self.length):
                self.string.append( unpack('>c', handle.read(1) ) [0] )

            self.string = ''.join(self.string)



    def fuzz(self):
        # WTF:
        # - numGlyphs should be the same as maxp table
        # - truncate the string table
        pass


class VdmxTable(FontTable):


    def __init__(self, handle):
        self.version = unpack('>H', handle.read(2) )[0]
        self.numRecs = unpack('>H', handle.read(2) )[0]
        self.numRatios = unpack('>H', handle.read(2) )[0]


        self.ratRange = []
        for i in range(0, self.numRatios):
            self.ratRange.append( self.Ratios(handle) )


        self.offset = []
        for i in range(0, self.numRatios):
            self.offset.append( unpack('>H', handle.read(2) ) [0] )


            # TODO: VDMX groups 

    class Ratios():

        def __init__(self, handle):

            self.bCharSet = unpack('>B', handle.read(1) )[0]
            self.xRatio = unpack('>B', handle.read(1) )[0]
            self.yStartRatio = unpack('>B', handle.read(1) )[0]
            self.yEndRatio = unpack('>B', handle.read(1) )[0]


class Utils():

    '''
    returns new buffer
    '''
    @staticmethod
    def doBufferHeadChecksum(fileInMemory, headDirectoryOffset):


        assert len(fileInMemory) % 4 == 0, 'File must be 4 byte aligned'

        # these var names are actually inverted..
        headDirectoryOffsetWithinTheFile = headDirectoryOffset 
        headTableOffset = unpack('>L', fileInMemory[headDirectoryOffset + 8: headDirectoryOffset + 12 ])[0]

        LOGGER.debug( '[D] Head headDirectoryOffsetWithinTheFile {} - headTableOffset {}'.format(headDirectoryOffsetWithinTheFile, headTableOffset) )

        total_data = 0

        # round length
        checksumLength = ( unpack('>L', fileInMemory[headDirectoryOffset + 12:headDirectoryOffset + 16])[0] + 3 ) & ~3

        # set checkSumAdjustement to 0 in the read buffer
        fileInMemory = fileInMemory[:headTableOffset + 8] + pack('>I', 0 ) + \
            fileInMemory[headTableOffset  + 12:]

        table = fileInMemory[headTableOffset:headTableOffset+checksumLength]

        LOGGER.debug( '[D] table size {}'.format(len(table)) )

        for i in range(0, len(table), 4):
            if i == 8:    # actually useless
                data = 0  # set checkSumAdjustement to 0 in the read buffer
                checkSumAdjustement = unpack('>I', table[i:i+4] ) [0]
            else:
                data = unpack('>I', table[i:i+4] ) [0]

            total_data += data

        headTableChecksum = 0xffffffff & total_data


        # head table checksum done, update checksum field in memory
        newFileInMemory = fileInMemory[0:headDirectoryOffsetWithinTheFile + 4] +  pack('>L', headTableChecksum) + \
            fileInMemory[headDirectoryOffsetWithinTheFile + 8:]

        LOGGER.debug( '[D] head table checksum {} @ {}'.format(headTableChecksum, headDirectoryOffsetWithinTheFile + 4) )

        # now, calculate entire font checksum
        total_data = 0

        #print len(newFileInMemory) % 4 

        # calculate new checkSumAdjustement value
        for i in range(0, len(newFileInMemory), 4):
            data = unpack('>I', newFileInMemory[i:i+4])[0]
            total_data += data

        newCheckSumAdjustement = total_data & 0xffffffff 
        newCheckSumAdjustement = (0xb1b0afba - newCheckSumAdjustement ) & 0xffffffff 

        LOGGER.debug( '[D] head newCheckSumAdjustement {}'.format(newCheckSumAdjustement) )


        # update
        newFileInMemory = newFileInMemory[:headTableOffset + 8] + pack('>I',newCheckSumAdjustement ) + \
            newFileInMemory[headTableOffset  + 12:]


        LOGGER.debug( '[D] updating newCheckSumAdjustement {} @ {}'.format(newCheckSumAdjustement, headTableOffset + 8 ) )


        return newFileInMemory    


    '''
    Compute ttf checksum for a buffer, i.e. a font table


    '''
    @staticmethod
    def doBufferChecksum(buf):
        total_data = 0

        # pad with 0s
        mod = len(buf) % 4
        while mod > 0:
            buf += chr(0x0)
            mod -= 1

        # round length
        checksumLength = (len(buf) + 3 ) & ~3

        #print len(buf), checksumLength

        for i in range(0, checksumLength, 4):
            data = unpack('>I', buf[i:i+4] ) [0]
            total_data += data

        final_data = 0xffffffff & total_data

        LOGGER.debug( '\n\tcalculated checksum: {}'.format(final_data) )


        return final_data




    '''
    aka millerfuzz:

    "As a note, in the CSW slides, the length divisor is a
    variable called 'fuzzfactor' - I just guessed at 10"

    numwrites = random.randrange( math.ceil((float(len(buf)) / FuzzFactor)))+1
    for j in range(numwrites):
      rbyte = random.randrange(256)rn = random.randrange(len(buf))
      buf[rn] = "%c"%(rbyte)
      numwrites = random.randrange(math.ceil((float(len(buf)) / FuzzFactor)))+1

      for j in range(numwrites):
        rbyte = random.randrange(256)rn = random.randrange(len(buf))
    buf[rn] = "%c"%(rbyte);

    '''
    @staticmethod
    def fuzzBufferBitFlipping(buf, maxWrites, fuzzFactor=10):
        fileInMemory = list(buf)



        #fuzzFactor = 0
        #while fuzzFactor < 1:
        #    fuzzFactor = random.random() * random.random() * 500
        #fuzzFactor = 10 

        numwrites = random.randrange( math.ceil( (float(len(fileInMemory) ) / fuzzFactor) ) )  + 1

        if numwrites > maxWrites:
            numwrites = random.randrange(maxWrites)
        

        #print 'ff',  len(buf)/fuzzFactor, 'writes', numwrites

        LOGGER.debug('BitFlipper: changing {} / {} bytes '.format(numwrites, len(fileInMemory)) )

        # bit flip
        for j in range(numwrites):
            rbyte = random.randrange(256)
            rn = random.randrange(len(fileInMemory))
            fileInMemory[rn] = "%c"%(rbyte);


        fileInMemory = ''.join(fileInMemory)


        return fileInMemory, numwrites

    '''
    N.B
    - this fuzzer returns buffer with different size wrt the original
    - changed the frequencies of mutations/junk insertions
    - align to 4


    a] mutations: it takes successive chunks and mutates them:
    - increments a bit
    - decrements a bit
    - tries some binary corner cases also allowing for endian

    b] insertions/deletion: every so often (in this case, every 128th of the file) it 
    also inserts a bunch of junk. The junk is a mix of:
    - raw random
    - ascii
    - some wacked unicode
    - some terminators and special chars


    '''
    @staticmethod
    def fuzzBufferBenFuzz(buf, fuzzFactor2):
        buf = list(buf)


        # a] mutations

        fuzzFactor = 0
        while fuzzFactor < 1:
            fuzzFactor = random.random() * random.random() * 10    
            
        m = math.ceil( (float( len(buf) ) / fuzzFactor ) / fuzzFactor2 )
        numberOfMutations = random.randrange( m )    

        LOGGER.info('BenFuzz: mutations {}/{} - buffer size {}'.format(numberOfMutations, int(m), len(buf) ) )


        # how many
        for i in range(numberOfMutations):

            # where
            position = random.randrange(len(buf) )

            mutationType = random.randrange(5)

            # 1] increment
            if mutationType == 1:
                try:
                    buf[position] = '%c' % ( ord(buf[position]) + int('0b1', 2) )
                except OverflowError as e:
                    buf[position] = '%c' % 0x0

            # 2] decrement
            elif mutationType == 2:
                try:
                    buf[position] = '%c' % ( ord(buf[position]) - int('0b1', 2) )
                except OverflowError as e:
                    buf[position] = '%c' % 0xf

            elif mutationType == 3:
                buf[position] = '%c' % ( ord(buf[position]) | 0x8 )

            elif mutationType == 4:
                buf[position] = '%c' % ( ord(buf[position]) ^ 0xf )



        # b] insertions
        
        fuzzFactor = 10
        while fuzzFactor < 1:
            fuzzFactor = random.random() * random.random() * 10    


        m = math.ceil( (float( len(buf) ) / fuzzFactor ) / (fuzzFactor2 / 2)  )
        numberOfJunkInsertion = random.randrange( m )

        LOGGER.info('BenFuzz: junk insertions {}/{} - buffer size {}'.format(numberOfJunkInsertion, int(m), len(buf) ) )



        # how many
        for i in range(numberOfJunkInsertion):

            # where 
            position = random.randrange( len(buf) )

            insertionType = random.randrange( 5 )

            # 1] insert raw random
            if insertionType == 1:
                buf = buf[:position] + list('%c' % random.randrange(256) ) + buf[position:]

            # 2] insert ascii
            elif insertionType == 2:
                buf = buf[:position] + list('%c' % ord(random.choice(string.ascii_letters))) + buf[position:]

            # 3] remove a byte
            elif insertionType == 3:
                buf = buf[:position - 1] + buf[position:]

            # 4] insert null
            elif insertionType == 4:
                buf = buf[:position] + list('%c' % 0x0) + buf[position:]



        # pad with 0s

        while len(buf) % 4 != 0:
            buf += chr(0x0)

        assert len(buf) % 4 == 0, 'WTF {}'.format(len(buf))

        return buf, numberOfMutations + numberOfJunkInsertion    


if __name__ == '__main__':


    if len(sys.argv) == 2:
        LOGGER.debug('[*] arsing {}'.format(sys.argv[1]))
        
        f = TTFont(sys.argv[1])
        #table = random.choice(list(set(f.fontTableDirectories.keys()) - set(TTFont.REQUIRED_TABLES) ))    
        #fuzzFactor =  f.fontTableDirectories[table].length / 50
        
        #if fuzzFactor < 2:
        #    fuzzFactor = 2
        
        #LOGGER.info('[*]\t{}'.format( table ))
        #font = f.fuzzBenStyle(table, fuzzFactor)
        #font = f.fuzzBenStyle('glyf', 80)
        
        #font = f.fuzzGlyfsBitFlipping()
        #open('test/testCase', 'wb').write(font[0])
        name = f.fontTableDirectories['name'].table
        f = open( sys.argv[1],'rb')
        
        for i in name.nameRecords:
            
            if i.platformId != 3:
                continue
            
            offset = name.offsetWithinFile + name.offsetToStartOfStringStorage + i.stringOffsetFromStartOfStorage
            f.seek(offset)
            item = unpack('>{}s'.format(i.stringLength), f.read(i.stringLength))[0]
            
            # unicode
            if i.encodingId == 1:
                item = unicode(item, 'utf-16-be').encode('utf-8')

            print i.nameId,  item, i.stringLength

        

    if len(sys.argv) == 3:
        LOGGER.debug('Parsing {}'.format(sys.argv[1]))
        for i in os.listdir(sys.argv[2]):
            print '% {}'.format(i)
            try:
                TTFont(i)
            except:
                continue