File: moz2d_bin2cpp.py

package info (click to toggle)
firefox 147.0-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 4,683,324 kB
  • sloc: cpp: 7,607,156; javascript: 6,532,492; ansic: 3,775,158; python: 1,415,368; xml: 634,556; asm: 438,949; java: 186,241; sh: 62,751; makefile: 18,079; objc: 13,092; perl: 12,808; yacc: 4,583; cs: 3,846; pascal: 3,448; lex: 1,720; ruby: 1,003; php: 436; lisp: 258; awk: 247; sql: 66; sed: 54; csh: 10; exp: 6
file content (137 lines) | stat: -rwxr-xr-x 4,207 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/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()