[gmime] Split GMimeFilterCRLF into Unix2Dos and Dos2Unix
- From: Jeffrey Stedfast <fejj src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gmime] Split GMimeFilterCRLF into Unix2Dos and Dos2Unix
- Date: Mon, 20 Mar 2017 01:03:36 +0000 (UTC)
commit 21e1d34a2d6196d1a9ada870af97b1a5c6b2b76f
Author: Jeffrey Stedfast <jestedfa microsoft com>
Date: Sun Mar 19 20:15:55 2017 -0400
Split GMimeFilterCRLF into Unix2Dos and Dos2Unix
docs/reference/gmime-docs.sgml | 4 +
docs/reference/gmime-sections.txt | 36 +++++++
docs/reference/gmime.hierarchy | 2 +
gmime/Makefile.am | 4 +
gmime/gmime-application-pkcs7-mime.c | 41 +++-----
gmime/gmime-filter-dos2unix.c | 188 ++++++++++++++++++++++++++++++++++
gmime/gmime-filter-dos2unix.h | 66 ++++++++++++
gmime/gmime-filter-unix2dos.c | 188 ++++++++++++++++++++++++++++++++++
gmime/gmime-filter-unix2dos.h | 66 ++++++++++++
gmime/gmime-filter.c | 2 +-
gmime/gmime-format-options.c | 7 +-
gmime/gmime-format-options.h | 4 +-
gmime/gmime-message.c | 6 +-
gmime/gmime-message.h | 5 +-
gmime/gmime-multipart-encrypted.c | 24 ++---
gmime/gmime-multipart-signed.c | 29 +++--
gmime/gmime-object.c | 1 +
gmime/gmime-object.h | 4 +-
gmime/gmime-parser.c | 2 +
gmime/gmime-part.c | 77 +++++++-------
gmime/gmime.c | 2 +
gmime/gmime.h | 2 +
tests/test-pgpmime.c | 7 +-
23 files changed, 665 insertions(+), 102 deletions(-)
---
diff --git a/docs/reference/gmime-docs.sgml b/docs/reference/gmime-docs.sgml
index 08482bc..d167a95 100644
--- a/docs/reference/gmime-docs.sgml
+++ b/docs/reference/gmime-docs.sgml
@@ -46,12 +46,14 @@
<!ENTITY GMimeFilterBest SYSTEM "xml/gmime-filter-best.xml">
<!ENTITY GMimeFilterCharset SYSTEM "xml/gmime-filter-charset.xml">
<!ENTITY GMimeFilterCRLF SYSTEM "xml/gmime-filter-crlf.xml">
+<!ENTITY GMimeFilterDos2Unix SYSTEM "xml/gmime-filter-dos2unix.xml">
<!ENTITY GMimeFilterEnriched SYSTEM "xml/gmime-filter-enriched.xml">
<!ENTITY GMimeFilterFrom SYSTEM "xml/gmime-filter-from.xml">
<!ENTITY GMimeFilterGZip SYSTEM "xml/gmime-filter-gzip.xml">
<!ENTITY GMimeFilterHTML SYSTEM "xml/gmime-filter-html.xml">
<!ENTITY GMimeFilterMd5 SYSTEM "xml/gmime-filter-md5.xml">
<!ENTITY GMimeFilterStrip SYSTEM "xml/gmime-filter-strip.xml">
+<!ENTITY GMimeFilterUnix2Dos SYSTEM "xml/gmime-filter-unix2dos.xml">
<!ENTITY GMimeFilterWindows SYSTEM "xml/gmime-filter-windows.xml">
<!ENTITY GMimeFilterYenc SYSTEM "xml/gmime-filter-yenc.xml">
<!ENTITY GMimeCertificate SYSTEM "xml/gmime-certificate.xml">
@@ -208,12 +210,14 @@ string utilities, file utilities, a main loop abstraction, and so on.
&GMimeFilterBest;
&GMimeFilterCharset;
&GMimeFilterCRLF;
+ &GMimeFilterDos2Unix;
&GMimeFilterEnriched;
&GMimeFilterFrom;
&GMimeFilterGZip;
&GMimeFilterHTML;
&GMimeFilterMd5;
&GMimeFilterStrip;
+ &GMimeFilterUnix2Dos;
&GMimeFilterWindows;
&GMimeFilterYenc;
</chapter>
diff --git a/docs/reference/gmime-sections.txt b/docs/reference/gmime-sections.txt
index ba0c515..df3b758 100644
--- a/docs/reference/gmime-sections.txt
+++ b/docs/reference/gmime-sections.txt
@@ -369,6 +369,24 @@ GMIME_FILTER_CRLF_GET_CLASS
</SECTION>
<SECTION>
+<FILE>gmime-filter-dos2unix</FILE>
+GMimeFilterDos2Unix
+g_mime_filter_dos2unix_new
+
+<SUBSECTION Private>
+g_mime_filter_dos2unix_get_type
+
+<SUBSECTION Standard>
+GMimeFilterDos2UnixClass
+GMIME_TYPE_FILTER_DOS2UNIX
+GMIME_FILTER_DOS2UNIX
+GMIME_IS_FILTER_DOS2UNIX
+GMIME_FILTER_DOS2UNIX_CLASS
+GMIME_IS_FILTER_DOS2UNIX_CLASS
+GMIME_FILTER_DOS2UNIX_GET_CLASS
+</SECTION>
+
+<SECTION>
<FILE>gmime-filter-enriched</FILE>
GMIME_FILTER_ENRICHED_IS_RICHTEXT
GMimeFilterEnriched
@@ -490,6 +508,24 @@ GMIME_FILTER_STRIP_GET_CLASS
</SECTION>
<SECTION>
+<FILE>gmime-filter-unix2dos</FILE>
+GMimeFilterUnix2Dos
+g_mime_filter_unix2dos_new
+
+<SUBSECTION Private>
+g_mime_filter_unix2dos_get_type
+
+<SUBSECTION Standard>
+GMimeFilterUnix2DosClass
+GMIME_TYPE_FILTER_UNIX2DOS
+GMIME_FILTER_UNIX2DOS
+GMIME_IS_FILTER_UNIX2DOS
+GMIME_FILTER_UNIX2DOS_CLASS
+GMIME_IS_FILTER_UNIX2DOS_CLASS
+GMIME_FILTER_UNIX2DOS_GET_CLASS
+</SECTION>
+
+<SECTION>
<FILE>gmime-filter-windows</FILE>
GMimeFilterWindows
g_mime_filter_windows_new
diff --git a/docs/reference/gmime.hierarchy b/docs/reference/gmime.hierarchy
index e37ccc4..cd32079 100644
--- a/docs/reference/gmime.hierarchy
+++ b/docs/reference/gmime.hierarchy
@@ -33,12 +33,14 @@ GObject
GMimeFilterBest
GMimeFilterCharset
GMimeFilterCRLF
+ GMimeFilterDos2Unix
GMimeFilterEnriched
GMimeFilterFrom
GMimeFilterGZip
GMimeFilterHTML
GMimeFilterMd5
GMimeFilterStrip
+ GMimeFilterUnix2Dos
GMimeFilterWindows
GMimeFilterYenc
GMimeParser
diff --git a/gmime/Makefile.am b/gmime/Makefile.am
index 59f781e..cf34f9d 100644
--- a/gmime/Makefile.am
+++ b/gmime/Makefile.am
@@ -36,12 +36,14 @@ libgmime_3_0_la_SOURCES = \
gmime-filter-best.c \
gmime-filter-charset.c \
gmime-filter-crlf.c \
+ gmime-filter-dos2unix.c \
gmime-filter-enriched.c \
gmime-filter-from.c \
gmime-filter-gzip.c \
gmime-filter-html.c \
gmime-filter-md5.c \
gmime-filter-strip.c \
+ gmime-filter-unix2dos.c \
gmime-filter-windows.c \
gmime-filter-yenc.c \
gmime-format-options.c \
@@ -96,12 +98,14 @@ gmimeinclude_HEADERS = \
gmime-filter-best.h \
gmime-filter-charset.h \
gmime-filter-crlf.h \
+ gmime-filter-dos2unix.h \
gmime-filter-enriched.h \
gmime-filter-from.h \
gmime-filter-gzip.h \
gmime-filter-html.h \
gmime-filter-md5.h \
gmime-filter-strip.h \
+ gmime-filter-unix2dos.h \
gmime-filter-windows.h \
gmime-filter-yenc.h \
gmime-format-options.h \
diff --git a/gmime/gmime-application-pkcs7-mime.c b/gmime/gmime-application-pkcs7-mime.c
index 0b10423..276d725 100644
--- a/gmime/gmime-application-pkcs7-mime.c
+++ b/gmime/gmime-application-pkcs7-mime.c
@@ -26,10 +26,11 @@
#include <string.h>
#include "gmime-application-pkcs7-mime.h"
+#include "gmime-filter-dos2unix.h"
#include "gmime-stream-filter.h"
#include "gmime-filter-basic.h"
-#include "gmime-filter-crlf.h"
#include "gmime-stream-mem.h"
+#include "gmime-internal.h"
#include "gmime-parser.h"
#include "gmime-error.h"
@@ -227,8 +228,8 @@ g_mime_application_pkcs7_mime_decompress (GMimeApplicationPkcs7Mime *pkcs7_mime,
GMimeApplicationPkcs7Mime *
g_mime_application_pkcs7_mime_encrypt (GMimeObject *entity, GMimeEncryptFlags flags, GPtrArray *recipients,
GError **err)
{
- GMimeStream *filtered, *ciphertext, *stream;
GMimeApplicationPkcs7Mime *pkcs7_mime;
+ GMimeStream *ciphertext, *stream;
GMimeContentType *content_type;
GMimeFormatOptions *options;
GMimeDataWrapper *content;
@@ -245,19 +246,13 @@ g_mime_application_pkcs7_mime_encrypt (GMimeObject *entity, GMimeEncryptFlags fl
return NULL;
}
- options = g_mime_format_options_get_default ();
+ options = _g_mime_format_options_clone (NULL, FALSE);
+ g_mime_format_options_set_newline_format (options, GMIME_NEWLINE_FORMAT_DOS);
/* get the cleartext */
stream = g_mime_stream_mem_new ();
- filtered = g_mime_stream_filter_new (stream);
-
- filter = g_mime_filter_crlf_new (TRUE, FALSE);
- g_mime_stream_filter_add ((GMimeStreamFilter *) filtered, filter);
- g_object_unref (filter);
-
- g_mime_object_write_to_stream (entity, options, filtered);
- g_mime_stream_flush (filtered);
- g_object_unref (filtered);
+ g_mime_object_write_to_stream (entity, options, stream);
+ g_mime_format_options_free (options);
/* reset the content stream */
g_mime_stream_reset (stream);
@@ -278,7 +273,7 @@ g_mime_application_pkcs7_mime_encrypt (GMimeObject *entity, GMimeEncryptFlags fl
/* construct the application/pkcs7-mime part */
pkcs7_mime = g_mime_application_pkcs7_mime_new (GMIME_SECURE_MIME_TYPE_ENVELOPED_DATA);
content = g_mime_data_wrapper_new_with_stream (ciphertext, GMIME_CONTENT_ENCODING_DEFAULT);
- g_mime_part_set_content (GMIME_PART (pkcs7_mime), content);
+ g_mime_part_set_content ((GMimePart *) pkcs7_mime, content);
g_object_unref (ciphertext);
g_object_unref (content);
@@ -343,7 +338,7 @@ g_mime_application_pkcs7_mime_decrypt (GMimeApplicationPkcs7Mime *pkcs7_mime,
stream = g_mime_stream_mem_new ();
filtered = g_mime_stream_filter_new (stream);
- filter = g_mime_filter_crlf_new (FALSE, FALSE);
+ filter = g_mime_filter_dos2unix_new (FALSE);
g_mime_stream_filter_add ((GMimeStreamFilter *) filtered, filter);
g_object_unref (filter);
@@ -401,8 +396,8 @@ g_mime_application_pkcs7_mime_decrypt (GMimeApplicationPkcs7Mime *pkcs7_mime,
GMimeApplicationPkcs7Mime *
g_mime_application_pkcs7_mime_sign (GMimeObject *entity, const char *userid, GError **err)
{
- GMimeStream *filtered, *ciphertext, *stream;
GMimeApplicationPkcs7Mime *pkcs7_mime;
+ GMimeStream *ciphertext, *stream;
GMimeContentType *content_type;
GMimeFormatOptions *options;
GMimeDataWrapper *content;
@@ -419,19 +414,13 @@ g_mime_application_pkcs7_mime_sign (GMimeObject *entity, const char *userid, GEr
return NULL;
}
- options = g_mime_format_options_get_default ();
+ options = _g_mime_format_options_clone (NULL, FALSE);
+ g_mime_format_options_set_newline_format (options, GMIME_NEWLINE_FORMAT_DOS);
/* get the cleartext */
stream = g_mime_stream_mem_new ();
- filtered = g_mime_stream_filter_new (stream);
-
- filter = g_mime_filter_crlf_new (TRUE, FALSE);
- g_mime_stream_filter_add ((GMimeStreamFilter *) filtered, filter);
- g_object_unref (filter);
-
- g_mime_object_write_to_stream (entity, options, filtered);
- g_mime_stream_flush (filtered);
- g_object_unref (filtered);
+ g_mime_object_write_to_stream (entity, options, stream);
+ g_mime_format_options_free (options);
/* reset the content stream */
g_mime_stream_reset (stream);
@@ -501,7 +490,7 @@ g_mime_application_pkcs7_mime_verify (GMimeApplicationPkcs7Mime *pkcs7_mime, GMi
stream = g_mime_stream_mem_new ();
filtered = g_mime_stream_filter_new (stream);
- filter = g_mime_filter_crlf_new (FALSE, FALSE);
+ filter = g_mime_filter_dos2unix_new (FALSE);
g_mime_stream_filter_add ((GMimeStreamFilter *) filtered, filter);
g_object_unref (filter);
diff --git a/gmime/gmime-filter-dos2unix.c b/gmime/gmime-filter-dos2unix.c
new file mode 100644
index 0000000..9d7e6e0
--- /dev/null
+++ b/gmime/gmime-filter-dos2unix.c
@@ -0,0 +1,188 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* GMime
+ * Copyright (C) 2000-2017 Jeffrey Stedfast
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gmime-filter-dos2unix.h"
+
+
+/**
+ * SECTION: gmime-filter-dos2unix
+ * @title: GMimeFilterDos2Unix
+ * @short_description: Convert line-endings from Windows/DOS (CRLF) to UNIX (LF).
+ *
+ * A #GMimeFilter for converting from DOS to UNIX line-endings.
+ **/
+
+
+static void g_mime_filter_dos2unix_class_init (GMimeFilterDos2UnixClass *klass);
+static void g_mime_filter_dos2unix_init (GMimeFilterDos2Unix *filter, GMimeFilterDos2UnixClass *klass);
+static void g_mime_filter_dos2unix_finalize (GObject *object);
+
+static GMimeFilter *filter_copy (GMimeFilter *filter);
+static void filter_filter (GMimeFilter *filter, char *in, size_t len, size_t prespace,
+ char **out, size_t *outlen, size_t *outprespace);
+static void filter_complete (GMimeFilter *filter, char *in, size_t len, size_t prespace,
+ char **out, size_t *outlen, size_t *outprespace);
+static void filter_reset (GMimeFilter *filter);
+
+
+static GMimeFilterClass *parent_class = NULL;
+
+
+GType
+g_mime_filter_dos2unix_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ static const GTypeInfo info = {
+ sizeof (GMimeFilterDos2UnixClass),
+ NULL, /* base_class_init */
+ NULL, /* base_class_finalize */
+ (GClassInitFunc) g_mime_filter_dos2unix_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GMimeFilterDos2Unix),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) g_mime_filter_dos2unix_init,
+ };
+
+ type = g_type_register_static (GMIME_TYPE_FILTER, "GMimeFilterDos2Unix", &info, 0);
+ }
+
+ return type;
+}
+
+
+static void
+g_mime_filter_dos2unix_class_init (GMimeFilterDos2UnixClass *klass)
+{
+ GMimeFilterClass *filter_class = GMIME_FILTER_CLASS (klass);
+
+ parent_class = g_type_class_ref (GMIME_TYPE_FILTER);
+
+ filter_class->copy = filter_copy;
+ filter_class->filter = filter_filter;
+ filter_class->complete = filter_complete;
+ filter_class->reset = filter_reset;
+}
+
+static void
+g_mime_filter_dos2unix_init (GMimeFilterDos2Unix *filter, GMimeFilterDos2UnixClass *klass)
+{
+ filter->ensure_newline = FALSE;
+ filter->pc = '\0';
+}
+
+
+static GMimeFilter *
+filter_copy (GMimeFilter *filter)
+{
+ GMimeFilterDos2Unix *dos2unix = (GMimeFilterDos2Unix *) filter;
+
+ return g_mime_filter_dos2unix_new (dos2unix->ensure_newline);
+}
+
+static void
+convert (GMimeFilter *filter, char *inbuf, size_t inlen, size_t prespace,
+ char **outbuf, size_t *outlen, size_t *outprespace, gboolean flush)
+{
+ GMimeFilterDos2Unix *dos2unix = (GMimeFilterDos2Unix *) filter;
+ register const char *inptr = inbuf;
+ const char *inend = inbuf + inlen;
+ size_t expected = inlen;
+ char *outptr;
+
+ if (flush && dos2unix->ensure_newline)
+ expected++;
+
+ if (dos2unix->pc == '\r')
+ expected++;
+
+ g_mime_filter_set_size (filter, expected, FALSE);
+
+ outptr = filter->outbuf;
+ while (inptr < inend) {
+ if (*inptr == '\n') {
+ *outptr++ = *inptr;
+ } else {
+ if (dos2unix->pc == '\r')
+ *outptr++ = dos2unix->pc;
+
+ if (*inptr != '\r')
+ *outptr++ = *inptr;
+ }
+
+ dos2unix->pc = *inptr++;
+ }
+
+ if (flush && dos2unix->ensure_newline && dos2unix->pc != '\n')
+ dos2unix->pc = *outptr++ = '\n';
+
+ *outlen = outptr - filter->outbuf;
+ *outprespace = filter->outpre;
+ *outbuf = filter->outbuf;
+}
+
+static void
+filter_filter (GMimeFilter *filter, char *inbuf, size_t inlen, size_t prespace,
+ char **outbuf, size_t *outlen, size_t *outprespace)
+{
+ convert (filter, inbuf, inlen, prespace, outbuf, outlen, outprespace, FALSE);
+}
+
+static void
+filter_complete (GMimeFilter *filter, char *inbuf, size_t inlen, size_t prespace,
+ char **outbuf, size_t *outlen, size_t *outprespace)
+{
+ convert (filter, inbuf, inlen, prespace, outbuf, outlen, outprespace, TRUE);
+}
+
+static void
+filter_reset (GMimeFilter *filter)
+{
+ GMimeFilterDos2Unix *dos2unix = (GMimeFilterDos2Unix *) filter;
+
+ dos2unix->pc = '\0';
+}
+
+
+/**
+ * g_mime_filter_dos2unix_new:
+ * @ensure_newline: %TRUE if the filter should ensure that the stream ends in a new line
+ *
+ * Creates a new #GMimeFilterDos2Unix filter.
+ *
+ * Returns: a new #GMimeFilterDos2Unix filter.
+ **/
+GMimeFilter *
+g_mime_filter_dos2unix_new (gboolean ensure_newline)
+{
+ GMimeFilterDos2Unix *dos2unix;
+
+ dos2unix = g_object_newv (GMIME_TYPE_FILTER_DOS2UNIX, 0, NULL);
+ dos2unix->ensure_newline = ensure_newline;
+
+ return (GMimeFilter *) dos2unix;
+}
diff --git a/gmime/gmime-filter-dos2unix.h b/gmime/gmime-filter-dos2unix.h
new file mode 100644
index 0000000..1e7960f
--- /dev/null
+++ b/gmime/gmime-filter-dos2unix.h
@@ -0,0 +1,66 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* GMime
+ * Copyright (C) 2000-2017 Jeffrey Stedfast
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+
+#ifndef __GMIME_FILTER_DOS2UNIX_H__
+#define __GMIME_FILTER_DOS2UNIX_H__
+
+#include <gmime/gmime-filter.h>
+
+G_BEGIN_DECLS
+
+#define GMIME_TYPE_FILTER_DOS2UNIX (g_mime_filter_dos2unix_get_type ())
+#define GMIME_FILTER_DOS2UNIX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),
GMIME_TYPE_FILTER_DOS2UNIX, GMimeFilterDos2Unix))
+#define GMIME_FILTER_DOS2UNIX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMIME_TYPE_FILTER_DOS2UNIX,
GMimeFilterDos2UnixClass))
+#define GMIME_IS_FILTER_DOS2UNIX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),
GMIME_TYPE_FILTER_DOS2UNIX))
+#define GMIME_IS_FILTER_DOS2UNIX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GMIME_TYPE_FILTER_DOS2UNIX))
+#define GMIME_FILTER_DOS2UNIX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMIME_TYPE_FILTER_DOS2UNIX,
GMimeFilterDos2UnixClass))
+
+typedef struct _GMimeFilterDos2Unix GMimeFilterDos2Unix;
+typedef struct _GMimeFilterDos2UnixClass GMimeFilterDos2UnixClass;
+
+/**
+ * GMimeFilterDos2Unix:
+ * @parent_object: parent #GMimeFilter
+ * @ensure_newline: %TRUE if the filter should ensure that the stream ends with a new line
+ * @pc: the previous character encountered
+ *
+ * A filter to convert a stream from Windows/DOS line endings to Unix line endings.
+ **/
+struct _GMimeFilterDos2Unix {
+ GMimeFilter parent_object;
+
+ gboolean ensure_newline;
+ char pc;
+};
+
+struct _GMimeFilterDos2UnixClass {
+ GMimeFilterClass parent_class;
+
+};
+
+
+GType g_mime_filter_dos2unix_get_type (void);
+
+GMimeFilter *g_mime_filter_dos2unix_new (gboolean ensure_newline);
+
+G_END_DECLS
+
+#endif /* __GMIME_FILTER_DOS2UNIX_H__ */
diff --git a/gmime/gmime-filter-unix2dos.c b/gmime/gmime-filter-unix2dos.c
new file mode 100644
index 0000000..f1d6865
--- /dev/null
+++ b/gmime/gmime-filter-unix2dos.c
@@ -0,0 +1,188 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* GMime
+ * Copyright (C) 2000-2017 Jeffrey Stedfast
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gmime-filter-unix2dos.h"
+
+
+/**
+ * SECTION: gmime-filter-unix2dos
+ * @title: GMimeFilterUnix2Dos
+ * @short_description: Convert line-endings from UNIX (LF) to Windows/DOS (CRLF).
+ *
+ * A #GMimeFilter for converting from UNIX to DOS line-endings.
+ **/
+
+
+static void g_mime_filter_unix2dos_class_init (GMimeFilterUnix2DosClass *klass);
+static void g_mime_filter_unix2dos_init (GMimeFilterUnix2Dos *filter, GMimeFilterUnix2DosClass *klass);
+static void g_mime_filter_unix2dos_finalize (GObject *object);
+
+static GMimeFilter *filter_copy (GMimeFilter *filter);
+static void filter_filter (GMimeFilter *filter, char *in, size_t len, size_t prespace,
+ char **out, size_t *outlen, size_t *outprespace);
+static void filter_complete (GMimeFilter *filter, char *in, size_t len, size_t prespace,
+ char **out, size_t *outlen, size_t *outprespace);
+static void filter_reset (GMimeFilter *filter);
+
+
+static GMimeFilterClass *parent_class = NULL;
+
+
+GType
+g_mime_filter_unix2dos_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ static const GTypeInfo info = {
+ sizeof (GMimeFilterUnix2DosClass),
+ NULL, /* base_class_init */
+ NULL, /* base_class_finalize */
+ (GClassInitFunc) g_mime_filter_unix2dos_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GMimeFilterUnix2Dos),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) g_mime_filter_unix2dos_init,
+ };
+
+ type = g_type_register_static (GMIME_TYPE_FILTER, "GMimeFilterUnix2Dos", &info, 0);
+ }
+
+ return type;
+}
+
+
+static void
+g_mime_filter_unix2dos_class_init (GMimeFilterUnix2DosClass *klass)
+{
+ GMimeFilterClass *filter_class = GMIME_FILTER_CLASS (klass);
+
+ parent_class = g_type_class_ref (GMIME_TYPE_FILTER);
+
+ filter_class->copy = filter_copy;
+ filter_class->filter = filter_filter;
+ filter_class->complete = filter_complete;
+ filter_class->reset = filter_reset;
+}
+
+static void
+g_mime_filter_unix2dos_init (GMimeFilterUnix2Dos *filter, GMimeFilterUnix2DosClass *klass)
+{
+ filter->ensure_newline = FALSE;
+ filter->pc = '\0';
+}
+
+
+static GMimeFilter *
+filter_copy (GMimeFilter *filter)
+{
+ GMimeFilterUnix2Dos *unix2dos = (GMimeFilterUnix2Dos *) filter;
+
+ return g_mime_filter_unix2dos_new (unix2dos->ensure_newline);
+}
+
+static void
+convert (GMimeFilter *filter, char *inbuf, size_t inlen, size_t prespace,
+ char **outbuf, size_t *outlen, size_t *outprespace, gboolean flush)
+{
+ GMimeFilterUnix2Dos *unix2dos = (GMimeFilterUnix2Dos *) filter;
+ register const char *inptr = inbuf;
+ const char *inend = inbuf + inlen;
+ size_t expected = inlen * 2;
+ char *outptr;
+
+ if (flush && unix2dos->ensure_newline)
+ expected += 2;
+
+ g_mime_filter_set_size (filter, expected, FALSE);
+
+ outptr = filter->outbuf;
+ while (inptr < inend) {
+ if (*inptr == '\r') {
+ *outptr++ = *inptr;
+ } else if (*inptr == '\n') {
+ if (unix2dos->pc != '\r')
+ *outptr++ = '\r';
+ *outptr++ = *inptr;
+ } else {
+ *outptr++ = *inptr;
+ }
+
+ unix2dos->pc = *inptr++;
+ }
+
+ if (flush && unix2dos->ensure_newline && unix2dos->pc != '\n') {
+ if (unix2dos->pc != '\r')
+ *outptr++ = '\r';
+ *outptr++ = '\n';
+ }
+
+ *outlen = outptr - filter->outbuf;
+ *outprespace = filter->outpre;
+ *outbuf = filter->outbuf;
+}
+
+static void
+filter_filter (GMimeFilter *filter, char *inbuf, size_t inlen, size_t prespace,
+ char **outbuf, size_t *outlen, size_t *outprespace)
+{
+ convert (filter, inbuf, inlen, prespace, outbuf, outlen, outprespace, FALSE);
+}
+
+static void
+filter_complete (GMimeFilter *filter, char *inbuf, size_t inlen, size_t prespace,
+ char **outbuf, size_t *outlen, size_t *outprespace)
+{
+ convert (filter, inbuf, inlen, prespace, outbuf, outlen, outprespace, TRUE);
+}
+
+static void
+filter_reset (GMimeFilter *filter)
+{
+ GMimeFilterUnix2Dos *unix2dos = (GMimeFilterUnix2Dos *) filter;
+
+ unix2dos->pc = '\0';
+}
+
+
+/**
+ * g_mime_filter_unix2dos_new:
+ * @ensure_newline: %TRUE if the filter should ensure that the stream ends in a new line
+ *
+ * Creates a new #GMimeFilterUnix2Dos filter.
+ *
+ * Returns: a new #GMimeFilterUnix2Dos filter.
+ **/
+GMimeFilter *
+g_mime_filter_unix2dos_new (gboolean ensure_newline)
+{
+ GMimeFilterUnix2Dos *unix2dos;
+
+ unix2dos = g_object_newv (GMIME_TYPE_FILTER_UNIX2DOS, 0, NULL);
+ unix2dos->ensure_newline = ensure_newline;
+
+ return (GMimeFilter *) unix2dos;
+}
diff --git a/gmime/gmime-filter-unix2dos.h b/gmime/gmime-filter-unix2dos.h
new file mode 100644
index 0000000..7b8246d
--- /dev/null
+++ b/gmime/gmime-filter-unix2dos.h
@@ -0,0 +1,66 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* GMime
+ * Copyright (C) 2000-2017 Jeffrey Stedfast
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+
+#ifndef __GMIME_FILTER_UNIX2DOS_H__
+#define __GMIME_FILTER_UNIX2DOS_H__
+
+#include <gmime/gmime-filter.h>
+
+G_BEGIN_DECLS
+
+#define GMIME_TYPE_FILTER_UNIX2DOS (g_mime_filter_unix2dos_get_type ())
+#define GMIME_FILTER_UNIX2DOS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),
GMIME_TYPE_FILTER_UNIX2DOS, GMimeFilterUnix2Dos))
+#define GMIME_FILTER_UNIX2DOS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GMIME_TYPE_FILTER_UNIX2DOS,
GMimeFilterUnix2DosClass))
+#define GMIME_IS_FILTER_UNIX2DOS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),
GMIME_TYPE_FILTER_UNIX2DOS))
+#define GMIME_IS_FILTER_UNIX2DOS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GMIME_TYPE_FILTER_UNIX2DOS))
+#define GMIME_FILTER_UNIX2DOS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GMIME_TYPE_FILTER_UNIX2DOS,
GMimeFilterUnix2DosClass))
+
+typedef struct _GMimeFilterUnix2Dos GMimeFilterUnix2Dos;
+typedef struct _GMimeFilterUnix2DosClass GMimeFilterUnix2DosClass;
+
+/**
+ * GMimeFilterUnix2Dos:
+ * @parent_object: parent #GMimeFilter
+ * @ensure_newline: %TRUE if the filter should ensure that the stream ends with a new line
+ * @pc: the previous character encountered
+ *
+ * A filter to convert a stream from Windows/DOS line endings to Unix line endings.
+ **/
+struct _GMimeFilterUnix2Dos {
+ GMimeFilter parent_object;
+
+ gboolean ensure_newline;
+ char pc;
+};
+
+struct _GMimeFilterUnix2DosClass {
+ GMimeFilterClass parent_class;
+
+};
+
+
+GType g_mime_filter_unix2dos_get_type (void);
+
+GMimeFilter *g_mime_filter_unix2dos_new (gboolean ensure_newline);
+
+G_END_DECLS
+
+#endif /* __GMIME_FILTER_UNIX2DOS_H__ */
diff --git a/gmime/gmime-filter.c b/gmime/gmime-filter.c
index e57563d..e43e470 100644
--- a/gmime/gmime-filter.c
+++ b/gmime/gmime-filter.c
@@ -143,7 +143,7 @@ filter_copy (GMimeFilter *filter)
* g_mime_filter_copy:
* @filter: filter
*
- * Copies @filter into a new GMimeFilter object.
+ * Copies @filter into a new #GMimeFilter object.
*
* Returns: (transfer full): a duplicate of @filter.
**/
diff --git a/gmime/gmime-format-options.c b/gmime/gmime-format-options.c
index a7e2e67..500503d 100644
--- a/gmime/gmime-format-options.c
+++ b/gmime/gmime-format-options.c
@@ -26,7 +26,8 @@
#include <string.h>
#include "gmime-format-options.h"
-#include "gmime-filter-crlf.h"
+#include "gmime-filter-dos2unix.h"
+#include "gmime-filter-unix2dos.h"
static GMimeFormatOptions *default_options = NULL;
@@ -269,9 +270,9 @@ g_mime_format_options_create_newline_filter (GMimeFormatOptions *options, gboole
options = default_options;
if (options->newline == GMIME_NEWLINE_FORMAT_DOS)
- return g_mime_filter_crlf_new (TRUE, FALSE);
+ return g_mime_filter_unix2dos_new (ensure_newline);
- return g_mime_filter_crlf_new (FALSE, FALSE);
+ return g_mime_filter_dos2unix_new (ensure_newline);
}
diff --git a/gmime/gmime-format-options.h b/gmime/gmime-format-options.h
index 83c4366..870b7d3 100644
--- a/gmime/gmime-format-options.h
+++ b/gmime/gmime-format-options.h
@@ -91,8 +91,8 @@ void g_mime_format_options_free (GMimeFormatOptions *options);
GMimeParamEncodingMethod g_mime_format_options_get_param_encoding_method (GMimeFormatOptions *options);
void g_mime_format_options_set_param_encoding_method (GMimeFormatOptions *options, GMimeParamEncodingMethod
method);
-GMimeNewLineFormat g_mime_format_get_newline_format (GMimeFormatOptions *options);
-void g_mime_format_set_newline_format (GMimeFormatOptions *options, GMimeNewLineFormat newline);
+GMimeNewLineFormat g_mime_format_options_get_newline_format (GMimeFormatOptions *options);
+void g_mime_format_options_set_newline_format (GMimeFormatOptions *options, GMimeNewLineFormat newline);
const char *g_mime_format_options_get_newline (GMimeFormatOptions *options);
GMimeFilter *g_mime_format_options_create_newline_filter (GMimeFormatOptions *options, gboolean
ensure_newline);
diff --git a/gmime/gmime-message.c b/gmime/gmime-message.c
index 89e0b8d..3bad84d 100644
--- a/gmime/gmime-message.c
+++ b/gmime/gmime-message.c
@@ -207,6 +207,7 @@ g_mime_message_init (GMimeMessage *message, GMimeMessageClass *klass)
guint i;
message->addrlists = g_new (InternetAddressList *, N_ADDRESS_TYPES);
+ message->compliance = GMIME_RFC_COMPLIANCE_STRICT;
message->message_id = NULL;
message->mime_part = NULL;
message->subject = NULL;
@@ -979,8 +980,11 @@ message_write_to_stream (GMimeObject *object, GMimeFormatOptions *options, gbool
GMimeObjectClass *klass = GMIME_OBJECT_GET_CLASS (mime_part);
options = _g_mime_format_options_clone (options, FALSE);
+ mime_part->ensure_newline = message->compliance == GMIME_RFC_COMPLIANCE_STRICT;
+ nwritten = klass->write_to_stream (mime_part, options, TRUE, stream);
+ mime_part->ensure_newline = FALSE;
- if ((nwritten = klass->write_to_stream (mime_part, options, TRUE, stream)) == -1)
+ if (nwritten == -1)
return -1;
total += nwritten;
diff --git a/gmime/gmime-message.h b/gmime/gmime-message.h
index ddfcd2b..bd59f22 100644
--- a/gmime/gmime-message.h
+++ b/gmime/gmime-message.h
@@ -85,8 +85,11 @@ struct _GMimeMessage {
char *message_id;
char *subject;
- time_t date;
int tz_offset;
+ time_t date;
+
+ /* < private > */
+ GMimeRfcComplianceMode compliance;
};
struct _GMimeMessageClass {
diff --git a/gmime/gmime-multipart-encrypted.c b/gmime/gmime-multipart-encrypted.c
index dcc362b..084dd5c 100644
--- a/gmime/gmime-multipart-encrypted.c
+++ b/gmime/gmime-multipart-encrypted.c
@@ -27,11 +27,12 @@
#include <string.h>
#include "gmime-multipart-encrypted.h"
+#include "gmime-filter-dos2unix.h"
#include "gmime-stream-filter.h"
#include "gmime-filter-basic.h"
#include "gmime-filter-from.h"
-#include "gmime-filter-crlf.h"
#include "gmime-stream-mem.h"
+#include "gmime-internal.h"
#include "gmime-parser.h"
#include "gmime-part.h"
#include "gmime-error.h"
@@ -158,12 +159,11 @@ GMimeMultipartEncrypted *
g_mime_multipart_encrypted_encrypt (GMimeCryptoContext *ctx, GMimeObject *entity, gboolean sign, const char
*userid,
GMimeEncryptFlags flags, GPtrArray *recipients, GError **err)
{
- GMimeParserOptions *options = g_mime_parser_options_get_default ();
- GMimeFormatOptions *format = g_mime_format_options_get_default ();
- GMimeStream *filtered, *stream, *ciphertext;
GMimePart *version_part, *encrypted_part;
GMimeMultipartEncrypted *encrypted;
+ GMimeStream *stream, *ciphertext;
GMimeContentType *content_type;
+ GMimeFormatOptions *options;
GMimeDataWrapper *content;
const char *protocol;
GMimeFilter *filter;
@@ -178,15 +178,11 @@ g_mime_multipart_encrypted_encrypt (GMimeCryptoContext *ctx, GMimeObject *entity
/* get the cleartext */
stream = g_mime_stream_mem_new ();
- filtered = g_mime_stream_filter_new (stream);
- filter = g_mime_filter_crlf_new (TRUE, FALSE);
- g_mime_stream_filter_add ((GMimeStreamFilter *) filtered, filter);
- g_object_unref (filter);
+ options = _g_mime_format_options_clone (NULL, FALSE);
+ g_mime_format_options_set_newline_format (options, GMIME_NEWLINE_FORMAT_DOS);
- g_mime_object_write_to_stream (entity, format, filtered);
- g_mime_stream_flush (filtered);
- g_object_unref (filtered);
+ g_mime_object_write_to_stream (entity, options, stream);
/* reset the content stream */
g_mime_stream_reset (stream);
@@ -203,12 +199,10 @@ g_mime_multipart_encrypted_encrypt (GMimeCryptoContext *ctx, GMimeObject *entity
g_mime_stream_reset (ciphertext);
/* construct the version part */
- content_type = g_mime_content_type_parse (options, protocol);
+ content_type = g_mime_content_type_parse (NULL, protocol);
version_part = g_mime_part_new_with_type (content_type->type, content_type->subtype);
g_object_unref (content_type);
- content_type = g_mime_content_type_parse (options, protocol);
- g_mime_object_set_content_type ((GMimeObject *) version_part, content_type);
g_mime_part_set_content_encoding (version_part, GMIME_CONTENT_ENCODING_7BIT);
stream = g_mime_stream_mem_new_with_buffer ("Version: 1\n", strlen ("Version: 1\n"));
content = g_mime_data_wrapper_new_with_stream (stream, GMIME_CONTENT_ENCODING_7BIT);
@@ -346,7 +340,7 @@ g_mime_multipart_encrypted_decrypt (GMimeMultipartEncrypted *encrypted, GMimeDec
stream = g_mime_stream_mem_new ();
filtered = g_mime_stream_filter_new (stream);
- filter = g_mime_filter_crlf_new (FALSE, FALSE);
+ filter = g_mime_filter_dos2unix_new (FALSE);
g_mime_stream_filter_add ((GMimeStreamFilter *) filtered, filter);
g_object_unref (filter);
diff --git a/gmime/gmime-multipart-signed.c b/gmime/gmime-multipart-signed.c
index a02bf14..7f87e39 100644
--- a/gmime/gmime-multipart-signed.c
+++ b/gmime/gmime-multipart-signed.c
@@ -29,10 +29,11 @@
#include "gmime-multipart-encrypted.h"
#include "gmime-message-part.h"
#include "gmime-stream-filter.h"
+#include "gmime-filter-unix2dos.h"
#include "gmime-filter-strip.h"
#include "gmime-filter-from.h"
-#include "gmime-filter-crlf.h"
#include "gmime-stream-mem.h"
+#include "gmime-internal.h"
#include "gmime-parser.h"
#include "gmime-error.h"
#include "gmime-part.h"
@@ -211,8 +212,6 @@ GMimeMultipartSigned *
g_mime_multipart_signed_sign (GMimeCryptoContext *ctx, GMimeObject *entity,
const char *userid, GError **err)
{
- GMimeParserOptions *options = g_mime_parser_options_get_default ();
- GMimeFormatOptions *format = g_mime_format_options_get_default ();
GMimeStream *stream, *filtered, *sigstream;
GMimeContentType *content_type;
GMimeDataWrapper *content;
@@ -249,14 +248,17 @@ g_mime_multipart_signed_sign (GMimeCryptoContext *ctx, GMimeObject *entity,
g_mime_stream_filter_add ((GMimeStreamFilter *) filtered, filter);
g_object_unref (filter);
- g_mime_object_write_to_stream (entity, format, filtered);
+ /* write the entity out to the stream */
+ g_mime_object_write_to_stream (entity, NULL, filtered);
g_mime_stream_flush (filtered);
g_mime_stream_reset (stream);
g_object_unref (filtered);
- /* Note: see rfc2015 or rfc3156, section 5.1 */
+ /* Note: see rfc2015 or rfc3156, section 5.1 - we do this *after* writing out
+ * the entity because we'll end up parsing the mime part back out again and
+ * we don't want it to be in DOS format. */
filtered = g_mime_stream_filter_new (stream);
- filter = g_mime_filter_crlf_new (TRUE, FALSE);
+ filter = g_mime_filter_unix2dos_new (FALSE);
g_mime_stream_filter_add ((GMimeStreamFilter *) filtered, filter);
g_object_unref (filter);
@@ -282,7 +284,7 @@ g_mime_multipart_signed_sign (GMimeCryptoContext *ctx, GMimeObject *entity,
g_object_unref (parser);
/* construct the signature part */
- content_type = g_mime_content_type_parse (options, protocol);
+ content_type = g_mime_content_type_parse (NULL, protocol);
signature = g_mime_part_new_with_type (content_type->type, content_type->subtype);
g_object_unref (content_type);
@@ -368,11 +370,11 @@ check_protocol_supported (const char *protocol, const char *supported)
GMimeSignatureList *
g_mime_multipart_signed_verify (GMimeMultipartSigned *mps, GMimeVerifyFlags flags, GError **err)
{
- GMimeFormatOptions *options = g_mime_format_options_get_default ();
GMimeStream *filtered, *stream, *sigstream;
const char *supported, *protocol;
GMimeObject *content, *signature;
GMimeSignatureList *signatures;
+ GMimeFormatOptions *options;
GMimeDataWrapper *wrapper;
GMimeCryptoContext *ctx;
GMimeDigestAlgo digest;
@@ -435,14 +437,17 @@ g_mime_multipart_signed_verify (GMimeMultipartSigned *mps, GMimeVerifyFlags flag
filtered = g_mime_stream_filter_new (stream);
/* Note: see rfc2015 or rfc3156, section 5.1 */
- filter = g_mime_filter_crlf_new (TRUE, FALSE);
+ filter = g_mime_filter_unix2dos_new (FALSE);
g_mime_stream_filter_add ((GMimeStreamFilter *) filtered, filter);
g_object_unref (filter);
+ // FIXME: use the GMimeFormatOptions...
+ //options = _g_mime_format_options_clone (NULL, FALSE);
+ //g_mime_format_options_set_newline_format (options, GMIME_NEWLINE_FORMAT_DOS);
- g_mime_object_write_to_stream (content, options, filtered);
- g_mime_stream_flush (filtered);
- g_object_unref (filtered);
+ g_mime_object_write_to_stream (content, NULL, filtered);
+ //g_mime_format_options_free (options);
g_mime_stream_reset (stream);
+ g_object_unref (filtered);
/* get the signature stream */
wrapper = g_mime_part_get_content ((GMimePart *) signature);
diff --git a/gmime/gmime-object.c b/gmime/gmime-object.c
index b321a86..d119f8a 100644
--- a/gmime/gmime-object.c
+++ b/gmime/gmime-object.c
@@ -142,6 +142,7 @@ g_mime_object_init (GMimeObject *object, GMimeObjectClass *klass)
g_mime_event_add (headers->changed, (GMimeEventCallback) header_list_changed, object);
object->headers = headers;
+ object->ensure_newline = FALSE;
object->content_type = NULL;
object->disposition = NULL;
object->content_id = NULL;
diff --git a/gmime/gmime-object.h b/gmime/gmime-object.h
index ed82fd8..f02d069 100644
--- a/gmime/gmime-object.h
+++ b/gmime/gmime-object.h
@@ -61,8 +61,10 @@ struct _GMimeObject {
GMimeContentDisposition *disposition;
GMimeContentType *content_type;
GMimeHeaderList *headers;
-
char *content_id;
+
+ /* < private > */
+ gboolean ensure_newline;
};
struct _GMimeObjectClass {
diff --git a/gmime/gmime-parser.c b/gmime/gmime-parser.c
index fc683a8..3da3018 100644
--- a/gmime/gmime-parser.c
+++ b/gmime/gmime-parser.c
@@ -1692,6 +1692,7 @@ parser_scan_message_part (GMimeParser *parser, GMimeParserOptions *options, GMim
}
message = g_mime_message_new (FALSE);
+ message->compliance = GMIME_RFC_COMPLIANCE_LOOSE;
header = priv->headers;
while (header) {
if (g_ascii_strncasecmp (header->name, "Content-", 8) != 0) {
@@ -2005,6 +2006,7 @@ parser_construct_message (GMimeParser *parser, GMimeParserOptions *options)
}
message = g_mime_message_new (FALSE);
+ message->compliance = GMIME_RFC_COMPLIANCE_LOOSE;
header = priv->headers;
while (header) {
if (priv->respect_content_length && !g_ascii_strcasecmp (header->name, "Content-Length")) {
diff --git a/gmime/gmime-part.c b/gmime/gmime-part.c
index 96a6f3c..e0419ef 100644
--- a/gmime/gmime-part.c
+++ b/gmime/gmime-part.c
@@ -37,8 +37,8 @@
#include "gmime-stream-filter.h"
#include "gmime-filter-basic.h"
#include "gmime-filter-best.h"
-#include "gmime-filter-crlf.h"
#include "gmime-filter-md5.h"
+#include "gmime-filter-unix2dos.h"
#include "gmime-table-private.h"
#define _(x) x
@@ -301,6 +301,7 @@ mime_part_headers_cleared (GMimeObject *object)
static ssize_t
write_content (GMimePart *part, GMimeFormatOptions *options, GMimeStream *stream)
{
+ GMimeObject *object = (GMimeObject *) part;
ssize_t nwritten, total = 0;
GMimeStream *filtered;
GMimeFilter *filter;
@@ -341,9 +342,11 @@ write_content (GMimePart *part, GMimeFormatOptions *options, GMimeStream *stream
break;
}
- filter = g_mime_format_options_create_newline_filter (options, FALSE);
- g_mime_stream_filter_add ((GMimeStreamFilter *) filtered, filter);
- g_object_unref (filter);
+ if (part->encoding != GMIME_CONTENT_ENCODING_BINARY) {
+ filter = g_mime_format_options_create_newline_filter (options,
object->ensure_newline);
+ g_mime_stream_filter_add ((GMimeStreamFilter *) filtered, filter);
+ g_object_unref (filter);
+ }
nwritten = g_mime_data_wrapper_write_to_stream (part->content, filtered);
g_mime_stream_flush (filtered);
@@ -367,11 +370,15 @@ write_content (GMimePart *part, GMimeFormatOptions *options, GMimeStream *stream
g_mime_stream_reset (content);
filtered = g_mime_stream_filter_new (stream);
- filter = g_mime_format_options_create_newline_filter (options, FALSE);
- g_mime_stream_filter_add ((GMimeStreamFilter *) filtered, filter);
- g_object_unref (filter);
+
+ if (part->encoding != GMIME_CONTENT_ENCODING_BINARY) {
+ filter = g_mime_format_options_create_newline_filter (options,
object->ensure_newline);
+ g_mime_stream_filter_add ((GMimeStreamFilter *) filtered, filter);
+ g_object_unref (filter);
+ }
nwritten = g_mime_stream_write_to_stream (content, filtered);
+ g_mime_stream_flush (filtered);
g_mime_stream_reset (content);
g_object_unref (filtered);
@@ -603,10 +610,9 @@ g_mime_part_set_content_md5 (GMimePart *mime_part, const char *content_md5)
{
GMimeObject *object = (GMimeObject *) mime_part;
unsigned char digest[16], b64digest[32];
- GMimeStreamFilter *filtered_stream;
GMimeContentType *content_type;
- GMimeFilter *md5_filter;
- GMimeStream *stream;
+ GMimeStream *filtered, *stream;
+ GMimeFilter *filter;
guint32 save = 0;
int state = 0;
size_t len;
@@ -618,28 +624,25 @@ g_mime_part_set_content_md5 (GMimePart *mime_part, const char *content_md5)
if (!content_md5) {
/* compute a md5sum */
stream = g_mime_stream_null_new ();
- filtered_stream = (GMimeStreamFilter *) g_mime_stream_filter_new (stream);
+ filtered = g_mime_stream_filter_new (stream);
g_object_unref (stream);
content_type = g_mime_object_get_content_type ((GMimeObject *) mime_part);
if (g_mime_content_type_is_type (content_type, "text", "*")) {
- GMimeFilter *crlf_filter;
-
- crlf_filter = g_mime_filter_crlf_new (TRUE, FALSE);
- g_mime_stream_filter_add (filtered_stream, crlf_filter);
- g_object_unref (crlf_filter);
+ filter = g_mime_filter_unix2dos_new (FALSE);
+ g_mime_stream_filter_add ((GMimeStreamFilter *) filtered, filter);
+ g_object_unref (filter);
}
- md5_filter = g_mime_filter_md5_new ();
- g_mime_stream_filter_add (filtered_stream, md5_filter);
+ filter = g_mime_filter_md5_new ();
+ g_mime_stream_filter_add ((GMimeStreamFilter *) filtered, filter);
- stream = (GMimeStream *) filtered_stream;
- g_mime_data_wrapper_write_to_stream (mime_part->content, stream);
- g_object_unref (stream);
+ g_mime_data_wrapper_write_to_stream (mime_part->content, filtered);
+ g_object_unref (filtered);
memset (digest, 0, 16);
- g_mime_filter_md5_get_digest ((GMimeFilterMd5 *) md5_filter, digest);
- g_object_unref (md5_filter);
+ g_mime_filter_md5_get_digest ((GMimeFilterMd5 *) filter, digest);
+ g_object_unref (filter);
len = g_mime_encoding_base64_encode_close (digest, 16, b64digest, &state, &save);
b64digest[len] = '\0';
@@ -669,10 +672,9 @@ gboolean
g_mime_part_verify_content_md5 (GMimePart *mime_part)
{
unsigned char digest[16], b64digest[32];
- GMimeStreamFilter *filtered_stream;
GMimeContentType *content_type;
- GMimeFilter *md5_filter;
- GMimeStream *stream;
+ GMimeStream *filtered, *stream;
+ GMimeFilter *filter;
guint32 save = 0;
int state = 0;
size_t len;
@@ -684,28 +686,25 @@ g_mime_part_verify_content_md5 (GMimePart *mime_part)
return FALSE;
stream = g_mime_stream_null_new ();
- filtered_stream = (GMimeStreamFilter *) g_mime_stream_filter_new (stream);
+ filtered = g_mime_stream_filter_new (stream);
g_object_unref (stream);
content_type = g_mime_object_get_content_type ((GMimeObject *) mime_part);
if (g_mime_content_type_is_type (content_type, "text", "*")) {
- GMimeFilter *crlf_filter;
-
- crlf_filter = g_mime_filter_crlf_new (TRUE, FALSE);
- g_mime_stream_filter_add (filtered_stream, crlf_filter);
- g_object_unref (crlf_filter);
+ filter = g_mime_filter_unix2dos_new (FALSE);
+ g_mime_stream_filter_add ((GMimeStreamFilter *) filtered, filter);
+ g_object_unref (filter);
}
- md5_filter = g_mime_filter_md5_new ();
- g_mime_stream_filter_add (filtered_stream, md5_filter);
+ filter = g_mime_filter_md5_new ();
+ g_mime_stream_filter_add ((GMimeStreamFilter *) filtered, filter);
- stream = (GMimeStream *) filtered_stream;
- g_mime_data_wrapper_write_to_stream (mime_part->content, stream);
- g_object_unref (stream);
+ g_mime_data_wrapper_write_to_stream (mime_part->content, filtered);
+ g_object_unref (filtered);
memset (digest, 0, 16);
- g_mime_filter_md5_get_digest ((GMimeFilterMd5 *) md5_filter, digest);
- g_object_unref (md5_filter);
+ g_mime_filter_md5_get_digest ((GMimeFilterMd5 *) filter, digest);
+ g_object_unref (filter);
len = g_mime_encoding_base64_encode_close (digest, 16, b64digest, &state, &save);
b64digest[len] = '\0';
diff --git a/gmime/gmime.c b/gmime/gmime.c
index 9fcc858..77cea63 100644
--- a/gmime/gmime.c
+++ b/gmime/gmime.c
@@ -147,12 +147,14 @@ g_mime_init (void)
g_mime_filter_best_get_type ();
g_mime_filter_charset_get_type ();
g_mime_filter_crlf_get_type ();
+ g_mime_filter_dos2unix_get_type ();
g_mime_filter_enriched_get_type ();
g_mime_filter_from_get_type ();
g_mime_filter_gzip_get_type ();
g_mime_filter_html_get_type ();
g_mime_filter_md5_get_type ();
g_mime_filter_strip_get_type ();
+ g_mime_filter_unix2dos_get_type ();
g_mime_filter_windows_get_type ();
g_mime_filter_yenc_get_type ();
diff --git a/gmime/gmime.h b/gmime/gmime.h
index 84717d4..d1a4764 100644
--- a/gmime/gmime.h
+++ b/gmime/gmime.h
@@ -65,12 +65,14 @@
#include <gmime/gmime-filter-best.h>
#include <gmime/gmime-filter-charset.h>
#include <gmime/gmime-filter-crlf.h>
+#include <gmime/gmime-filter-dos2unix.h>
#include <gmime/gmime-filter-enriched.h>
#include <gmime/gmime-filter-from.h>
#include <gmime/gmime-filter-gzip.h>
#include <gmime/gmime-filter-html.h>
#include <gmime/gmime-filter-md5.h>
#include <gmime/gmime-filter-strip.h>
+#include <gmime/gmime-filter-unix2dos.h>
#include <gmime/gmime-filter-windows.h>
#include <gmime/gmime-filter-yenc.h>
#include <gmime/gmime-crypto-context.h>
diff --git a/tests/test-pgpmime.c b/tests/test-pgpmime.c
index 45f5e6c..014668f 100644
--- a/tests/test-pgpmime.c
+++ b/tests/test-pgpmime.c
@@ -221,6 +221,7 @@ static void
test_multipart_signed (GMimeCryptoContext *ctx)
{
GMimeSignatureList *signatures;
+ GMimeSignatureStatus status;
GMimeMultipartSigned *mps;
GMimeMessage *message;
GMimeTextPart *part;
@@ -259,9 +260,13 @@ test_multipart_signed (GMimeCryptoContext *ctx)
}
v(print_verify_results (signatures));
- g_object_unref (signatures);
+ status = get_sig_status (signatures);
+ g_object_unref (signatures);
g_object_unref (message);
+
+ if (status & GMIME_SIGNATURE_STATUS_RED)
+ throw (exception_new ("signature status was BAD"));
}
#define MULTIPART_ENCRYPTED_CONTENT "This is a test of multipart/encrypted.\n"
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]