X-Git-Url: http://git.marmaro.de/?a=blobdiff_plain;f=sbr%2Fescape_display_name.c;h=4e98e9730c19448d16a81605ffefde241a0f0097;hb=731107f0ab2f3878743fea49910478c6b21bde1b;hp=0918942c9299e3a59f1e769020af11f307629742;hpb=f423b06bf5ab4a966b17857f027a46e74447f438;p=mmh diff --git a/sbr/escape_display_name.c b/sbr/escape_display_name.c index 0918942..4e98e97 100644 --- a/sbr/escape_display_name.c +++ b/sbr/escape_display_name.c @@ -1,63 +1,68 @@ +/* + * escape_display_name.c -- Escape a display name, hopefully per RFC 5322. + * + * This code is Copyright (c) 2012, by the authors of nmh. See the + * COPYRIGHT file in the root directory of the nmh distribution for + * complete copyright information. + */ + #include #include #include -#include #include -/* Escape a display name, hopefully per RFC 5322. - The argument is assumed to be a pointer to a character array of - one-byte characters with enough space to handle the additional - characters. */ +/* Escape a display name, hopefully per RFC 5322. Assumes one-byte + characters. The char array pointed to by the name argument is + modified in place. Its size is specified by the namesize + argument. */ void -escape_display_name (char *name) { +escape_display_name (char *name, size_t namesize) { /* Quote and escape name that contains any specials, as necessary. */ if (strpbrk("\"(),.:;<>@[\\]", name)) { - size_t len = strlen(name); char *destp, *srcp; - size_t destpos, srcpos; - /* E.g., 2 characters, "", would require 7, "\"\""\0. */ - char *tmp = malloc (2*len+3); - - for (destp = tmp, srcp = name, destpos = 0, srcpos = 0; - *srcp; - ++destp, ++srcp, ++destpos, ++srcpos) { - if (srcpos == 0) { + /* Maximum space requirement would be if each character had + to be escaped, plus enclosing double quotes, plus null termintor. + E.g., 2 characters, "", would require 7, "\"\""0, where that 0 + is '\0'. */ + char *tmp = mh_xmalloc (2*strlen(name) + 3); + + for (destp = tmp, srcp = name; *srcp; ++srcp) { + if (srcp == name) { /* Insert initial double quote, if needed. */ if (*srcp != '"') { *destp++ = '"'; - ++destpos; } } else { - /* Escape embedded, unescaped ". */ - if (*srcp == '"' && srcpos < len - 1 && *(srcp-1) != '\\') { + /* Escape embedded, unescaped double quote. */ + if (*srcp == '"' && *(srcp+1) != '\0' && *(srcp-1) != '\\') { *destp++ = '\\'; - ++destpos; } } - *destp = *srcp; + *destp++ = *srcp; /* End of name. */ - if (srcpos == len - 1) { + if (*(srcp+1) == '\0') { /* Insert final double quote, if needed. */ if (*srcp != '"') { - *++destp = '"'; - ++destpos; + *destp++ = '"'; } - *++destp = '\0'; - ++destpos; + *destp++ = '\0'; } } if (strcmp (tmp, "\"")) { - /* assert (strlen(tmp) + 1 == destpos); */ - strncpy (name, tmp, destpos); + /* assert (strlen(tmp) + 1 == destp - tmp); */ + size_t len = destp - tmp; + strncpy (name, tmp, len <= namesize ? len : namesize); } else { /* Handle just " as special case here instead of above. */ - strcpy (name, "\"\\\"\""); + strncpy (name, "\"\\\"\"", namesize); } + name[namesize - 1] = '\0'; + free (tmp); } }