thunderbird-patch-review
Simple email patch review tool for Thunderbird
git clone git://mccd.space/thunderbird-patch-reviewcommit 311a4a6314711fdd8d6f64210ad8c013ebe23e30
parent 0d97836750f6d9f92ecf9f97a266cfe943dd226d
Author: Marc <marc@coquand.email>
Date: Sun, 19 Jul 2026 11:41:57 +0200
bugfix with patch apply
Diffstat:
2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/extension/api/patchHost/implementation.js b/extension/api/patchHost/implementation.js
@@ -144,7 +144,11 @@ async function apply(repo, strategy, patches) {
// maps the target to the new name and the old name is recorded deleted.
function collectFinalBlobs(text) {
const finals = new Map();
- const lines = text.split("\n");
+ // Mail transport commonly delivers CRLF (Thunderbird's getRaw does); a
+ // trailing \r would defeat the $-anchored path regexes below, since in
+ // JS `.` matches neither \r nor \n. A path genuinely ending in \r is
+ // git-quoted and hits the quoted-path bail, so stripping is safe.
+ const lines = text.split("\n").map((l) => (l.endsWith("\r") ? l.slice(0, -1) : l));
let block = null;
let unsupported = false;
const flush = (b) => {
@@ -280,7 +284,11 @@ async function check(repo, strategy, patches) {
PathUtils.tempDir,
`patch-review.check.${Date.now()}.${Math.floor(Math.random() * 1e9)}.patch`
);
- await IOUtils.writeUTF8(probe, patches.join("\n"));
+ // Unlike git am (whose mailinfo strips mail-transport CRLF), git apply
+ // takes the probe bytes literally, and a \r on every context line
+ // matches nothing. Fold transport CRLF to LF; a genuine content \r in
+ // a CRLF-file patch arrives as \r\r\n and keeps its single \r.
+ await IOUtils.writeUTF8(probe, patches.join("\n").replace(/\r\n/g, "\n"));
let fwd;
try {
fwd = await run(git, ["-C", repo, "-c", "advice.mergeConflict=false", "-c", "advice.amWorkDir=false", "apply", "--check", probe]);
diff --git a/tests/run.mjs b/tests/run.mjs
@@ -461,6 +461,13 @@ function check(name, cond, extra = "") {
"",
].join("\n");
check("check: quoted path bails to null", collect(quoted) === null);
+
+ // Thunderbird's getRaw delivers CRLF line endings; the parser must
+ // read them identically to LF instead of bailing to null.
+ check(
+ "check: collectFinalBlobs tolerates CRLF line endings",
+ eq(collect(two.replace(/\n/g, "\r\n")), new Map([["f", { blob: "ccccccc" }]]))
+ );
}
}