Skip to content
Merged
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
56 changes: 50 additions & 6 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
with:
toolchain: 1.98.1
components: rustfmt, clippy
targets: x86_64-unknown-linux-musl, aarch64-unknown-linux-musl, x86_64-pc-windows-gnu, i686-pc-windows-gnu, wasm32-wasip1
targets: x86_64-unknown-linux-musl, aarch64-unknown-linux-musl, x86_64-apple-darwin, aarch64-apple-darwin, x86_64-pc-windows-gnu, i686-pc-windows-gnu, wasm32-wasip1, wasm32-unknown-unknown

- name: Cache cargo
uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
Expand Down Expand Up @@ -69,8 +69,10 @@ jobs:
sudo apt-get update -qq
sudo apt-get install -y --no-install-recommends gcc-mingw-w64 musl-tools p7zip-full qemu-user-static

# zig, because mimalloc is C and apt has no aarch64-musl compiler, plus
# cargo-zigbuild for that cross-build and wasmtime for tests/wasm.sh.
# zig, because mimalloc is C and apt has no aarch64-musl compiler and the
# macOS build needs a Mach-O linker, plus cargo-zigbuild for those
# cross-builds, wasmtime for tests/wasm.sh and
# wasm-bindgen for the npm package.
# Versions and digests live in the script; ci.sh has already installed the
# gate tools it shares with this step.
- name: Install build tools
Expand Down Expand Up @@ -107,15 +109,18 @@ jobs:
run: |
cp target/x86_64-unknown-linux-musl/release/dat3 dat3
cp target/aarch64-unknown-linux-musl/release/dat3 dat3-arm64
cp target/universal2-apple-darwin/release/dat3 dat3-macos
cp target/x86_64-pc-windows-gnu/release/dat3.exe dat3.exe
cp target/i686-pc-windows-gnu/release/dat3.exe dat3-win32.exe
cp target/wasm32-wasip1/release/dat3.wasm dat3.wasm
cp target/dat3-wasm.tgz dat3-wasm.tgz

- name: Prepare debug assets
if: ${{ !startsWith(github.ref, 'refs/tags/v') }}
run: |
cp target/x86_64-unknown-linux-musl/debug/dat3 dat3-debug
cp target/aarch64-unknown-linux-musl/debug/dat3 dat3-arm64-debug
cp target/universal2-apple-darwin/debug/dat3 dat3-macos-debug
cp target/x86_64-pc-windows-gnu/debug/dat3.exe dat3-debug.exe
cp target/i686-pc-windows-gnu/debug/dat3.exe dat3-win32-debug.exe
cp target/wasm32-wasip1/debug/dat3.wasm dat3-debug.wasm
Expand All @@ -130,9 +135,11 @@ jobs:
path: |
dat3
dat3-arm64
dat3-macos
dat3.exe
dat3-win32.exe
dat3.wasm
dat3-wasm.tgz
if-no-files-found: error

- name: Upload debug artifacts
Expand All @@ -143,15 +150,16 @@ jobs:
path: |
dat3-debug
dat3-arm64-debug
dat3-macos-debug
dat3-debug.exe
dat3-win32-debug.exe
dat3-debug.wasm
if-no-files-found: error

# The declared rust-version is a promise to users, and nothing checked it: the
# build job pins a toolchain many releases newer, so code using a feature
# stabilised after 1.87 would compile there and fail for anyone honouring the
# README. The version is read from Cargo.toml rather than repeated here.
# stabilised after 1.87 would compile there and fail for anyone honouring
# docs/building.md. The version is read from Cargo.toml rather than repeated here.
msrv:
name: msrv
runs-on: ubuntu-latest
Expand All @@ -171,18 +179,52 @@ jobs:
uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # master
with:
toolchain: ${{ steps.msrv.outputs.version }}
targets: wasm32-unknown-unknown

# --locked so the committed lockfile is what gets checked, and --all-targets
# so the test code is covered too.
- name: Check against the declared MSRV
run: cargo check --all-targets --locked

# Not a default workspace member: it builds only for its wasm target
- name: Check the wasm library against the declared MSRV
run: cargo check -p dat3-wasm --target wasm32-unknown-unknown --locked

# The macOS binary is cross-built on Linux, where nothing can run it. One
# runner per architecture, so each slice of the universal binary is run.
macos:
name: macos (${{ matrix.runner }})
needs: ci
strategy:
matrix:
runner: [macos-26, macos-26-intel]
runs-on: ${{ matrix.runner }}
timeout-minutes: 10
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Download release artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: dat3
path: assets

# Artifacts do not keep the executable bit
- name: Test the macOS binary
env:
MACOS_DAT3: assets/dat3-macos
run: chmod +x "$MACOS_DAT3" && ./tests/macos.sh

# Separate job so contents:write exists only on a tag run, and only for the
# step that publishes. It builds nothing: the binaries come from the build
# job's artifact.
release:
name: release
needs: ci
needs: [ci, macos]
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
timeout-minutes: 10
Expand All @@ -208,9 +250,11 @@ jobs:
files: |
assets/dat3
assets/dat3-arm64
assets/dat3-macos
assets/dat3.exe
assets/dat3-win32.exe
assets/dat3.wasm
assets/dat3-wasm.tgz
assets/SHA256SUMS
fail_on_unmatched_files: true
env:
Expand Down
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

## Unreleased

- New: releases ship a macOS binary (`dat3-macos`), a universal binary that runs natively on Intel and Apple Silicon Macs. It is not notarized, so a copy downloaded in a browser has to be allowed in System Settings, or cleared with `xattr -d com.apple.quarantine dat3-macos`, before its first run.
- Fixed: a crafted Fallout 2 or Arcanum archive could make dat3 reserve gigabytes of memory for a single file name, and a crafted entry in any format could expand on extraction far past the size it declares. Entry paths are now limited to 1024 bytes, and an entry must decompress to exactly its declared size.
- Errors for damaged Fallout 1, Fallout 2 and Arcanum archives now report missing data in bytes rather than bits, and name the Fallout 2 entry that failed.
- Errors for damaged Fallout 1, Fallout 2 and Arcanum archives now report missing data in bytes rather than bits, and name the Fallout 1 or Fallout 2 entry that failed.
- Fixed: `l`, `x` and `e` reported a requested name as not found, and failed, when an earlier glob in the same command had already selected that file.
- Fixed: adding a file whose name or directory is longer than 255 bytes to a Fallout 1 archive wrote an archive that could not be opened again. The add now fails and leaves the archive untouched.
- Fixed: adding a file of 4 GiB or more wrote a corrupt archive. Such files are now refused.
Expand All @@ -16,7 +17,11 @@
- Entry names Windows cannot create as named are now refused on every platform, both when extracting and when adding: a `:` inside a name (which writes an NTFS alternate data stream), device names such as `CON`, `NUL`, `COM1` or `LPT1` with or without an extension, and names ending in a dot or space. Extraction checks every name first, so a refused name leaves nothing half-extracted.
- Fixed: when `e` met several files of the same name (ignoring case) in different directories, which copy ended up on disk varied from run to run. The last one in archive order now wins, and `e` warns how many were skipped.
- Fixed: `a` printed each "Skipping symlink" warning twice.
- Fixed: `x` and `e` wrote through a symlink already present at a file's destination, overwriting the file the link pointed to. The link is now replaced by the extracted file.
- Saving an archive now flushes it to disk before replacing the old file, and on Linux and macOS keeps the old file's permissions. Two dat3 runs saving the same archive at once no longer write into each other's temporary file, though the one that finishes last still replaces the other's changes. Archives with very long file names, which could not be saved, now save.
- New: the archive code is available to other Rust programs as the `dat3-core` library, used as a git dependency on this repository. Its API may still change between releases.
- New: releases ship `dat3-wasm.tgz`, an npm package of the same library for Node.js and Electron: open archives from bytes, list, read, add and remove entries, and write the result back out. It runs on every platform, with TypeScript types.
- Changed: `.bgforge.yml` sets the default format with a single flat key, `dat3.default_format: arcanum`. The nested form (`dat3:` with `default_format:` under it) is no longer read, so a config using it falls back to `dat2` until it is rewritten.

## v0.10.1

Expand Down
128 changes: 122 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading