Skip to content

Commit 9f61859

Browse files
committed
libopenarc: Wrap b= fields at the margin
Cleans up two XXXs.
1 parent fdabe99 commit 9f61859

File tree

5 files changed

+85
-6
lines changed

5 files changed

+85
-6
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ All notable changes to this project will be documented in this file.
5252
and `s=` tags.
5353
- libopenarc - `arc_eom()` propagates internal errors like memory allocation
5454
failure instead of marking the chain as failed.
55+
- libopenarc - Signature fields are wrapped at the configured margin.
5556
- milter - Use after free.
5657
- milter - Unlikely division by zero.
5758
- milter - Small memory leak during config loading.

libopenarc/arc.c

+2-6
Original file line numberDiff line numberDiff line change
@@ -3599,9 +3599,7 @@ arc_getseal(ARC_MESSAGE *msg,
35993599
}
36003600

36013601
/* append it to the stub */
3602-
arc_dstring_cat(dstr, (char *) b64sig);
3603-
3604-
/* XXX -- wrapping needs to happen here */
3602+
arc_dstring_cat_wrap(dstr, (char *) b64sig, msg->arc_margin);
36053603

36063604
/* add it to the seal */
36073605
h = ARC_MALLOC(sizeof hdr);
@@ -3700,9 +3698,7 @@ arc_getseal(ARC_MESSAGE *msg,
37003698
}
37013699

37023700
/* append it to the stub */
3703-
arc_dstring_cat(dstr, (char *) b64sig);
3704-
3705-
/* XXX -- wrapping needs to happen here */
3701+
arc_dstring_cat_wrap(dstr, (char *) b64sig, msg->arc_margin);
37063702

37073703
/* add it to the seal */
37083704
h = ARC_MALLOC(sizeof hdr);

test/test_milter.py

+3
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ def _run_miltertest(
5050
if msg[0] == miltertest.SMFIR_INSHEADER:
5151
# Check for invalid characters
5252
assert '\r' not in msg[1]['value']
53+
# Check for proper wrapping
54+
if msg[1]['name'] in ['ARC-Message-Signature', 'ARC-Seal']:
55+
assert not any(len(x) > 80 for x in msg[1]['value'].splitlines())
5356
ins_headers.insert(msg[1]['index'], [msg[1]['name'], msg[1]['value']])
5457
elif msg[0] in miltertest.DISPOSITION_REPLIES:
5558
assert msg[0] == miltertest.SMFIR_ACCEPT

util/arc-dstring.c

+78
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,84 @@ arc_dstring_catn(struct arc_dstring *dstr, const char *str, size_t nbytes)
378378
return true;
379379
}
380380

381+
/**
382+
* Append a string to a dstring, wrapping at a specific column.
383+
*
384+
* Parameters:
385+
* dstr: dstring to modify
386+
* str: string to append
387+
* margin: maximum line length, not including CRLF
388+
*
389+
* Returns:
390+
* Whether the operation succeeded.
391+
*/
392+
bool
393+
arc_dstring_cat_wrap(struct arc_dstring *dstr, const char *str, size_t margin)
394+
{
395+
size_t len;
396+
size_t slen;
397+
398+
if (margin < 3)
399+
{
400+
/* margin is either disabled or nonsensical */
401+
return arc_dstring_cat(dstr, str);
402+
}
403+
404+
/* find the current line length */
405+
len = 0;
406+
for (char *p = dstr->ds_buf; *p; p++)
407+
{
408+
len++;
409+
if (*p == '\n')
410+
{
411+
len = 0;
412+
}
413+
}
414+
415+
if (len >= margin)
416+
{
417+
len = 0;
418+
}
419+
else
420+
{
421+
len = margin - len;
422+
}
423+
424+
slen = strlen(str);
425+
if (len > slen)
426+
{
427+
len = slen;
428+
}
429+
430+
if (len > 0)
431+
{
432+
if (!arc_dstring_catn(dstr, str, len))
433+
{
434+
return false;
435+
}
436+
}
437+
438+
for (const char *p = str + len; p < str + slen; p += margin - 2)
439+
{
440+
if (!arc_dstring_cat(dstr, "\r\n\t "))
441+
{
442+
return false;
443+
}
444+
445+
len = strlen(p);
446+
if (len > margin - 2)
447+
{
448+
len = margin - 2;
449+
}
450+
451+
if (!arc_dstring_catn(dstr, p, len))
452+
{
453+
return false;
454+
}
455+
}
456+
return true;
457+
}
458+
381459
/*
382460
** ARC_DSTRING_GET -- retrieve data in a dstring
383461
**

util/arc-dstring.h

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ extern void arc_dstring_blank(struct arc_dstring *);
2727
extern bool arc_dstring_cat(struct arc_dstring *, const char *);
2828
extern bool arc_dstring_cat1(struct arc_dstring *, int);
2929
extern bool arc_dstring_catn(struct arc_dstring *, const char *, size_t);
30+
extern bool arc_dstring_cat_wrap(struct arc_dstring *, const char *, size_t);
3031
extern bool arc_dstring_copy(struct arc_dstring *, const char *);
3132
extern void arc_dstring_strip(struct arc_dstring *, const char *);
3233
extern void arc_dstring_free(struct arc_dstring *);

0 commit comments

Comments
 (0)