Skip to content

Age.TestKit: 61/143 CCTV vectors fail on Windows due to Git autocrlf line-ending normalization #3

Description

@petre-c

Summary

Age.TestKit/CctvTestRunner fails 61 of 143 wire-format reference vectors on Windows. The same vectors pass cleanly on Linux (143/143). The failures are not crypto bugs — they're caused by Git's default core.autocrlf=true on Windows checkouts normalizing the LF-only testdata .txt files to CRLF, which corrupts byte-exact reference vectors.

Repro

On a fresh Windows checkout of pscheid92/AgeSharp@main (no patches):

git clone https://github.com/pscheid92/AgeSharp
cd AgeSharp
dotnet test Age.TestKit/Age.TestKit.csproj -c Release --nologo

Result:

Failed!  - Failed: 61, Passed: 82, Skipped: 0, Total: 143

On a Linux runner (e.g. GitHub Actions ubuntu-latest):

Passed!  - Failed: 0, Passed: 143, Skipped: 0, Total: 143

Root cause

testdata/*.txt files are byte-exact age v1 reference vectors. The CCTV runner reads them and compares against expected hashes / decryption outputs. On Windows, Git's default core.autocrlf=true converts LF to CRLF on checkout, breaking the byte-exactness:

$ file Age.TestKit/testdata/armor_empty.txt
Age.TestKit/testdata/armor_empty.txt: ASCII text, with CRLF line terminators

Hex dump confirms 0d 0a after every line — should be 0a only:

00000000: 6578 7065 6374 3a20 6865 6164 6572 2066  expect: header f
00000010: 6169 6c75 7265 0d0a 6669 6c65 206b 6579  ailure..file key

Failure distribution

The 61 failures span every test category — not just armored ones — because the metadata parser is also affected:

Test prefix Failing
armor_* 29
stanza_* 9
x25519_* 8
stream_* 7
hybrid_* 5
scrypt_* 1
hmac_* 1
empty 1
Total 61

Suggested fix

Add a .gitattributes file that marks the testdata as binary so Git leaves it alone on every platform:

Age.TestKit/testdata/** binary
Age.TestKit/testdata/**/*.txt binary

Or scope it tighter to just the .txt files in that directory.

After the .gitattributes lands, existing Windows clones need to re-fetch the files to get the LF version:

git rm --cached -r Age.TestKit/testdata
git checkout HEAD -- Age.TestKit/testdata

Environment

  • AgeSharp main (unpatched, commit at time of repro: latest)
  • .NET SDK 10.0.203 on Windows 11
  • Git core.autocrlf=true (Windows default)

Why I noticed

This came up while validating an unrelated patch (#2 — WASM cipher swap). I initially attributed the 61 failures to pre-existing upstream bugs (because they showed up on both patched and unpatched checkouts on Windows). Re-running the same code on Linux CI revealed 143/143 pass — at which point the platform pattern was obvious.

Happy to send a PR with the .gitattributes fix if you'd like.

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