mdeliver: ignore last empty line of mbox entries

https://www.loc.gov/preservation/digital/formats/fdd/fdd000383.shtml
> Each message is immediately prefaced by a separation line and
> terminated by an empty line.

Bug discovered by skarnet.

Fixes #207.
pull/209/head
Leah Neukirchen 3 years ago
parent 7d04932813
commit 669af4ffca

@ -147,6 +147,8 @@ try_again:
int in_header = 1;
int is_old = 0;
int prev_line_empty = 0;
int this_line_empty = 0; // only for mbox parsing
while (1) {
errno = 0;
ssize_t rd = getdelim(&line, &linelen, '\n', infile);
@ -158,8 +160,12 @@ try_again:
char *line_start = line;
if (line[0] == '\n' && (!line[1] ||
(line[1] == '\r' && !line[2])))
(line[1] == '\r' && !line[2]))) {
this_line_empty = Mflag ? 1 : 0;
in_header = 0;
} else {
this_line_empty = 0;
}
if (Mflag && strncmp("From ", line, 5) == 0)
break;
@ -189,8 +195,15 @@ try_again:
}
}
if (fwrite(line_start, 1, rd, outfile) != (size_t)rd)
goto fail;
// print delayed empty line
if (prev_line_empty)
if (fputc('\n', outfile) == EOF)
goto fail;
if (!this_line_empty)
if (fwrite(line_start, 1, rd, outfile) != (size_t)rd)
goto fail;
prev_line_empty = this_line_empty;
}
if (fflush(outfile) == EOF)
goto fail;

@ -0,0 +1,69 @@
#!/bin/sh -e
cd ${0%/*}
. ./lib.sh
plan 2
rm -rf test.dir
mkdir test.dir
cd test.dir
mmkdir inbox
cat <<EOF >tmp.1
Subject: message 1
This is message 1.
EOF
cat <<EOF >tmp.2
Subject: message 2
This is message 2. It has a trailing empty line.
EOF
printf >tmp.3 'Subject: message 3
This is message 3. It has a no trailing newline, oops.'
cat <<EOF >tmp.4
Subject: message 4
This is message 4. It has multiple trailing empty lines.
EOF
mexport ./tmp.1 | mdeliver -M inbox/
check 'message 1 is delivered verbatim via mbox' 'cmp ./tmp.1 ./inbox/new/*:2,'
rm -f ./inbox/new/*
mexport ./tmp.2 | mdeliver -M inbox/
check 'message 2 is delivered verbatim via mbox' 'cmp ./tmp.2 ./inbox/new/*:2,'
rm -f ./inbox/new/*
mexport ./tmp.3 | mdeliver -M inbox/
check 'message 3 gets a newline via mbox' 'awk 1 ./tmp.3 | cmp - ./inbox/new/*:2,'
rm -f ./inbox/new/*
mexport ./tmp.4 | mdeliver -M inbox/
check 'message 4 gets delivered verbatim via mbox' 'cmp ./tmp.4 ./inbox/new/*:2,'
rm -f ./inbox/new/*
mdeliver inbox/ <./tmp.1
check 'message 1 is delivered verbatim via stdin' 'cmp ./tmp.1 ./inbox/new/*:2,'
rm -f ./inbox/new/*
mdeliver inbox/ <./tmp.2
check 'message 2 is delivered verbatim via stdin' 'cmp ./tmp.2 ./inbox/new/*:2,'
rm -f ./inbox/new/*
mdeliver inbox/ <./tmp.3
check 'message 3 gets a newline via stdin' 'cmp ./tmp.3 ./inbox/new/*:2,'
rm -f ./inbox/new/*
mdeliver inbox/ <./tmp.4
check 'message 4 is delivered verbatim via stdin' 'cmp ./tmp.4 ./inbox/new/*:2,'
rm -f ./inbox/new/*
Loading…
Cancel
Save