Skip to content

PSX: header parsing fails if the 0x4C section contains non-ASCII bytes #545

Description

@FaultyRAM

Currently, splat fails to parse the executables from King's Field (Japan) with this error:

Traceback (most recent call last):
  File "/usr/bin/splat", line 8, in <module>
    sys.exit(splat_main())
             ~~~~~~~~~~^^
  File "/usr/lib/python3.14/site-packages/splat/__main__.py", line 27, in splat_main
    args.func(args)
    ~~~~~~~~~^^^^^^
  File "/usr/lib/python3.14/site-packages/splat/scripts/split.py", line 687, in process_arguments
    main(
    ~~~~^
        args.config,
        ^^^^^^^^^^^^
    ...<6 lines>...
        args.make_full_disasm_for_code,
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/usr/lib/python3.14/site-packages/splat/scripts/split.py", line 621, in main
    do_split(all_segments, rom_bytes, stats, cache)
    ~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.14/site-packages/splat/scripts/split.py", line 358, in do_split
    segment.split(segment_bytes)
    ~~~~~~~~~~~~~^^^^^^^^^^^^^^^
  File "/usr/lib/python3.14/site-packages/splat/segtypes/common/header.py", line 36, in split
    header_lines = self.parse_header(rom_bytes)
  File "/usr/lib/python3.14/site-packages/splat/segtypes/psx/header.py", line 60, in parse_header
    self.get_line("ascii", rom_bytes[0x4C : self.rom_end], "Sony Inc")
    ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.14/site-packages/splat/segtypes/common/header.py", line 19, in get_line
    text = data.decode("ASCII").strip()
           ~~~~~~~~~~~^^^^^^^^^
UnicodeDecodeError: 'ascii' codec can't decode byte 0xea in position 58: ordinal not in range(128)

What's happening here is that the 0x4C header section contains a null-terminated ASCII string followed by trailing bytes, some of which are non-ASCII. PsxSegHeader::parse_header assumes the entire section is valid ASCII, so it passes this data to CommonSegHeader::get_line, which tries to decode it and promptly dies.

It's probably easiest to just treat this section as an arbitrary byte sequence. AFAICT it isn't actually used for anything, i.e. the contents are not meaningful and only contain a null-terminated ASCII string by convention.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions