git/list[1] front-page[2] threads[3] people[4] search[5] about
wed 2026-10-07 18:10 UTC

Re: AI Textconv filter misconfiguration on Windows leads to silent corruption of diff output (ongoing investigation)

From
Skybuck Flying <skybuck2000@hotmail.com>
Date
Sep 1, 2026, 21:37 UTC
Message-ID
<AM0PR02MB4450923337E1B2DAAD688B09B3A82@AM0PR02MB4450.eurprd02.prod.outlook.com>
In-Reply-To
<AM0PR02MB4450BB21D265D843560BCA0DB3A82@AM0PR02MB4450.eurprd02.prod.outlook.com>
In short: PNG files were corrupted, but DLLs files not !
Hi Git developers,
I am submitting a detailed report about a serious issue I encountered on Windows where a globally configured Git textconv filter silently corrupts binary files during checkout. The corruption occurred without any warnings, and only became visible when comparing Git‑checked‑out files with the original versions downloaded via curl.
This report documents the cause, the technical mechanism, the reproduction steps, the fix, and the future risks.
---

Summary of the issue A PNG file inside the repository https://github.com/openai/openai-openapi became corrupted after cloning. The same file downloaded via curl was intact. This immediately suggested that a Git filter was rewriting the file during checkout.

The root cause was a global .gitattributes file containing:
    * text diff=lfclean
Combined with the following global diff driver configuration:
    diff.lfclean.textconv = sed -e s/\r//
    diff.lfclean.binary = false
This configuration forces Git to treat *all* files as text, including binary formats, and to run a textconv filter that removes carriage return characters. Any binary file containing 0x0D bytes is silently modified during checkout.
---

Why PNG files were corrupted but DLL files were not PNG files contain structured binary chunks (tEXt, iTXt, zTXt) that may legitimately include CR/LF characters. When the textconv filter removes CR bytes, the chunk lengths no longer match the actual data, resulting in a corrupted PNG.

DLL files, on the other hand, typically contain no CR characters at all. Because the filter only removes CR bytes, DLL files remain unchanged simply because there is nothing for the filter to remove. This makes the corruption appear “selective”, but it is purely accidental.
Any binary format containing CR bytes is at risk.
---
Reproduction steps
1. Create a global .gitattributes file:
       * text diff=lfclean
2. Configure the diff driver globally:
       diff.lfclean.textconv=sed -e s/\r//
       diff.lfclean.binary=false
3. Clone any repository containing binary files.
4. Compare the blob with the working-tree file:
       git show HEAD:path/to/file > raw.bin
       fc /b raw.bin path/to/file
If the binary contains CR bytes, the working-tree file will differ from the blob.
---

Cause of the problem The pattern "*" matches every file. The attribute "text" forces Git to treat every file as text, overriding binary detection. The diff driver "lfclean" applies a textconv filter that rewrites file contents. Git applies this filter during checkout, not only during diff operations.

This combination guarantees corruption of any binary file containing CR bytes.
---

Solution The correct fix is to remove the global .gitattributes file and the global diff driver:

    del C:\Users\<user>\.gitattributes
    git config --global --unset core.attributesfile
    git config --global --unset diff.lfclean.textconv
    git config --global --unset diff.lfclean.binary
    git config --global --remove-section diff.lfclean
Alternatively, restrict the filter to known text file extensions inside individual repositories.
---

Future risks Global .gitattributes rules are applied to every repository on the system. Using "*" with "text" or any filter is extremely dangerous because:

- Git silently rewrites binary files during checkout.
- Corruption is not detected by Git.
- Corruption depends on file contents, making it unpredictable.
- Users may not realize that Git is modifying files.
- Any future repository containing binary formats with CR bytes will be corrupted.
This configuration effectively creates a system-wide corruption vector.
A warning or safeguard when "text" is forced globally might help prevent accidental misuse.
---

Conclusion This issue demonstrates that global textconv filters can silently corrupt binary files on Windows. The corruption is subtle, unpredictable, and difficult to diagnose. Removing global filters and avoiding "*" patterns in global .gitattributes files is essential for data integrity.

Thank you for your time and consideration.

Best regards, Skybuck

Previous: Skybuck FlyingNext: rsbecker@nexbridge.com
Message 11 of 16 in “AI Textconv filter misconfiguration on Windows leads to silent corruption of diff output (ongoing investigation)”
  1. Skybuck FlyingAug 11, 2026
  2. Skybuck FlyingAug 11, 2026
  3. Skybuck FlyingAug 11, 2026
  4. Jeff KingAug 11, 2026
  5. Skybuck FlyingAug 11, 2026
  6. Theodore TsoAug 11, 2026
  7. Skybuck FlyingAug 11, 2026
  8. Bradley MorganAug 21, 2026
  9. Skybuck FlyingSep 1, 2026
  10. Skybuck FlyingSep 1, 2026
  11. Skybuck FlyingSep 1, 2026
  12. rsbecker@nexbridge.comSep 1, 2026
  13. Skybuck FlyingSep 2, 2026
  14. Skybuck FlyingSep 2, 2026
  15. D. Ben KnobleSep 2, 2026
  16. Skybuck FlyingSep 2, 2026

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.