2 * escape_addresses.c -- Escape address components, hopefully per RFC 5322.
4 * This code is Copyright (c) 2012, by the authors of nmh. See the
5 * COPYRIGHT file in the root directory of the nmh distribution for
6 * complete copyright information.
13 escape_component (char *name
, size_t namesize
, char *chars
);
17 escape_display_name (char *name
, size_t namesize
) {
18 char *specials
= "\"(),.:;<>@[\\]";
19 escape_component (name
, namesize
, specials
);
24 escape_local_part (char *name
, size_t namesize
) {
25 /* wsp (whitespace) is horizontal tab or space, according to
27 char *specials_less_dot_plus_wsp
= " \"(),:;<>@[\\]";
28 escape_component (name
, namesize
, specials_less_dot_plus_wsp
);
32 /* Escape an address component, hopefully per RFC 5322. Assumes
33 one-byte characters. The char array pointed to by the name
34 argument is modified in place. Its size is specified by the
35 namesize argument. The need_escape argument is a string of
36 characters that require that name be escaped. */
38 escape_component (char *name
, size_t namesize
, char *chars_to_escape
) {
39 /* If name contains any chars_to_escape:
41 2) escape any embedded "
43 if (strpbrk(name
, chars_to_escape
)) {
45 /* Maximum space requirement would be if each character had
46 to be escaped, plus enclosing double quotes, plus null termintor.
47 E.g., 2 characters, "", would require 7, "\"\""0, where that 0
49 char *tmp
= mh_xmalloc (2*strlen(name
) + 3);
51 for (destp
= tmp
, srcp
= name
; *srcp
; ++srcp
) {
53 /* Insert initial double quote, if needed. */
58 /* Escape embedded, unescaped double quote. */
59 if (*srcp
== '"' && *(srcp
+1) != '\0' && *(srcp
-1) != '\\') {
67 if (*(srcp
+1) == '\0') {
68 /* Insert final double quote, if needed. */
77 if (strcmp (tmp
, "\"")) {
78 size_t len
= destp
- tmp
;
79 assert ((ssize_t
) strlen(tmp
) + 1 == destp
- tmp
);
80 strncpy (name
, tmp
, len
<= namesize
? len
: namesize
);
82 /* Handle just " as special case here instead of above. */
83 strncpy (name
, "\"\\\"\"", namesize
);
86 name
[namesize
- 1] = '\0';