Skip to content

Latest commit

 

History

History
105 lines (79 loc) · 4.57 KB

File metadata and controls

105 lines (79 loc) · 4.57 KB

Contributing

Development workflow notes for libjpeg-turbo-rs. User-facing documentation lives in README.md and on docs.rs.

Ground rules

  • All changes go through pull requests; CI must be green (the workspace gate cross-validates against C libjpeg-turbo byte-for-byte).
  • cargo fmt --all and cargo clippy --lib -- -D warnings before each commit (git config core.hooksPath .githooks installs the pre-commit hook).
  • Tests follow TDD and must cross-validate against C djpeg/cjpeg/ jpegtran where a C contract exists — see CLAUDE.md for the full testing rules, and docs/LAST_MILE.md for the live release gate.

C-ABI regression coverage

Both integration oracle jobs run every C-ABI test target, with PNG support:

LIBJPEG_TURBO_PREFIX=/path/to/v8/install \
LIBJPEG_TURBO_REFERENCE_DIR=/path/to/v8/install \
cargo test -p libjpeg-turbo-rs-capi --tests --features png --no-fail-fast

Cargo discovers new test targets automatically. oracle_version_pins guards this complete selection on both jobs; a named subset or compile-only command cannot replace it. The explicit v8 prefix makes the shared classic/TurboJPEG oracle helpers mandatory. Some older downstream harnesses still have their own prerequisite skips; executing every target does not prove every external consumer was available. --no-fail-fast collects failures across test binaries.

Issues worked on unattended

scripts/issue_loop.sh can work through the open issues without supervision, one fresh agent per issue; CLAUDE.md documents how to run it. Two label conventions come out of that, and both are meant for humans to use:

  • autofix-skip — put it on an umbrella or tracker issue that closes only when its children do, so no agent tries to "fix" the tracker itself.
  • autofix-blocked — the loop applies this after two attempts produce no merged pull request, and an agent applies it itself when the issue needs a human decision or hardware it does not have. Either way it means read the issue comments; removing the label puts the issue back in the queue.

Run reports land in target/issue-loop-logs/ on the machine that ran the loop.

Running sanitizers locally

Requires a nightly toolchain (rustup install nightly) and the rust-src component:

rustup component add rust-src --toolchain nightly

AddressSanitizer (detects heap overflows, use-after-free, stack overflows):

RUSTFLAGS="-Z sanitizer=address" \
LSAN_OPTIONS="suppressions=$(pwd)/lsan_suppressions.txt:detect_leaks=1" \
cargo +nightly test --workspace --lib \
  --target x86_64-unknown-linux-gnu \
  --no-fail-fast -- --test-threads=1

UB checks (detects signed integer overflow, invalid enum discriminant, misaligned pointer dereference):

RUSTFLAGS="-Z ub-checks=yes" \
cargo +nightly test --workspace --lib \
  --no-fail-fast -- --test-threads=1

Note: rustc does not implement sanitizer=undefined; -Z ub-checks=yes is the correct nightly knob for runtime UB detection.

All three sanitizer jobs (asan, ubsan, and the P4-11 C-boundary asan harness) run on every PR via .github/workflows/sanitizers.yml. macOS is excluded because the NEON SIMD paths produce spurious cross-thread ASan shadow-map false positives under parallel test execution.

The C-ABI misuse harness

crates/libjpeg-turbo-rs-capi/examples/cabi_misuse_harness.c is a C driver that dlopens one shared library, runs one named case, and exits — so a case that faults is one child's exit status rather than the whole run's. It needs no special toolchain:

cc -O1 -g -Wall -Wextra -o /tmp/cabi_misuse_harness   crates/libjpeg-turbo-rs-capi/examples/cabi_misuse_harness.c -ldl -lpthread
cargo build -p libjpeg-turbo-rs-capi
/tmp/cabi_misuse_harness target/debug/liblibjpeg_turbo_rs_capi.so   pitch_boundaries references/libjpeg-turbo/testimages/testorig.jpg

Point it at <prefix>/lib/libturbojpeg.so instead and you get the same transcript from stock TurboJPEG; that comparison is what crates/libjpeg-turbo-rs-capi/tests/cabi_misuse_harness.rs automates, and it requires an oracle at or above the tool-current release in docs/oracle_versions.tsv (it checks for tj3InitVersion). Lines the two implementations are known to disagree on live in that file's KNOWN_DIVERGENCES (and, for the sixteen tj3Set pairs one item owns, in APPLICABILITY_DIVERGENCES), each naming the LAST_MILE item that owns it and each required to still diverge, so a fix deletes its entry.

The same cases run under ASan and UBSan in sanitizers.yml's c_boundary_asan job.