mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-11-11 12:33:53 -06:00
feat: refuse a binary ref without a place in it
A source_ref part that names a compiled image now has to carry an address, a decompiled function or an IL method. An import directory, a string table or readelf output only says the binary exists. A name under a directory is a file of the tree and a .dll.map is not a DLL. The exception list is empty: every closed profile now cites code.
This commit is contained in:
1 parent
e00045ba0e
commit
8c18f12643
2 files changed
+55
-21
No files matched your search
+29
-17
@@ -161,34 +161,46 @@ _CODE_SUFFIXES = frozenset(
|
||||
"go rs lua pas pp asm s sh bash zsh ps1 bat cmd vbs swift d zig nim qml qc rb pl php "
|
||||
"scala ml hs dart vue ino z80 smali".split()
|
||||
)
|
||||
_CODE_FILE = re.compile(r"[\w+.-]\.([A-Za-z0-9+]+)\b")
|
||||
_BINARY_EVIDENCE = re.compile(
|
||||
r"\b0x[0-9a-fA-F]+\b|\bFUN_[0-9a-fA-F]+\b|\.(?:so|dll|exe|dylib|dex|apk|jar|elf|nro|xex)\b",
|
||||
_CODE_FILE = re.compile(r"(?<=[\w+-])\.([A-Za-z0-9+]+)\b")
|
||||
# A compiled image: a part that names one has to say where in it the file
|
||||
# is read, an address, a decompiled function or an IL method.
|
||||
# A name under a directory is a file of the tree it sits in, and a further
|
||||
# extension (.dll.map) makes it another file.
|
||||
_BINARY_FILE = re.compile(
|
||||
r"(?<![\w/+.-])[\w+.-]+\.(?:so|dll|exe|dylib|dex|elf|nro|xex)(?:\.\d+)*(?![\w.-]*\w)",
|
||||
re.IGNORECASE,
|
||||
)
|
||||
_BINARY_EVIDENCE = re.compile(
|
||||
r"\b0x[0-9a-fA-F]+\b"
|
||||
r"|\b(?:FUN|sub|thunk|LAB)_[0-9a-fA-F]+\b"
|
||||
r"|\bIL_[0-9a-fA-F]{4}\b"
|
||||
r"|::|\.\.c?ctor\b"
|
||||
r"|\b[A-Za-z_][\w.$]*\("
|
||||
)
|
||||
|
||||
# Profiles whose files cite no published code. Each reason says why the
|
||||
# check cannot apply yet.
|
||||
DATA_ONLY_REF_EXCEPTIONS: dict[str, str] = {
|
||||
"ace-dl": "closed source: the refs describe what the shipped binary opens",
|
||||
"cpcemu": "closed source: the refs describe what the shipped binary opens",
|
||||
"drastic": "closed source: the shader format files are read by the shipped binary",
|
||||
"lexaloffle": "closed source: PICO-8 reads pico8_gpio, the refs are its readme and the KNULLI install script",
|
||||
"mfme": "closed source: the refs are the release notes of the shipped binary",
|
||||
}
|
||||
DATA_ONLY_REF_EXCEPTIONS: dict[str, str] = {}
|
||||
|
||||
|
||||
def _ref_cites_code(ref: str) -> bool:
|
||||
"""A source_ref part names a source file, or a binary with an address."""
|
||||
"""A source_ref cites a source file or a place in a compiled image.
|
||||
|
||||
A part naming a binary without an address, a decompiled function or an
|
||||
IL method says only that the binary exists: "import directory",
|
||||
"string table" and "readelf -d" are not the code that reads a file.
|
||||
"""
|
||||
from sourceref import split_source_ref
|
||||
|
||||
if _BINARY_EVIDENCE.search(ref):
|
||||
return True
|
||||
cited = False
|
||||
for part in split_source_ref(ref):
|
||||
for suffix in _CODE_FILE.findall(part.raw):
|
||||
if suffix.lower() in _CODE_SUFFIXES:
|
||||
return True
|
||||
return False
|
||||
located = bool(_BINARY_EVIDENCE.search(part.raw)) or any(
|
||||
suffix.lower() in _CODE_SUFFIXES for suffix in _CODE_FILE.findall(part.raw)
|
||||
)
|
||||
if _BINARY_FILE.search(part.raw) and not located:
|
||||
return False
|
||||
cited = cited or located
|
||||
return cited
|
||||
|
||||
|
||||
def _data_only_source_refs(path: Path, document: object) -> list[str]:
|
||||
|
||||
@@ -53,17 +53,39 @@ class DataOnlySourceRefs(unittest.TestCase):
|
||||
|
||||
def test_a_binary_with_an_address_passes(self):
|
||||
for ref in ("libemucore.so 0x1a2b3c", "Fusion.exe 0x00401000",
|
||||
"bigpemu FUN_006d8be0 (BootROM read)", "nethersx2 v2.2n classes.dex icons/star-%d.png"):
|
||||
"bigpemu FUN_006d8be0 (BootROM read)",
|
||||
"CSpect.exe 3.3.1.0 a.H::e() IL_00bd-IL_00c9",
|
||||
"GameAssembly.dll DSP1..ctor (name and CRC32)",
|
||||
"libpizzaboy-jni.so pizza.c:931-937 (path buffer)"):
|
||||
with self.subTest(ref=ref):
|
||||
self.assertEqual(self.errors(ref), [])
|
||||
|
||||
def test_a_binary_named_without_a_place_in_it_is_refused(self):
|
||||
for ref in ("ArcadeFlashWeb v1.0.2 pepflashplayer.dll string table",
|
||||
"Future Pinball.exe 1.9.1.20101231 import directory",
|
||||
"Main.java:27302, libfpse.so readelf -d",
|
||||
"nethersx2 v2.2n classes.dex icons/star-%d.png",
|
||||
"Fusion.exe 0x00401000, PS3Eye.dll .rdata"):
|
||||
with self.subTest(ref=ref):
|
||||
self.assertEqual(len(self.errors(ref)), 1)
|
||||
|
||||
def test_a_binary_file_of_a_source_tree_is_a_path(self):
|
||||
self.assertEqual(self.errors(
|
||||
"src/loader/elfLoader/elfLoader.cpp:365, libs/win32/ll-deps/zlib1.dll"), [])
|
||||
self.assertEqual(self.errors(
|
||||
"src/emu/kernel/src/libmanager.cpp:549-566, src/patch/ecam/group/ecam.dll.map:190-193"), [])
|
||||
|
||||
def test_each_build_mode_is_judged(self):
|
||||
self.assertEqual(len(self.errors({"standalone": "src/main.cpp:10", "libretro": "data/list.txt:3"})), 1)
|
||||
|
||||
def test_an_excepted_profile_is_not_judged(self):
|
||||
name = next(iter(validate_schemas.DATA_ONLY_REF_EXCEPTIONS))
|
||||
path = REPO_ROOT / "emulators" / f"{name}.yml"
|
||||
self.assertEqual(validate_schemas._data_only_source_refs(path, _profile("history.txt:38")), [])
|
||||
path = REPO_ROOT / "emulators" / "synthetic.yml"
|
||||
exceptions = validate_schemas.DATA_ONLY_REF_EXCEPTIONS
|
||||
exceptions["synthetic"] = "binary found nowhere"
|
||||
try:
|
||||
self.assertEqual(validate_schemas._data_only_source_refs(path, _profile("history.txt:38")), [])
|
||||
finally:
|
||||
del exceptions["synthetic"]
|
||||
|
||||
def test_every_exception_names_a_profile_and_a_reason(self):
|
||||
for name, reason in validate_schemas.DATA_ONLY_REF_EXCEPTIONS.items():
|
||||
|
||||
Reference in new issue
Block a user