mb.kludge: recognise FTS-0004 AREA: envelope in ParseKludgeLine

AREA: is the echomail transport envelope -- FTS-0004 puts it at the
head of the packet-message body, before any ^A kludges.  It has the
same no-^A-prefix shape as the FTS-4 trailing control lines (SEEN-BY:
/ PATH:) the parser already handled.

Without this, SplitKludgeBlob would leave AREA:<tag> sitting in the
"body" output and msgbase writers would store the echomail
envelope-tag as the first 12+ characters of the on-disk body.  HPT
and every other tosser strip AREA: before write since the area tag
is implicit in the destination container (JAM directory, Squish
basename, SDM directory).

Fix: add AREA: to isTrailControl, add 'area' to the dispatch case.
The attribute bag now carries area under the 'area' key (same slot
0.5.0 already populates from `MessageBaseOpen`'s area-tag argument
on reads), consumers that need the tag read it there.

Broke test_uue_hpt_compare when NR's `post -u` path built a body
blob starting with "AREA:<tag>" and handed it to WriteMessage via
SplitKludgeBlob; the envelope leaked through into the JAM body,
inflating decoded UUE by the envelope length per section.  With
the parse fix every consumer now gets a clean body + a populated
'area' attribute.
This commit is contained in:
2026-04-19 16:16:28 -07:00
parent cd2cc900a7
commit ee0f1caa4e

View File

@@ -111,7 +111,15 @@ begin
if Line = '' then exit;
isKludge := Line[1] = #1;
upperLine := UpperCase(Line);
isTrailControl := (Pos('SEEN-BY:', upperLine) = 1) or
{ FTS-0004: AREA:, SEEN-BY: and PATH: appear without ^A prefix -
AREA: is the echomail transport envelope, the other two are
FTS-4 trailing control lines. All three belong in the attribute
bag so msgbase writers can store the area-tag in the slot that
makes sense for the format (JAM has no area field -- it's
implicit in the directory path -- so the attr is consumed and
dropped from body; Squish / SDM ditto). }
isTrailControl := (Pos('AREA:', upperLine) = 1) or
(Pos('SEEN-BY:', upperLine) = 1) or
(Pos('PATH:', upperLine) = 1);
if not (isKludge or isTrailControl) then exit;
@@ -158,6 +166,7 @@ begin
'seen-by': AppendAttr(A, 'seen-by', value);
'path': AppendAttr(A, 'path', value);
'via': AppendAttr(A, 'via', value);
'area': A.SetValue('area', value);
else
AppendAttr(A, 'kludge.' + lower, value);
end;