Source code

Revision control

Copy as Markdown

Other Tools

#!/usr/bin/env python
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from argparse import ArgumentParser
from pathlib import Path
from struct import calcsize, unpack
WR_IMAGEFORMATS = {
1: "R8",
2: "R16",
3: "BGRA8",
4: "RGBAF32",
5: "RG8",
6: "RG16",
7: "RGBAI32",
8: "RGBA8",
}
def bytes_to_hex_literal(data):
# data is bytes
# yields hex formatted strings like "0xFF"
# this can be simplified in 3.8+ using bytes.hex(sep=",").split(",")
hexified = iter(data.hex().upper())
# see grouper in itertools recipes
for result in zip(hexified, hexified):
yield f"0x{''.join(result)}"
def unpack_fp(fmt, fp):
# fmt is a struct format string
# fp is an open file handle
# returns tuple as per struct.unpack(fmt, ...)
size = calcsize(fmt)
return unpack(fmt, fp.read(size))
def main():
aparse = ArgumentParser()
aparse.add_argument("dump", type=Path, help="A Moz2D libFuzzer testcase to read")
args = aparse.parse_args()
with args.dump.open("rb") as dump:
(
aFormat, # B
aRenderRect_min_x, # 8i
aRenderRect_min_y,
aRenderRect_max_x,
aRenderRect_max_y,
aVisibleRect_min_x,
aVisibleRect_min_y,
aVisibleRect_max_x,
aVisibleRect_max_y,
aTileSize, # H
) = unpack_fp("=B8iH", dump)
if aTileSize:
(aTileOffset_x, aTileOffset_y) = unpack_fp("=2i", dump)
(aDirtyRect_notnull,) = unpack_fp("=B", dump)
if aDirtyRect_notnull:
(
aDirtyRect_min_x,
aDirtyRect_min_y,
aDirtyRect_max_x,
aDirtyRect_max_y,
) = unpack_fp("=4i", dump)
(output_len,) = unpack_fp("=I", dump)
blob_len = 0
print("const uint8_t blob_buffer[] = {")
while True:
line = tuple(bytes_to_hex_literal(dump.read(16)))
if not line:
break
blob_len += len(line)
print(f" {', '.join(line)},")
print("};")
print(f"uint8_t output_buffer[{output_len}];")
print("auto aRenderRect = mozilla::wr::LayoutIntRect {")
print(f" .min: {{ .x: {aRenderRect_min_x}, .y: {aRenderRect_min_y} }},")
print(f" .max: {{ .x: {aRenderRect_max_x}, .y: {aRenderRect_max_y} }},")
print("};")
print("auto aVisibleRect = mozilla::wr::DeviceIntRect {")
print(f" .min: {{ .x: {aVisibleRect_min_x}, .y: {aVisibleRect_min_y} }},")
print(f" .max: {{ .x: {aVisibleRect_max_x}, .y: {aVisibleRect_max_y} }},")
print("};")
if aTileSize:
print(f"uint16_t tileSize = {aTileSize};")
print("auto aTileOffset = mozilla::wr::TileOffset {")
print(f" .x: {aTileOffset_x}, .y: {aTileOffset_y},")
print("};")
aTileSize = "tileSize"
aTileOffset = "&aTileOffset"
else:
aTileSize = "0"
aTileOffset = "nullptr"
if aDirtyRect_notnull:
print("auto aDirtyRect = mozilla::wr::LayoutIntRect {")
print(f" .min: {{ .x: {aDirtyRect_min_x}, .y: {aDirtyRect_min_y} }},")
print(f" .max: {{ .x: {aDirtyRect_max_x}, .y: {aDirtyRect_max_y} }},")
print("};")
aDirtyRect = "&aDirtyRect"
else:
aDirtyRect = "nullptr"
print()
print("wr_moz2d_render_cb(")
print(f" mozilla::wr::ByteSlice {{ .buffer: blob_buffer, .len: {blob_len} }},")
if aFormat in WR_IMAGEFORMATS:
print(f" mozilla:wr::ImageFormat::{WR_IMAGEFORMATS[aFormat]},")
else:
print(f" {aFormat}, // mozilla:wr::ImageFormat::?")
print(" &aRenderRect, &aVisibleRect,")
if aTileSize or aDirtyRect_notnull:
print(f" {aTileSize}, {aTileOffset},")
print(f" {aDirtyRect},")
else:
print(f" {aTileSize}, {aTileOffset}, {aDirtyRect},")
print(
f" mozilla::wr::MutByteSlice {{ .buffer: output_buffer,"
f" .len: {output_len} }});"
)
if __name__ == "__main__":
main()