d011b2b6e0
- attremover 1.0.14 - htmlviewer 0.32 - notification 0.30 - rssyl 0.33 - vcalendar 2.0.13 While here add patches for upstream bugs #2840, #2841 and #2842. Add links to corresponding patches for tracking purposes. All from Christopher Zimmermann, thanks!
136 lines
3.2 KiB
Plaintext
136 lines
3.2 KiB
Plaintext
$OpenBSD: patch-src_common_quoted-printable_c,v 1.1 2012/06/29 14:02:54 landry Exp $
|
|
http://www.thewildbeast.co.uk/claws-mail/bugzilla/show_bug.cgi?id=2640
|
|
--- src/common/quoted-printable.c.orig Wed Jun 27 11:05:23 2012
|
|
+++ src/common/quoted-printable.c Fri Jun 29 11:08:56 2012
|
|
@@ -22,66 +22,81 @@
|
|
|
|
#include "utils.h"
|
|
|
|
+
|
|
#define MAX_LINELEN 76
|
|
|
|
#define IS_LBREAK(p) \
|
|
- (*(p) == '\0' || *(p) == '\n' || (*(p) == '\r' && *((p) + 1) == '\n'))
|
|
+ ((p)[0] == '\n' ? 1 : ((p)[0] == '\r' && (p)[1] == '\n') ? 2 : 0)
|
|
|
|
-#define SOFT_LBREAK_IF_REQUIRED(n) \
|
|
- if (len + (n) > MAX_LINELEN || \
|
|
- (len + (n) == MAX_LINELEN && (!IS_LBREAK(inp + 1)))) { \
|
|
- *outp++ = '='; \
|
|
- *outp++ = '\n'; \
|
|
- len = 0; \
|
|
- }
|
|
-
|
|
-void qp_encode_line(gchar *out, const guchar *in)
|
|
+gint qp_encode(gboolean text, gchar *out, const guchar *in, gint len)
|
|
{
|
|
- const guchar *inp = in;
|
|
- gchar *outp = out;
|
|
- guchar ch;
|
|
- gint len = 0;
|
|
+ /* counters of input/output characters */
|
|
+ gint inc = 0;
|
|
+ gint outc = 1; /* one character reserved for '=' soft line break */
|
|
|
|
- while (*inp != '\0') {
|
|
- ch = *inp;
|
|
-
|
|
- if (IS_LBREAK(inp)) {
|
|
- *outp++ = '\n';
|
|
- len = 0;
|
|
- if (*inp == '\r')
|
|
- inp++;
|
|
- inp++;
|
|
- } else if (ch == '\t' || ch == ' ') {
|
|
- if (IS_LBREAK(inp + 1)) {
|
|
- SOFT_LBREAK_IF_REQUIRED(3);
|
|
- *outp++ = '=';
|
|
- get_hex_str(outp, ch);
|
|
- outp += 2;
|
|
- len += 3;
|
|
- inp++;
|
|
- } else {
|
|
- SOFT_LBREAK_IF_REQUIRED(1);
|
|
- *outp++ = *inp++;
|
|
- len++;
|
|
+ while(inc < len) {
|
|
+ /* allow literal linebreaks in text */
|
|
+ if(text) {
|
|
+ if(IS_LBREAK(in)) {
|
|
+ /* inserting linebreaks is the job of our caller */
|
|
+ g_assert(outc <= MAX_LINELEN);
|
|
+ *out = '\0';
|
|
+ return inc + IS_LBREAK(in);
|
|
}
|
|
- } else if ((ch >= 33 && ch <= 60) || (ch >= 62 && ch <= 126)) {
|
|
- SOFT_LBREAK_IF_REQUIRED(1);
|
|
- *outp++ = *inp++;
|
|
- len++;
|
|
- } else {
|
|
- SOFT_LBREAK_IF_REQUIRED(3);
|
|
- *outp++ = '=';
|
|
- get_hex_str(outp, ch);
|
|
- outp += 2;
|
|
- len += 3;
|
|
- inp++;
|
|
+ if(IS_LBREAK(in+1)) {
|
|
+ /* free the reserved character since no softbreak
|
|
+ * will be needed after the current character */
|
|
+ outc--;
|
|
+ /* guard against whitespace before a literal linebreak */
|
|
+ if(*in == ' ' || *in == '\t') {
|
|
+ goto escape;
|
|
+ }
|
|
+ }
|
|
}
|
|
+ if(*in == '=') {
|
|
+ goto escape;
|
|
+ }
|
|
+ /* Cave: Whitespace is unconditionally output literally,
|
|
+ * but according to the RFC it must not be output before a
|
|
+ * linebreak.
|
|
+ * This requirement is obeyed by quoting all linebreaks
|
|
+ * and therefore ending all lines with '='. */
|
|
+ else if((*in >= ' ' && *in <= '~') || *in == '\t') {
|
|
+ if(outc + 1 <= MAX_LINELEN) {
|
|
+ *out++ = *in++;
|
|
+ outc++;
|
|
+ inc++;
|
|
+ }
|
|
+ else break;
|
|
+ }
|
|
+ else {
|
|
+escape:
|
|
+ if(outc + 3 <= MAX_LINELEN) {
|
|
+ *out++ = '=';
|
|
+ outc++;
|
|
+ get_hex_str(out, *in);
|
|
+ out += 2;
|
|
+ outc += 2;
|
|
+ in++;
|
|
+ inc++;
|
|
+ }
|
|
+ else break;
|
|
+ }
|
|
}
|
|
+ g_assert(outc <= MAX_LINELEN);
|
|
+ *out++ = '=';
|
|
+ *out = '\0';
|
|
+ return inc;
|
|
+}
|
|
|
|
- if (len > 0)
|
|
- *outp++ = '\n';
|
|
+void qp_encode_line(gchar *out, const guchar *in) {
|
|
+ while (*in != '\0') {
|
|
+ in += qp_encode(TRUE, out, in, strlen(in));
|
|
|
|
- *outp = '\0';
|
|
+ while(*out != '\0') out++;
|
|
+ *out++ = '\n';
|
|
+ *out++ = '\0';
|
|
+ }
|
|
}
|
|
|
|
gint qp_decode_line(gchar *str)
|