From 80d048633bfb3dd50e65aadd72eff56c388e3f15 Mon Sep 17 00:00:00 2001 From: Toddr Bot Date: Fri, 10 Apr 2026 05:15:04 +0000 Subject: [PATCH 1/3] Add CLAUDE.md with project conventions and gotchas Captures dual-life module dynamics, build/test workflow, the critical files.t hardcoded-hash gotcha, XS code patterns (endianness, 64-bit counters, allocation macros), and PR workflow for the fork structure. Co-Authored-By: Claude Opus 4.6 --- CLAUDE.md | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..88c6ea8 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,102 @@ +# CLAUDE.md — Digest::MD5 + +## Project identity + +Digest::MD5 is a **dual-life** Perl module — it ships with perl core and is also released independently to CPAN. The canonical upstream is `gisle/digest-md5`. The `Dual-Life/Digest-MD5` fork is used for development; PRs target upstream. + +- **Current version**: see `$VERSION` in `MD5.pm` +- **Minimum Perl**: 5.006 (declared in `Makefile.PL`) +- **XS module**: the core implementation is in `MD5.xs` (C code) + +## Repository structure + +``` +MD5.pm Perl module (OO + functional interface, POD docs) +MD5.xs XS/C implementation of MD5 algorithm +Makefile.PL ExtUtils::MakeMaker build script +t/ Test suite + md5-aaa.t Exhaustive padding/correctness vectors (large, 549 lines) + files.t Checksums of README, MD5.xs, rfc1321.txt (hardcoded hashes!) + context.t context() save/restore tests + clone.t clone() method tests + utf8.t Unicode string handling + warns.t Warning detection for misuse patterns + align.t Unaligned memory block tests + badfile.t addfile() error handling + bits.t add_bits() method + threads.t Thread safety via ithread cloning +hints/ Platform-specific compiler workarounds (DEC, IRIX, MacOS) +bin/md5sum.pl Command-line md5sum utility +rfc1321.txt RFC 1321 reference text +``` + +## Build and test + +```bash +perl Makefile.PL && make && make test +``` + +The XS code compiles to `MD5.c` -> `MD5.o` -> `blib/`. Always run `make test` before committing — a commit that doesn't pass tests is not a valid commit. + +## What NOT to modify + +- **Changes**: version history is maintained by the release manager, not contributors +- **Version numbers**: never bump `$VERSION` in `MD5.pm` +- **MANIFEST**: generated by `make manifest` — do not manually sort or reformat +- **README**: static file with hardcoded checksum in `t/files.t` + +## Critical gotcha: t/files.t + +`t/files.t` contains **hardcoded MD5 checksums** for `README`, `MD5.xs`, and `rfc1321.txt`. Any change to these three files will cause `files.t` to fail. When modifying `MD5.xs`, you **must** update the expected hash on line 25 of `t/files.t`: + +```perl +# Update this hash after changing MD5.xs: +f4b5da4e0f19b4c0ab374b7085ed8955 MD5.xs +``` + +Compute the new hash with: `perl -MDigest::MD5 -e 'open my $f,"<","MD5.xs"; print Digest::MD5->new->addfile($f)->hexdigest'` + +Or after rebuilding: `make test` will show the mismatch. + +## XS code patterns + +### Memory allocation +The codebase uses `New(id, ptr, n, type)` (deprecated) for allocations. The modern equivalent is `Newx(ptr, n, type)`. A compatibility shim exists for `Newxz` (line 48-49) but not yet for `Newx`. + +### Endianness +`BYTEORDER` values differ between 32-bit (`0x1234`/`0x4321`) and 64-bit (`0x12345678`/`0x87654321`). The `TO32`/`TRUNC32` macros handle truncation when `BYTEORDER > 0x4321`. Any byte-swapping or endian-conditional code must handle both widths. + +### 64-bit considerations +The MD5 byte counter uses split U32 fields (`bytes_low`/`bytes_high`). Carry detection compares against `STRLEN` (which is 64-bit on LP64 systems). Comparisons must use same-width operands to avoid implicit promotion bugs. + +### Thread safety +When `USE_ITHREADS` and `MGf_DUP` are defined, the context is duplicated via `dup_md5_ctx()` on thread clone. The vtable structure differs between threaded and non-threaded builds. + +## Test conventions + +- Most tests use `Test::More` (converted from old `Test.pm` style) +- `files.t` still uses manual `print "ok"` / `print "not ok"` style +- `md5-aaa.t` is the comprehensive correctness test (88K, ~500 test vectors) +- Tests must handle `PERL_CORE` mode (some files unavailable when run from perl core build) +- `EBCDIC` paths exist in some tests for mainframe compatibility + +## PR workflow + +This repo (`Dual-Life/Digest-MD5`) is a **fork** of `gisle/digest-md5`. + +- PRs go to upstream: `gh pr create --draft --repo gisle/digest-md5 --head Dual-Life:` +- Issues go to upstream: `gh issue create --repo gisle/digest-md5` +- Branch prefix: `koan.toddr.bot/` + +## CI + +GitHub Actions workflow in `.github/workflows/testsuite.yml`: +- Ubuntu (latest Perl), Linux matrix (5.8-5.32), macOS +- Uses `actions/checkout@v2` and `perl-actions/install-with-cpm@v1` +- Note: `.travis.yml` still exists but Travis CI is defunct for open source + +## Open issues (as of 2025) + +- **#10**: FIPS mode detection — MD5 should croak when system FIPS is enabled +- **#8**: U32 alignment on 64-bit — `BYTEORDER` conditionals need 64-bit values +- **#6**: Incorrect MD5 with large scalars — 64-bit byte counter overflow From d9a644bd2fde27fc83817703f8fa7f736dcda845 Mon Sep 17 00:00:00 2001 From: Toddr Bot Date: Fri, 10 Apr 2026 05:16:23 +0000 Subject: [PATCH 2/3] Exclude CLAUDE.md from CPAN distribution Add CLAUDE.md to MANIFEST.SKIP so make manifest won't include it in the distribution tarball. It's a development aid, not user-facing. Co-Authored-By: Claude Opus 4.6 --- MANIFEST.SKIP | 1 + 1 file changed, 1 insertion(+) diff --git a/MANIFEST.SKIP b/MANIFEST.SKIP index 6b253c9..f75f8f0 100644 --- a/MANIFEST.SKIP +++ b/MANIFEST.SKIP @@ -19,4 +19,5 @@ pm_to_blib$ ^cpanfile$ ^\.gitignore$ ^\.travis.yml$ +^CLAUDE\.md$ ^MYMETA\. From a53b97e3af97610264b22ab5b393623dcbe451e6 Mon Sep 17 00:00:00 2001 From: Toddr Bot Date: Sat, 11 Apr 2026 05:07:31 +0000 Subject: [PATCH 3/3] ci: replace Docker containers with actions-setup-perl Docker Hub has removed perl:5.8 through perl:5.24 container images, causing CI failures on all branches including main. Replace the container-based approach with shogo82148/actions-setup-perl which builds Perl from source and supports 5.8+. Changes: - Switch linux matrix from Docker containers to actions-setup-perl - Update actions/checkout v2 -> v4 - Update install-with-cpm v1 -> stable (ubuntu job) - Add Perl 5.34, 5.36, 5.38, 5.40 to test matrix - Drop Perl 5.8 (22 years old, minimal practical value) - Add Windows CI job (Strawberry Perl via actions-setup-perl) - Add macOS CI job (system perl, no container) - Limit AUTHOR_TESTING/RELEASE_TESTING to ubuntu job only Co-Authored-By: Claude Opus 4.6 --- .github/workflows/testsuite.yml | 60 ++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/.github/workflows/testsuite.yml b/.github/workflows/testsuite.yml index 3cd0e3e..08905a2 100644 --- a/.github/workflows/testsuite.yml +++ b/.github/workflows/testsuite.yml @@ -19,10 +19,10 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - run: perl -V - name: install dependencies - uses: perl-actions/install-with-cpm@v1 + uses: perl-actions/install-with-cpm@stable with: cpanfile: "cpanfile" - name: Makefile.PL @@ -35,9 +35,7 @@ jobs: needs: [ubuntu] env: PERL_USE_UNSAFE_INC: 0 - AUTHOR_TESTING: 1 AUTOMATED_TESTING: 1 - RELEASE_TESTING: 1 runs-on: ubuntu-latest @@ -46,6 +44,10 @@ jobs: matrix: perl-version: [ + "5.40", + "5.38", + "5.36", + "5.34", "5.32", "5.30", "5.28", @@ -58,22 +60,19 @@ jobs: "5.14", "5.12", "5.10", - "5.8", ] - container: - image: perl:${{ matrix.perl-version }} - steps: - - uses: actions/checkout@v2 - - run: perl -V - - name: install dependencies - uses: perl-actions/install-with-cpm@v1 + - uses: actions/checkout@v4 + - name: Set up perl ${{ matrix.perl-version }} + uses: shogo82148/actions-setup-perl@v1 with: - sudo: false - cpanfile: "cpanfile" + perl-version: ${{ matrix.perl-version }} + - run: perl -V - name: Makefile.PL run: perl -I$(pwd) Makefile.PL + - name: make + run: make - name: make test run: make test @@ -81,25 +80,40 @@ jobs: needs: [ubuntu] env: PERL_USE_UNSAFE_INC: 0 - AUTHOR_TESTING: 1 AUTOMATED_TESTING: 1 - RELEASE_TESTING: 1 runs-on: macOS-latest - strategy: - fail-fast: false - matrix: - perl-version: [latest] - steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - run: perl -V - name: install dependencies - uses: perl-actions/install-with-cpm@v1 + uses: perl-actions/install-with-cpm@stable with: cpanfile: "cpanfile" - name: Makefile.PL run: perl -I$(pwd) Makefile.PL - name: make test run: make test + + windows: + needs: [ubuntu] + env: + PERL_USE_UNSAFE_INC: 0 + AUTOMATED_TESTING: 1 + + runs-on: windows-latest + + steps: + - uses: actions/checkout@v4 + - name: Set up Strawberry Perl + uses: shogo82148/actions-setup-perl@v1 + with: + perl-version: "5.38" + - run: perl -V + - name: Makefile.PL + run: perl Makefile.PL + - name: make + run: gmake + - name: make test + run: gmake test