]> git.ipfire.org Git - thirdparty/mlmmj.git/commitdiff
decode_qp: add Q format support and reuse the function
authorBaptiste Daroussin <bapt@FreeBSD.org>
Wed, 8 Jan 2025 10:42:45 +0000 (11:42 +0100)
committerBaptiste Daroussin <bapt@FreeBSD.org>
Wed, 8 Jan 2025 10:42:45 +0000 (11:42 +0100)
decode rfc2047's Q format using the strgen's decode_qp this reduces code
duplication

include/strgen.h
src/do_all_the_voodoo_here.c
src/strgen.c
src/unistr.c
tests/mlmmj.c

index 8f63a670f990298e44f30ed51ecd21532d556cf7..3fac0820dbd676076459d3ccfc40be9b9ad9a00f 100644 (file)
@@ -35,7 +35,7 @@ char *mydirname(const char *path);
 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 */
index 2e58e1786fd732155d42a56bbf39d8434f0a15a6..3ba56da73ca3c881e53e774c1abf273407c2831f 100644 (file)
@@ -128,7 +128,7 @@ int do_all_the_voodoo_here(int infd, int outfd, int hdrfd, int footfd,
                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);
index d0e5a8580f70a63ba1515dc66e8fa9cb44abec47..14418c761c46368dd4d985fd7f72dbfe249f9add 100644 (file)
@@ -190,7 +190,7 @@ decode_char(const char *s)
 }
 
 char *
-decode_qp(const char *qpstr)
+decode_qp(const char *qpstr, bool qformat)
 {
        char *buffer = NULL;
        size_t size = 0;
@@ -224,6 +224,12 @@ decode_qp(const char *qpstr)
                        fputc(decode_char(qpstr), bufp);
                        qpstr += 2;
                        break;
+               case '_':
+                       if (qformat) {
+                               fputc(0x20, bufp);
+                               break;
+                       }
+                       /* FALLTHROUGH */
                default:
                        fputc(*qpstr, bufp);
                        break;
index 2984cc2cc6684778a6813fb1fcdfde8f71824ffd..c5fce3d7f69298657f7cfb5942ac4dc73704bd6a 100644 (file)
@@ -35,6 +35,7 @@
 #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. */
@@ -266,40 +267,11 @@ char *unistr_to_utf8(const unistr *str)
 }
 
 
-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);
 }
 
 
@@ -407,7 +379,7 @@ static int header_decode_word(char *wsp, char *word, unistr *ret)
        }
 
        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 {
index 670b0df6fa2f19346b695c883299f86382f09523..ac8a15b3281ae8c8437e0f47de618e83282e26ff 100644 (file)
@@ -683,16 +683,17 @@ ATF_TC_BODY(strtotimet, tc)
 
 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)