mess822x 1.26
mess822x
Loading...
Searching...
No Matches
mess822_qp.c
Go to the documentation of this file.
1#include "mess822.h"
2#include "str.h"
3
4static const char qptab[] =
5{
6// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
7 0, 0, 0, 0, 0, 0, 0, 0, 0,'\t','\n', 0, 0, 0, 0, 0,
8 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0 , 0, 0, 0, 0, 0,
9 ' ' ,'!','"','#','$','%','&','\'','(',')' ,'*' ,'+', ',','-','.','/',
10 '0' ,'1','2','3','4','5','6','7' ,'8','9' ,':' ,';', '<', 0,'>','?',
11 '@' ,'A','B','C','D','E','F','G' ,'H','I' ,'J' ,'K', 'L','M','N','O',
12 'P' ,'Q','R','S','T','U','V','W' ,'X','Y' ,'Z' ,'[','\\',']','^','_',
13 '`' ,'a','b','c','d','e','f','g' ,'h','i' ,'j' ,'k', 'l','m','n','o',
14 'p' ,'q','r','s','t','u','v','w' ,'x','y' ,'z' ,'{', '|','}','~', 0,
15};
16
17static const char hextab[] = "0123456789abcdef";
18static const char qpok[] = "0123456789abcdef "; // FIXME: Invalid last char required
19static const char QPok[] = "0123456789ABCDEF "; // FIXME: Invalid last char required
20
21int hex2dec(const char hex[2])
22{
23 unsigned char c, dec = 0;
24
25 for (int i = 0; i < 2; i++) {
26 c = hex[i];
27 dec <<= 4;
28 if (c >= '0' && c <= '9') dec += c - '0';
29 else if (c >= 'A' && c <= 'F') dec += c - 55; // 'A' - 10
30 else if (c >= 'a' && c <= 'f') dec += c - 87; // 'a' - 10
31 else return -1;
32 }
33 return dec;
34}
35
36/* If the character is <= ' ', > '~', or '=', we want to
37 * print it out in =XY format, unless it's a \n, where
38 * we dump a RFC822 \r\n, or unless it's a tab or space,
39 * where we display it as is, except if it's at end of
40 * line we need to dump a soft linebreak to keep from
41 * having a bare whitespace at the end of the line
42 * (RFC1541 5.1, rule 3). If the line ever gets over
43 * 70 characters long, we need to drop a soft linebreak
44 * and start a new line (RFC1541 5.1, rule 5). If none
45 * of the above is true, dump the ascii value of the
46 * character and continue on our way.
47 *
48 * Return number of byte encoded
49*/
50
51int mess822_qpencode(stralloc *out,stralloc *in)
52{
53 int r = 0; // number of written chars
54 unsigned char ch;
55 char xch[2];
56
57 if (in->len == 0) {
58 if (!stralloc_copys(out,"")) return -1;
59 return 0;
60 }
61 if (!stralloc_copys(out,"")) return -1;
62
63 for (int i = 0; i < in->len - 1; i++) {
64 ch = in->s[i];
65 if ((ch & 0x80) || (ch == '.') || (qptab[ch] == 0)) {
66 if (!stralloc_append(out,"=")) return -1;
67 r++;
68 xch[0] = hextab[(ch >> 4) & 0x0f];
69 xch[1] = hextab[(ch & 0x0f)];
70 if (!stralloc_catb(out,xch,2)) return -1;
71 r += 2;
72 } else {
73 if (!stralloc_append(out,in->s + i)) return -1;
74 r++;
75 }
76 if (r % 76 == 0) if (!stralloc_catb(out,"=\n",2)) return -1;
77 r += 2;
78 }
79
80 return r;
81}
82
83/* Decode a quoted-printable string:
84 1. Convert 2 byte chars introduced by '='.
85 2. Respect \r\n and \r.
86 3. Translate '_' as WSP if RFC 2047.
87 4. Treat standard chars unchanged.
88 The incoming byte sequence does not need to be \0 terminated.
89 The outgoing stralloc is \0 terminated.
90
91 Return number of bytes decoded, -1 if out of memory
92*/
93
94int mess822_qpdecode(stralloc *out,const char *in,int len,int flag)
95{
96 int r = 0;
97 char ch;
98
99 if (len == 0) {
100 if (!stralloc_copys(out,"")) return -1;
101 return 1;
102 }
103 if (!stralloc_readyplus(out,len)) return -1;
104
105 while (len) {
106 if (*in == '\0') return r; // done
107 if (flag == 2047 && *in == '_') { // RFC 2047 ยง 4.2(2)
108 if (!stralloc_append(out," ")) return -1;
109 r++, in++; len--; continue;
110 }
111 if (*in == '=') { // QP double byte char
112 if (*(in + 1) == '\n') { in += 2; len -= 2; continue; }
113 if ((str_chr(QPok,*(in + 1)) < 16 && str_chr(QPok,*(in + 2)) < 16) ||
114 (str_chr(qpok,*(in + 1)) < 16 && str_chr(qpok,*(in + 2)) < 16)) {
115 ch = hex2dec((char *)in + 1);
116 if (!stralloc_append(out,&ch)) return -1;
117 r++; in += 3; len -= 3;
118 } else { r += 2; in += 2; len -= 2; continue; } // ignore any none-valid char
119 }
120 else { // standard char
121 if (!stralloc_append(out,in)) return -1;
122 r++; in++; len--;
123 }
124 }
125 if (!stralloc_0(out)) return -1;
126
127 return r;
128}
int flag
Definition 822field.c:16
void c(char *, char *, char *, int, int, int)
Definition install.c:46
int mess822_qpdecode(stralloc *out, const char *in, int len, int flag)
Definition mess822_qp.c:94
int hex2dec(const char hex[2])
Definition mess822_qp.c:21
int mess822_qpencode(stralloc *out, stralloc *in)
Definition mess822_qp.c:51
stralloc out
Definition b64decode.c:11