moz2d_bin2cpp.py (4207B)
1 #!/usr/bin/env python 2 # This Source Code Form is subject to the terms of the Mozilla Public 3 # License, v. 2.0. If a copy of the MPL was not distributed with this 4 # file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 6 from argparse import ArgumentParser 7 from pathlib import Path 8 from struct import calcsize, unpack 9 10 WR_IMAGEFORMATS = { 11 1: "R8", 12 2: "R16", 13 3: "BGRA8", 14 4: "RGBAF32", 15 5: "RG8", 16 6: "RG16", 17 7: "RGBAI32", 18 8: "RGBA8", 19 } 20 21 22 def bytes_to_hex_literal(data): 23 # data is bytes 24 # yields hex formatted strings like "0xFF" 25 # this can be simplified in 3.8+ using bytes.hex(sep=",").split(",") 26 hexified = iter(data.hex().upper()) 27 28 # see grouper in itertools recipes 29 for result in zip(hexified, hexified): 30 yield f"0x{''.join(result)}" 31 32 33 def unpack_fp(fmt, fp): 34 # fmt is a struct format string 35 # fp is an open file handle 36 # returns tuple as per struct.unpack(fmt, ...) 37 size = calcsize(fmt) 38 return unpack(fmt, fp.read(size)) 39 40 41 def main(): 42 aparse = ArgumentParser() 43 aparse.add_argument("dump", type=Path, help="A Moz2D libFuzzer testcase to read") 44 args = aparse.parse_args() 45 46 with args.dump.open("rb") as dump: 47 ( 48 aFormat, # B 49 aRenderRect_min_x, # 8i 50 aRenderRect_min_y, 51 aRenderRect_max_x, 52 aRenderRect_max_y, 53 aVisibleRect_min_x, 54 aVisibleRect_min_y, 55 aVisibleRect_max_x, 56 aVisibleRect_max_y, 57 aTileSize, # H 58 ) = unpack_fp("=B8iH", dump) 59 60 if aTileSize: 61 (aTileOffset_x, aTileOffset_y) = unpack_fp("=2i", dump) 62 63 (aDirtyRect_notnull,) = unpack_fp("=B", dump) 64 65 if aDirtyRect_notnull: 66 ( 67 aDirtyRect_min_x, 68 aDirtyRect_min_y, 69 aDirtyRect_max_x, 70 aDirtyRect_max_y, 71 ) = unpack_fp("=4i", dump) 72 73 (output_len,) = unpack_fp("=I", dump) 74 75 blob_len = 0 76 77 print("const uint8_t blob_buffer[] = {") 78 while True: 79 line = tuple(bytes_to_hex_literal(dump.read(16))) 80 if not line: 81 break 82 blob_len += len(line) 83 print(f" {', '.join(line)},") 84 print("};") 85 86 print(f"uint8_t output_buffer[{output_len}];") 87 88 print("auto aRenderRect = mozilla::wr::LayoutIntRect {") 89 print(f" .min: {{ .x: {aRenderRect_min_x}, .y: {aRenderRect_min_y} }},") 90 print(f" .max: {{ .x: {aRenderRect_max_x}, .y: {aRenderRect_max_y} }},") 91 print("};") 92 print("auto aVisibleRect = mozilla::wr::DeviceIntRect {") 93 print(f" .min: {{ .x: {aVisibleRect_min_x}, .y: {aVisibleRect_min_y} }},") 94 print(f" .max: {{ .x: {aVisibleRect_max_x}, .y: {aVisibleRect_max_y} }},") 95 print("};") 96 97 if aTileSize: 98 print(f"uint16_t tileSize = {aTileSize};") 99 print("auto aTileOffset = mozilla::wr::TileOffset {") 100 print(f" .x: {aTileOffset_x}, .y: {aTileOffset_y},") 101 print("};") 102 aTileSize = "tileSize" 103 aTileOffset = "&aTileOffset" 104 else: 105 aTileSize = "0" 106 aTileOffset = "nullptr" 107 108 if aDirtyRect_notnull: 109 print("auto aDirtyRect = mozilla::wr::LayoutIntRect {") 110 print(f" .min: {{ .x: {aDirtyRect_min_x}, .y: {aDirtyRect_min_y} }},") 111 print(f" .max: {{ .x: {aDirtyRect_max_x}, .y: {aDirtyRect_max_y} }},") 112 print("};") 113 aDirtyRect = "&aDirtyRect" 114 else: 115 aDirtyRect = "nullptr" 116 117 print() 118 print("wr_moz2d_render_cb(") 119 print(f" mozilla::wr::ByteSlice {{ .buffer: blob_buffer, .len: {blob_len} }},") 120 if aFormat in WR_IMAGEFORMATS: 121 print(f" mozilla:wr::ImageFormat::{WR_IMAGEFORMATS[aFormat]},") 122 else: 123 print(f" {aFormat}, // mozilla:wr::ImageFormat::?") 124 print(" &aRenderRect, &aVisibleRect,") 125 if aTileSize or aDirtyRect_notnull: 126 print(f" {aTileSize}, {aTileOffset},") 127 print(f" {aDirtyRect},") 128 else: 129 print(f" {aTileSize}, {aTileOffset}, {aDirtyRect},") 130 print( 131 f" mozilla::wr::MutByteSlice {{ .buffer: output_buffer," 132 f" .len: {output_len} }});" 133 ) 134 135 136 if __name__ == "__main__": 137 main()