mirror of
https://github.com/luau-lang/luau.git
synced 2024-11-15 14:25:44 +08:00
e5ec0cdff3
## What's changed - `bit32.byteswap` added ([RFC](4f543ec23b/docs/function-bit32-byteswap.md
)) - Buffer library implementation ([RFC](4f543ec23b/docs/type-byte-buffer.md
)) - Fixed a missing `stdint.h` include - Fixed parser limiter for recursive type annotations being kind of weird (fixes #645) ### Native Codegen - Fixed a pair of issues when lowering `bit32.extract` - Fixed a narrow edge case that could result in an infinite loop without an interruption - Fixed a negative array out-of-bounds access issue - Temporarily reverted linear block predecessor value propagation ### New type solver - We now type check assignments to annotated variables - Fixed some test cases under local type inference - Moved `isPending` checks for type families to improve performance - Optimized our process for testing if a free type is sufficiently solved - Removed "none ptr" from lea instruction disassembly logging ### Build system & tooling - CMake configuration now validates dependencies to maintain separation between components - Improvements to the fuzzer coverage - Deduplicator for fuzzed callstacks --------- Co-authored-by: Arseny Kapoulkine <arseny.kapoulkine@gmail.com> Co-authored-by: Vyacheslav Egorov <vegorov@roblox.com> Co-authored-by: Andy Friesen <afriesen@roblox.com> Co-authored-by: Aaron Weiss <aaronweiss@roblox.com> Co-authored-by: Vighnesh Vijay <vvijay@roblox.com>
47 lines
1.4 KiB
Python
47 lines
1.4 KiB
Python
#!/usr/bin/python3
|
|
# This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
|
|
|
# Given a fuzzer binary and a list of crashing programs, this tool collects unique crash reasons and prints reproducers.
|
|
|
|
import re
|
|
import sys
|
|
import subprocess
|
|
|
|
def get_crash_reason(binary, file):
|
|
res = subprocess.run([binary, file], stdout=subprocess.DEVNULL, stderr=subprocess.PIPE)
|
|
if res.returncode == 0:
|
|
print(f"Warning: {binary} {file} returned 0")
|
|
return None
|
|
err = res.stderr.decode("utf-8")
|
|
|
|
if (pos := err.find("ERROR: libFuzzer:")) != -1:
|
|
return err[pos:]
|
|
|
|
print(f"Warning: {binary} {file} returned unrecognized error {err}")
|
|
return None
|
|
|
|
def get_crash_fingerprint(reason):
|
|
# Due to ASLR addresses are different every time, so we filter them out
|
|
reason = re.sub(r"0x[0-9a-f]+", "0xXXXX", reason)
|
|
return reason
|
|
|
|
binary = sys.argv[1]
|
|
files = sys.argv[2:]
|
|
|
|
seen = set()
|
|
|
|
for index, file in enumerate(files):
|
|
reason = get_crash_reason(binary, file)
|
|
if reason is None:
|
|
continue
|
|
fingerprint = get_crash_fingerprint(reason)
|
|
if fingerprint in seen:
|
|
# print a spinning ASCII wheel to indicate that we're making progress
|
|
print("-\|/"[index % 4] + "\r", end="")
|
|
continue
|
|
seen.add(fingerprint)
|
|
print(f"Reproducer: {binary} {file}")
|
|
print(f"Crash reason: {reason}")
|
|
print()
|
|
|
|
print(f"Total unique crash reasons: {len(seen)}") |