openbsd-ports/mail/claws-mail/patches/patch-src_common_quoted-printable_c
landry d011b2b6e0 Update to claws-mail 3.8.1 and plugins :
- 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!
2012-06-29 14:02:54 +00:00

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)