summaryrefslogtreecommitdiffstats
path: root/src/lib-mail/quoted-printable.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib-mail/quoted-printable.c')
-rw-r--r--src/lib-mail/quoted-printable.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/lib-mail/quoted-printable.c b/src/lib-mail/quoted-printable.c
new file mode 100644
index 0000000..9bfbe35
--- /dev/null
+++ b/src/lib-mail/quoted-printable.c
@@ -0,0 +1,49 @@
+/* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "buffer.h"
+#include "hex-binary.h"
+#include "quoted-printable.h"
+
+int quoted_printable_q_decode(const unsigned char *src, size_t src_size,
+ buffer_t *dest)
+{
+ char hexbuf[3];
+ size_t src_pos, next;
+ bool errors = FALSE;
+
+ hexbuf[2] = '\0';
+
+ next = 0;
+ for (src_pos = 0; src_pos < src_size; src_pos++) {
+ if (src[src_pos] != '_' && src[src_pos] != '=')
+ continue;
+
+ buffer_append(dest, src + next, src_pos - next);
+ next = src_pos;
+
+ if (src[src_pos] == '_') {
+ buffer_append_c(dest, ' ');
+ next++;
+ continue;
+ }
+
+ if (src_pos+2 >= src_size)
+ break;
+
+ /* =<hex> */
+ hexbuf[0] = src[src_pos+1];
+ hexbuf[1] = src[src_pos+2];
+
+ if (hex_to_binary(hexbuf, dest) == 0) {
+ src_pos += 2;
+ next = src_pos+1;
+ } else {
+ /* non-hex data, show as-is */
+ errors = TRUE;
+ next = src_pos;
+ }
+ }
+ buffer_append(dest, src + next, src_size - next);
+ return errors ? -1 : 0;
+}