const char *mybasename(const char *path);
char *genmsgid(const char *fqdn);
char *gendatestr(void);
-char *decode_qp(const char *qpstr);
+char *decode_qp(const char *qpstr, bool qformat);
bool splitlistaddr(const char *listaddr, char **listname, const char **listfqdn);
#endif /* STRGEN_H */
if(prefix) {
if(strncasecmp(hdrline, "Subject:", 8) == 0) {
subject_present = 1;
- unqp = decode_qp(hdrline + 8);
+ unqp = decode_qp(hdrline + 8, false);
if(strstr(hdrline + 8, prefix) == NULL &&
strstr(unqp, prefix) == NULL) {
dprintf(outfd, "Subject: %s%s\n", prefix, hdrline + 8);
}
char *
-decode_qp(const char *qpstr)
+decode_qp(const char *qpstr, bool qformat)
{
char *buffer = NULL;
size_t size = 0;
fputc(decode_char(qpstr), bufp);
qpstr += 2;
break;
+ case '_':
+ if (qformat) {
+ fputc(0x20, bufp);
+ break;
+ }
+ /* FALLTHROUGH */
default:
fputc(*qpstr, bufp);
break;
#include "mlmmj.h"
#include "xmalloc.h"
#include "unistr.h"
+#include "strgen.h"
#include "log_error.h"
/* This is allocated on the stack, so it can't be too big. */
}
-static int hexval(char ch)
+static void
+decode_quoted_print(char *str, char **binary, size_t *bin_len)
{
- ch = tolower(ch);
-
- if ((ch >= 'a') && (ch <= 'f')) {
- return 10 + ch - 'a';
- }
-
- if ((ch >= '0') && (ch <= '9')) {
- return ch - '0';
- }
-
- return 0;
-}
-
-
-static void decode_qp(char *str, char **binary, size_t *bin_len)
-{
- int i;
-
- /* decoded string will never be longer, and we don't include a NUL */
- *binary = xmalloc(strlen(str));
- *bin_len = 0;
-
- for (i=0; str[i]; i++) {
- if ((str[i] == '=') && isxdigit(str[i+1]) && isxdigit(str[i+2])) {
- (*binary)[(*bin_len)++] = (hexval(str[i+1]) << 4) + hexval(str[i+2]);
- i += 2;
- } else if (str[i] == '_') {
- (*binary)[(*bin_len)++] = 0x20;
- } else {
- (*binary)[(*bin_len)++] = str[i];
- }
- }
+ *binary = decode_qp(str, true);
+ *bin_len = strlen(*binary);
}
}
if (tolower(encoding[0]) == 'q') {
- decode_qp(string, &binary, &bin_len);
+ decode_quoted_print(string, &binary, &bin_len);
} else if (tolower(encoding[0]) == 'b') {
decode_base64(string, &binary, &bin_len);
} else {
ATF_TC_BODY(decode_qp, tc)
{
- ATF_REQUIRE_STREQ(decode_qp("="), "=");
- ATF_REQUIRE_STREQ(decode_qp("=\ra"), "=\ra");
- ATF_REQUIRE_STREQ(decode_qp("=\r\na"), "a");
- ATF_REQUIRE_STREQ(decode_qp("=\na"), "a");
- ATF_REQUIRE_STREQ(decode_qp("This is a subject"), "This is a subject");
- ATF_REQUIRE_STREQ(decode_qp("This= is a subject"), "This= is a subject");
- ATF_REQUIRE_STREQ(decode_qp("This=2 is a subject"), "This=2 is a subject");
- ATF_REQUIRE_STREQ(decode_qp("This=23 is a subject"), "This# is a subject");
- ATF_REQUIRE_STREQ(decode_qp("This=3D is a subject"), "This= is a subject");
- ATF_REQUIRE_STREQ(decode_qp("This_ is a subject"), "This_ is a subject");
+ ATF_REQUIRE_STREQ(decode_qp("=", false), "=");
+ ATF_REQUIRE_STREQ(decode_qp("=\ra", false), "=\ra");
+ ATF_REQUIRE_STREQ(decode_qp("=\r\na", false), "a");
+ ATF_REQUIRE_STREQ(decode_qp("=\na", false), "a");
+ ATF_REQUIRE_STREQ(decode_qp("This is a subject", false), "This is a subject");
+ ATF_REQUIRE_STREQ(decode_qp("This= is a subject", false), "This= is a subject");
+ ATF_REQUIRE_STREQ(decode_qp("This=2 is a subject", false), "This=2 is a subject");
+ ATF_REQUIRE_STREQ(decode_qp("This=23 is a subject", false), "This# is a subject");
+ ATF_REQUIRE_STREQ(decode_qp("This=3D is a subject", false), "This= is a subject");
+ ATF_REQUIRE_STREQ(decode_qp("This_ is a subject", false), "This_ is a subject");
+ ATF_REQUIRE_STREQ(decode_qp("This_ is a subject", true), "This is a subject");
}
ATF_TC_BODY(parse_lastdigest, tc)