Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Download and use 16-bit SkiFree for NE tests #90

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 19 additions & 9 deletions .github/workflows/legobin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,39 @@ on:
workflow_call:

jobs:
fetch:
lego:
runs-on: ubuntu-latest
steps:

- name: Restore cached original binaries
id: cache-original-binaries
uses: actions/cache/restore@v3
- name: Cache original binaries
id: cache-lego
uses: actions/cache@v3
with:
enableCrossOsArchive: true
path: legobin
key: legobin

- name: Download original island binaries
if: ${{ !steps.cache-original-binaries.outputs.cache-hit }}
if: ${{ !steps.cache-lego.outputs.cache-hit }}
run: |
wget https://legoisland.org/download/CONFIG.EXE --directory-prefix=legobin
wget https://legoisland.org/download/ISLE.EXE --directory-prefix=legobin
wget https://legoisland.org/download/LEGO1.DLL --directory-prefix=legobin

skifree:
runs-on: ubuntu-latest
steps:

- name: Cache original binaries
if: ${{ !steps.cache-original-binaries.outputs.cache-hit }}
uses: actions/cache/save@v3
id: cache-skifree
uses: actions/cache@v3
with:
enableCrossOsArchive: true
path: legobin
key: legobin
path: skifree
key: skifree

- name: Download original ski binaries
if: ${{ !steps.cache-skifree.outputs.cache-hit }}
run: |
wget https://archive.org/download/win3_SKIFREE/SKIFREE.ZIP
unzip -d skifree SKIFREE.ZIP
14 changes: 11 additions & 3 deletions .github/workflows/unittest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,22 @@ jobs:
python-version: ${{ matrix.python-version }}
cache: 'pip'

- name: Restore cached binary files
id: cache-original-binaries
- name: Restore lego files
id: cache-lego
uses: actions/cache/restore@v3
with:
enableCrossOsArchive: true
path: legobin
key: legobin

- name: Restore skifree files
id: cache-skifree
uses: actions/cache/restore@v3
with:
enableCrossOsArchive: true
path: skifree
key: skifree

- name: Install python libraries
shell: bash
run: |
Expand All @@ -44,4 +52,4 @@ jobs:
- name: Run unit tests
shell: bash
run: |
pytest . --lego1=legobin/LEGO1.DLL
pytest . --lego1=legobin/LEGO1.DLL --ski=skifree/SKI.EXE
1 change: 1 addition & 0 deletions reccmp/isledecomp/formats/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from .detect import detect_image
from .image import Image
from .mz import MZImage
from .ne import NEImage
from .pe import PEImage
2 changes: 1 addition & 1 deletion reccmp/isledecomp/formats/ne.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class NewExeHeader:
def from_memory(cls, data: bytes, offset: int) -> tuple["NewExeHeader", int]:
if not cls.taste(data, offset):
raise ValueError
struct_fmt = "<2s2BHI17HI3H2B4H"
struct_fmt = "<2s2B2HI16HI3H2B4H"
struct_size = struct.calcsize(struct_fmt)
# fmt: off
items: tuple[bytes, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int] = (
Expand Down
28 changes: 26 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,22 @@
from typing import Iterator
import pytest

from reccmp.isledecomp import PEImage, detect_image
from reccmp.isledecomp import NEImage, PEImage, detect_image


def pytest_addoption(parser):
"""Allow the option to run tests against the original LEGO1.DLL."""
"""Allow the option to run tests against sample binaries."""
parser.addoption("--lego1", action="store", help="Path to LEGO1.DLL")
parser.addoption("--ski", action="store", help="Path to SKI.EXE")


# LEGO1.DLL: v1.1 English, September
LEGO1_SHA256 = "14645225bbe81212e9bc1919cd8a692b81b8622abb6561280d99b0fc4151ce17"

# SkiFree 1.0
# https://ski.ihoc.net/
SKI_SHA256 = "0b97b99fcf34af5f5d624080417c79c7d36ae11351a7870ce6e0a476f03515c2"


@pytest.fixture(name="binfile", scope="session")
def fixture_binfile(pytestconfig) -> Iterator[PEImage]:
Expand All @@ -32,3 +37,22 @@ def fixture_binfile(pytestconfig) -> Iterator[PEImage]:
image = detect_image(filename)
assert isinstance(image, PEImage)
yield image


@pytest.fixture(name="skifree", scope="session")
def fixture_skifree(pytestconfig) -> Iterator[NEImage]:
filename = pytestconfig.getoption("--ski")

# Skip this if we have not provided the path to SKI.EXE.
if filename is None:
pytest.skip(allow_module_level=True, reason="No path to SKI")

filename = Path(filename)
with filename.open("rb") as f:
digest = hashlib.sha256(f.read()).hexdigest()
if digest != SKI_SHA256:
pytest.fail(reason="Did not match expected SKI.EXE")

image = detect_image(filename)
assert isinstance(image, NEImage)
yield image
14 changes: 14 additions & 0 deletions tests/test_image_ne.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from reccmp.isledecomp.formats import NEImage
from reccmp.isledecomp.formats.ne import NESegmentFlags, NETargetOSFlags


def test_vitals(skifree: NEImage):
# Linker version 5.5
assert (skifree.header.ne_ver, skifree.header.ne_rev) == (5, 5)
assert skifree.header.ne_enttab == 0x526
assert skifree.header.ne_cbenttab == 0x88
assert skifree.header.ne_heap == 0x4000
assert skifree.header.ne_stack == 0x4000
assert skifree.header.ne_flags == NESegmentFlags.NEINST | NESegmentFlags.NEWINAPI
assert skifree.header.ne_exetyp == NETargetOSFlags.NE_WINDOWS
assert skifree.header.ne_flagsothers == 8 # according to ghidra