[gmime] GMIME_ENABLE_RFC2047_WORKAROUNDS is no more. Use GMimeParserOptions instead.
- From: Jeffrey Stedfast <fejj src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gmime] GMIME_ENABLE_RFC2047_WORKAROUNDS is no more. Use GMimeParserOptions instead.
- Date: Tue, 7 Feb 2017 02:44:21 +0000 (UTC)
commit 055c05ff9de58b2951c7399e251675f17cb19fe8
Author: Jeffrey Stedfast <jestedfa microsoft com>
Date: Mon Feb 6 21:43:44 2017 -0500
GMIME_ENABLE_RFC2047_WORKAROUNDS is no more. Use GMimeParserOptions instead.
PORTING | 15 ++++
gmime/gmime-content-type.c | 9 ++-
gmime/gmime-content-type.h | 2 +-
gmime/gmime-disposition.c | 9 ++-
gmime/gmime-disposition.h | 2 +-
gmime/gmime-header.c | 30 +++++++-
gmime/gmime-header.h | 6 +-
gmime/gmime-message.c | 54 +++++++-------
gmime/gmime-multipart-encrypted.c | 6 +-
gmime/gmime-multipart-signed.c | 4 +-
gmime/gmime-object.c | 40 +++++++----
gmime/gmime-object.h | 5 +-
gmime/gmime-param.c | 19 +++---
gmime/gmime-param.h | 3 +-
gmime/gmime-parser-options.c | 57 +++++++++++++--
gmime/gmime-parser-options.h | 2 +
gmime/gmime-parser.c | 10 +--
gmime/gmime-utils.c | 140 ++++++++++---------------------------
gmime/gmime-utils.h | 14 ++--
gmime/gmime.c | 7 --
gmime/gmime.h | 11 +---
gmime/internet-address.c | 27 ++++----
gmime/internet-address.h | 4 +-
tests/test-headers.c | 2 +-
tests/test-mime.c | 58 +++++++++------
25 files changed, 287 insertions(+), 249 deletions(-)
---
diff --git a/PORTING b/PORTING
index 68e951d..843a6d7 100644
--- a/PORTING
+++ b/PORTING
@@ -41,6 +41,21 @@ Porting from GMime 2.6 to GMime 3.0
argument remains as it has always been, an unfolded (but still encoded)
header value.
+- g_mime_object_new() and g_mime_object_new_with_type() both now take a
+ GMimeParserOptions argument.
+
+- g_mime_param_new_from_string() has been replaced by g_mime_param_parse()
+ and now takes a GMimeParserOptions argument.
+
+- g_mime_content_type_new_from_string() has been replaced by
+ g_mime_content_type_parse() and now takes a GMimeParserOptions argument.
+
+- g_mime_content_disposition_new_from_string() has been replaced by
+ g_mime_content_disposition_parse() and now takes a GMimeParserOptions argument.
+
+- internet_address_list_parse_string() has been replaced by
+ internet_address_list_parse() and now takes a GMimeParserOptions argument.
+
- GMimeHeaderIter has been dropped in favour of a more direct way of
iterating over a GMimeHeaderList using int indexes.
diff --git a/gmime/gmime-content-type.c b/gmime/gmime-content-type.c
index bd8c07f..022bfdf 100644
--- a/gmime/gmime-content-type.c
+++ b/gmime/gmime-content-type.c
@@ -167,15 +167,16 @@ g_mime_content_type_new (const char *type, const char *subtype)
/**
- * g_mime_content_type_new_from_string:
+ * g_mime_content_type_parse:
+ * @options: a #GMimeParserOptions
* @str: input string containing a content-type (and params)
*
- * Constructs a new Content-Type object based on the input string.
+ * Parses the input string into a #GMimeContentType object.
*
* Returns: a new #GMimeContentType object based on the input string.
**/
GMimeContentType *
-g_mime_content_type_new_from_string (const char *str)
+g_mime_content_type_parse (GMimeParserOptions *options, const char *str)
{
GMimeContentType *mime_type;
const char *inptr = str;
@@ -198,7 +199,7 @@ g_mime_content_type_new_from_string (const char *str)
if (*inptr++ == ';' && *inptr) {
GMimeParam *param;
- param = mime_type->params = g_mime_param_new_from_string (inptr);
+ param = mime_type->params = g_mime_param_parse (options, inptr);
while (param != NULL) {
g_hash_table_insert (mime_type->param_hash, param->name, param);
param = param->next;
diff --git a/gmime/gmime-content-type.h b/gmime/gmime-content-type.h
index 3938dd1..a0fc292 100644
--- a/gmime/gmime-content-type.h
+++ b/gmime/gmime-content-type.h
@@ -71,7 +71,7 @@ GType g_mime_content_type_get_type (void);
GMimeContentType *g_mime_content_type_new (const char *type, const char *subtype);
-GMimeContentType *g_mime_content_type_new_from_string (const char *str);
+GMimeContentType *g_mime_content_type_parse (GMimeParserOptions *options, const char *str);
char *g_mime_content_type_to_string (GMimeContentType *mime_type);
diff --git a/gmime/gmime-disposition.c b/gmime/gmime-disposition.c
index 7edd39e..3123f24 100644
--- a/gmime/gmime-disposition.c
+++ b/gmime/gmime-disposition.c
@@ -128,15 +128,16 @@ g_mime_content_disposition_new (void)
/**
- * g_mime_content_disposition_new_from_string:
+ * g_mime_content_disposition_parse:
+ * @options: a #GMimeParserOptions
* @str: Content-Disposition field value or %NULL
*
- * Creates a new #GMimeContentDisposition object.
+ * Parses the input string into a #GMimeContentDisposition object.
*
* Returns: a new #GMimeContentDisposition object.
**/
GMimeContentDisposition *
-g_mime_content_disposition_new_from_string (const char *str)
+g_mime_content_disposition_parse (GMimeParserOptions *options, const char *str)
{
GMimeContentDisposition *disposition;
const char *inptr = str;
@@ -159,7 +160,7 @@ g_mime_content_disposition_new_from_string (const char *str)
/* parse the parameters, if any */
if (*inptr++ == ';' && *inptr) {
- param = disposition->params = g_mime_param_new_from_string (inptr);
+ param = disposition->params = g_mime_param_parse (options, inptr);
while (param) {
g_hash_table_insert (disposition->param_hash, param->name, param);
diff --git a/gmime/gmime-disposition.h b/gmime/gmime-disposition.h
index 2a2f3e6..7aae985 100644
--- a/gmime/gmime-disposition.h
+++ b/gmime/gmime-disposition.h
@@ -85,7 +85,7 @@ GType g_mime_content_disposition_get_type (void);
GMimeContentDisposition *g_mime_content_disposition_new (void);
-GMimeContentDisposition *g_mime_content_disposition_new_from_string (const char *str);
+GMimeContentDisposition *g_mime_content_disposition_parse (GMimeParserOptions *options, const char *str);
void g_mime_content_disposition_set_disposition (GMimeContentDisposition *disposition, const char *value);
const char *g_mime_content_disposition_get_disposition (GMimeContentDisposition *disposition);
diff --git a/gmime/gmime-header.c b/gmime/gmime-header.c
index 3c918cf..a9479b7 100644
--- a/gmime/gmime-header.c
+++ b/gmime/gmime-header.c
@@ -45,6 +45,8 @@
* values.
**/
+extern GMimeParserOptions *_g_mime_parser_options_clone (GMimeParserOptions *options);
+
struct _GMimeHeader {
GMimeHeaderList *list;
gint64 offset;
@@ -54,6 +56,7 @@ struct _GMimeHeader {
};
struct _GMimeHeaderList {
+ GMimeParserOptions *options;
GHashTable *writers;
GMimeEvent *changed;
GHashTable *hash;
@@ -208,12 +211,12 @@ _g_mime_header_set_offset (GMimeHeader *header, gint64 offset)
}
static ssize_t
-default_writer (GMimeStream *stream, const char *name, const char *value)
+default_writer (GMimeParserOptions *options, GMimeStream *stream, const char *name, const char *value)
{
ssize_t nwritten;
char *val;
- val = g_mime_utils_header_printf ("%s: %s\n", name, value);
+ val = g_mime_utils_header_printf (options, "%s: %s\n", name, value);
nwritten = g_mime_stream_write_string (stream, val);
g_free (val);
@@ -253,7 +256,7 @@ g_mime_header_write_to_stream (GMimeHeader *header, GMimeStream *stream)
if (!(writer = g_hash_table_lookup (header->list->writers, header->name)))
writer = default_writer;
- if ((nwritten = writer (stream, header->name, header->value)) == -1)
+ if ((nwritten = writer (header->list->options, stream, header->name, header->value)) == -1)
return -1;
total += nwritten;
@@ -265,17 +268,21 @@ g_mime_header_write_to_stream (GMimeHeader *header, GMimeStream *stream)
/**
* g_mime_header_list_new:
+ * @options: a #GMimeParserOptions
*
* Creates a new #GMimeHeaderList object.
*
* Returns: a new header list object.
**/
GMimeHeaderList *
-g_mime_header_list_new (void)
+g_mime_header_list_new (GMimeParserOptions *options)
{
GMimeHeaderList *headers;
+ g_return_val_if_fail (options != NULL, NULL);
+
headers = g_slice_new (GMimeHeaderList);
+ headers->options = _g_mime_parser_options_clone (options);
headers->writers = g_hash_table_new_full (g_mime_strcase_hash,
g_mime_strcase_equal,
g_free, NULL);
@@ -307,6 +314,7 @@ g_mime_header_list_destroy (GMimeHeaderList *headers)
g_ptr_array_free (headers->list, TRUE);
+ g_mime_parser_options_free (headers->options);
g_hash_table_destroy (headers->writers);
g_hash_table_destroy (headers->hash);
@@ -340,6 +348,20 @@ g_mime_header_list_clear (GMimeHeaderList *headers)
}
+GMimeParserOptions *
+_g_mime_header_list_get_options (GMimeHeaderList *headers)
+{
+ return headers->options;
+}
+
+void
+_g_mime_header_list_set_options (GMimeHeaderList *headers, GMimeParserOptions *options)
+{
+ g_mime_parser_options_free (headers->options);
+ headers->options = _g_mime_parser_options_clone (options);
+}
+
+
/**
* g_mime_header_list_get_count:
* @headers: a #GMimeHeaderList
diff --git a/gmime/gmime-header.h b/gmime/gmime-header.h
index f088ef9..c51a79e 100644
--- a/gmime/gmime-header.h
+++ b/gmime/gmime-header.h
@@ -23,6 +23,7 @@
#define __GMIME_HEADER_H__
#include <glib.h>
+#include <gmime/gmime-parser-options.h>
#include <gmime/gmime-stream.h>
G_BEGIN_DECLS
@@ -30,6 +31,7 @@ G_BEGIN_DECLS
/**
* GMimeHeaderWriter:
+ * @options: The #GMimeParserOptions
* @stream: The output stream.
* @name: The field name.
* @value: The field value.
@@ -39,7 +41,7 @@ G_BEGIN_DECLS
*
* Returns: the number of bytes written or %-1 on error.
**/
-typedef ssize_t (* GMimeHeaderWriter) (GMimeStream *stream, const char *name, const char *value);
+typedef ssize_t (* GMimeHeaderWriter) (GMimeParserOptions *options, GMimeStream *stream, const char *name,
const char *value);
/**
@@ -66,7 +68,7 @@ ssize_t g_mime_header_write_to_stream (GMimeHeader *header, GMimeStream *stream)
**/
typedef struct _GMimeHeaderList GMimeHeaderList;
-GMimeHeaderList *g_mime_header_list_new (void);
+GMimeHeaderList *g_mime_header_list_new (GMimeParserOptions *options);
void g_mime_header_list_destroy (GMimeHeaderList *headers);
diff --git a/gmime/gmime-message.c b/gmime/gmime-message.c
index 178ccda..ded2555 100644
--- a/gmime/gmime-message.c
+++ b/gmime/gmime-message.c
@@ -55,13 +55,14 @@ extern void _g_mime_object_set_header (GMimeObject *object, const char *header,
extern void _g_mime_header_set_offset (GMimeHeader *header, gint64 offset);
+extern GMimeParserOptions *_g_mime_header_list_get_options (GMimeHeaderList *headers);
extern void _g_mime_header_list_prepend (GMimeHeaderList *headers, const char *name, const char *value,
const char *raw_value, gint64 offset);
extern void _g_mime_header_list_append (GMimeHeaderList *headers, const char *name, const char *value, const
char *raw_value, gint64 offset);
extern void _g_mime_header_list_set (GMimeHeaderList *headers, const char *name, const char *value, const
char *raw_value, gint64 offset);
extern GMimeEvent *_g_mime_header_list_get_changed_event (GMimeHeaderList *headers);
-extern char *_g_mime_utils_unstructured_header_fold (const char *field, const char *value);
-extern char *_g_mime_utils_structured_header_fold (const char *field, const char *value);
+extern char *_g_mime_utils_unstructured_header_fold (GMimeParserOptions *options, const char *field, const
char *value);
+extern char *_g_mime_utils_structured_header_fold (GMimeParserOptions *options, const char *field, const
char *value);
static void g_mime_message_class_init (GMimeMessageClass *klass);
static void g_mime_message_init (GMimeMessage *message, GMimeMessageClass *klass);
@@ -77,12 +78,12 @@ static char *message_get_headers (GMimeObject *object);
static ssize_t message_write_to_stream (GMimeObject *object, GMimeStream *stream, gboolean content_only);
static void message_encode (GMimeObject *object, GMimeEncodingConstraint constraint);
-/*static ssize_t write_structured (GMimeStream *stream, const char *name, const char *value);*/
-static ssize_t write_references (GMimeStream *stream, const char *name, const char *value);
-static ssize_t write_addrspec (GMimeStream *stream, const char *name, const char *value);
-static ssize_t write_received (GMimeStream *stream, const char *name, const char *value);
-static ssize_t write_subject (GMimeStream *stream, const char *name, const char *value);
-static ssize_t write_msgid (GMimeStream *stream, const char *name, const char *value);
+/*static ssize_t write_structured (GMimeParserOptions *options, GMimeStream *stream, const char *name, const
char *value);*/
+static ssize_t write_references (GMimeParserOptions *options, GMimeStream *stream, const char *name, const
char *value);
+static ssize_t write_addrspec (GMimeParserOptions *options, GMimeStream *stream, const char *name, const
char *value);
+static ssize_t write_received (GMimeParserOptions *options, GMimeStream *stream, const char *name, const
char *value);
+static ssize_t write_subject (GMimeParserOptions *options, GMimeStream *stream, const char *name, const char
*value);
+static ssize_t write_msgid (GMimeParserOptions *options, GMimeStream *stream, const char *name, const char
*value);
static void sender_changed (InternetAddressList *list, gpointer args, GMimeMessage *message);
@@ -491,7 +492,7 @@ struct _received_part {
};
static ssize_t
-write_received (GMimeStream *stream, const char *name, const char *value)
+write_received (GMimeParserOptions *options, GMimeStream *stream, const char *name, const char *value)
{
struct _received_part *parts, *part, *tail;
const char *inptr, *lwsp = NULL;
@@ -604,12 +605,12 @@ write_received (GMimeStream *stream, const char *name, const char *value)
}
static ssize_t
-write_subject (GMimeStream *stream, const char *name, const char *value)
+write_subject (GMimeParserOptions *options, GMimeStream *stream, const char *name, const char *value)
{
char *folded;
ssize_t n;
- folded = _g_mime_utils_unstructured_header_fold (name, value);
+ folded = _g_mime_utils_unstructured_header_fold (options, name, value);
n = g_mime_stream_write_string (stream, folded);
g_free (folded);
@@ -617,7 +618,7 @@ write_subject (GMimeStream *stream, const char *name, const char *value)
}
static ssize_t
-write_msgid (GMimeStream *stream, const char *name, const char *value)
+write_msgid (GMimeParserOptions *options, GMimeStream *stream, const char *name, const char *value)
{
/* Note: we don't want to wrap the Message-Id header - seems to
break a lot of clients (and servers) */
@@ -625,7 +626,7 @@ write_msgid (GMimeStream *stream, const char *name, const char *value)
}
static ssize_t
-write_references (GMimeStream *stream, const char *name, const char *value)
+write_references (GMimeParserOptions *options, GMimeStream *stream, const char *name, const char *value)
{
GMimeReferences *references, *reference;
ssize_t nwritten;
@@ -669,12 +670,12 @@ write_references (GMimeStream *stream, const char *name, const char *value)
#if 0
static ssize_t
-write_structured (GMimeStream *stream, const char *name, const char *value)
+write_structured (GMimeParserOptions *options, GMimeStream *stream, const char *name, const char *value)
{
char *folded;
ssize_t n;
- folded = _g_mime_utils_structured_header_fold (name, value);
+ folded = _g_mime_utils_structured_header_fold (options, name, value);
n = g_mime_stream_write_string (stream, folded);
g_free (folded);
@@ -683,7 +684,7 @@ write_structured (GMimeStream *stream, const char *name, const char *value)
#endif
static ssize_t
-write_addrspec (GMimeStream *stream, const char *name, const char *value)
+write_addrspec (GMimeParserOptions *options, GMimeStream *stream, const char *name, const char *value)
{
InternetAddressList *addrlist;
GString *str;
@@ -692,7 +693,7 @@ write_addrspec (GMimeStream *stream, const char *name, const char *value)
str = g_string_new (name);
g_string_append (str, ": ");
- if (value && (addrlist = internet_address_list_parse_string (value))) {
+ if (value && (addrlist = internet_address_list_parse (options, value))) {
internet_address_list_writer (addrlist, str);
g_object_unref (addrlist);
}
@@ -739,7 +740,7 @@ enum {
};
static void
-message_add_addresses_from_string (GMimeMessage *message, int action, GMimeAddressType type, const char *str)
+message_add_addresses_from_string (GMimeParserOptions *options, GMimeMessage *message, int action,
GMimeAddressType type, const char *str)
{
InternetAddressList *addrlist, *list;
@@ -748,7 +749,7 @@ message_add_addresses_from_string (GMimeMessage *message, int action, GMimeAddre
if (action == SET)
internet_address_list_clear (addrlist);
- if ((list = internet_address_list_parse_string (str))) {
+ if ((list = internet_address_list_parse (options, str))) {
if (action == PREPEND)
internet_address_list_prepend (addrlist, list);
else
@@ -761,6 +762,7 @@ message_add_addresses_from_string (GMimeMessage *message, int action, GMimeAddre
static gboolean
process_header (GMimeObject *object, int action, const char *header, const char *value)
{
+ GMimeParserOptions *options = _g_mime_header_list_get_options (object->headers);
GMimeMessage *message = (GMimeMessage *) object;
InternetAddressList *addrlist;
time_t date;
@@ -775,37 +777,37 @@ process_header (GMimeObject *object, int action, const char *header, const char
switch (i) {
case HEADER_SENDER:
block_changed_event (message, GMIME_ADDRESS_TYPE_SENDER);
- message_add_addresses_from_string (message, SET, GMIME_ADDRESS_TYPE_SENDER, value);
+ message_add_addresses_from_string (options, message, SET, GMIME_ADDRESS_TYPE_SENDER, value);
unblock_changed_event (message, GMIME_ADDRESS_TYPE_SENDER);
break;
case HEADER_FROM:
block_changed_event (message, GMIME_ADDRESS_TYPE_FROM);
- message_add_addresses_from_string (message, SET, GMIME_ADDRESS_TYPE_FROM, value);
+ message_add_addresses_from_string (options, message, SET, GMIME_ADDRESS_TYPE_FROM, value);
unblock_changed_event (message, GMIME_ADDRESS_TYPE_FROM);
break;
case HEADER_REPLY_TO:
block_changed_event (message, GMIME_ADDRESS_TYPE_REPLY_TO);
- message_add_addresses_from_string (message, SET, GMIME_ADDRESS_TYPE_REPLY_TO, value);
+ message_add_addresses_from_string (options, message, SET, GMIME_ADDRESS_TYPE_REPLY_TO, value);
unblock_changed_event (message, GMIME_ADDRESS_TYPE_REPLY_TO);
break;
case HEADER_TO:
block_changed_event (message, GMIME_ADDRESS_TYPE_TO);
- message_add_addresses_from_string (message, action, GMIME_ADDRESS_TYPE_TO, value);
+ message_add_addresses_from_string (options, message, action, GMIME_ADDRESS_TYPE_TO, value);
unblock_changed_event (message, GMIME_ADDRESS_TYPE_TO);
break;
case HEADER_CC:
block_changed_event (message, GMIME_ADDRESS_TYPE_CC);
- message_add_addresses_from_string (message, action, GMIME_ADDRESS_TYPE_CC, value);
+ message_add_addresses_from_string (options, message, action, GMIME_ADDRESS_TYPE_CC, value);
unblock_changed_event (message, GMIME_ADDRESS_TYPE_CC);
break;
case HEADER_BCC:
block_changed_event (message, GMIME_ADDRESS_TYPE_BCC);
- message_add_addresses_from_string (message, action, GMIME_ADDRESS_TYPE_BCC, value);
+ message_add_addresses_from_string (options, message, action, GMIME_ADDRESS_TYPE_BCC, value);
unblock_changed_event (message, GMIME_ADDRESS_TYPE_BCC);
break;
case HEADER_SUBJECT:
g_free (message->subject);
- message->subject = g_mime_utils_header_decode_text (value);
+ message->subject = g_mime_utils_header_decode_text (options, value);
break;
case HEADER_DATE:
if (value) {
diff --git a/gmime/gmime-multipart-encrypted.c b/gmime/gmime-multipart-encrypted.c
index 1cd07c3..640d98a 100644
--- a/gmime/gmime-multipart-encrypted.c
+++ b/gmime/gmime-multipart-encrypted.c
@@ -56,7 +56,6 @@
* multipart/encrypted MIME type.
**/
-
/* GObject class methods */
static void g_mime_multipart_encrypted_class_init (GMimeMultipartEncryptedClass *klass);
static void g_mime_multipart_encrypted_init (GMimeMultipartEncrypted *mps, GMimeMultipartEncryptedClass
*klass);
@@ -163,6 +162,7 @@ g_mime_multipart_encrypted_encrypt (GMimeMultipartEncrypted *mpe, GMimeObject *c
const char *userid, GMimeDigestAlgo digest,
GPtrArray *recipients, GError **err)
{
+ GMimeParserOptions *options = g_mime_parser_options_get_default ();
GMimeStream *filtered_stream, *ciphertext, *stream;
GMimePart *version_part, *encrypted_part;
GMimeContentType *content_type;
@@ -206,11 +206,11 @@ g_mime_multipart_encrypted_encrypt (GMimeMultipartEncrypted *mpe, GMimeObject *c
g_mime_stream_reset (ciphertext);
/* construct the version part */
- content_type = g_mime_content_type_new_from_string (protocol);
+ content_type = g_mime_content_type_parse (options, 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_new_from_string (protocol);
+ content_type = g_mime_content_type_parse (options, protocol);
g_mime_object_set_content_type (GMIME_OBJECT (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"));
diff --git a/gmime/gmime-multipart-signed.c b/gmime/gmime-multipart-signed.c
index 2e10439..f660585 100644
--- a/gmime/gmime-multipart-signed.c
+++ b/gmime/gmime-multipart-signed.c
@@ -57,7 +57,6 @@
* multipart/signed MIME type.
**/
-
/* GObject class methods */
static void g_mime_multipart_signed_class_init (GMimeMultipartSignedClass *klass);
static void g_mime_multipart_signed_init (GMimeMultipartSigned *mps, GMimeMultipartSignedClass *klass);
@@ -217,6 +216,7 @@ g_mime_multipart_signed_sign (GMimeMultipartSigned *mps, GMimeObject *content,
GMimeCryptoContext *ctx, const char *userid,
GMimeDigestAlgo digest, GError **err)
{
+ GMimeParserOptions *options = g_mime_parser_options_get_default ();
GMimeStream *stream, *filtered, *sigstream;
GMimeContentType *content_type;
GMimeDataWrapper *wrapper;
@@ -293,7 +293,7 @@ g_mime_multipart_signed_sign (GMimeMultipartSigned *mps, GMimeObject *content,
g_object_unref (parser);
/* construct the signature part */
- content_type = g_mime_content_type_new_from_string (protocol);
+ content_type = g_mime_content_type_parse (options, protocol);
signature = g_mime_part_new_with_type (content_type->type, content_type->subtype);
g_object_unref (content_type);
diff --git a/gmime/gmime-object.c b/gmime/gmime-object.c
index beacbd2..6bc99b1 100644
--- a/gmime/gmime-object.c
+++ b/gmime/gmime-object.c
@@ -55,6 +55,11 @@ struct _subtype_bucket {
GType object_type;
};
+extern GMimeParserOptions *_g_mime_parser_options_clone (GMimeParserOptions *options);
+
+extern GMimeParserOptions *_g_mime_header_list_get_options (GMimeHeaderList *headers);
+extern void _g_mime_header_list_set_options (GMimeHeaderList *headers, GMimeParserOptions *options);
+
extern void _g_mime_header_list_prepend (GMimeHeaderList *headers, const char *name, const char *value,
const char *raw_value, gint64 offset);
extern void _g_mime_header_list_append (GMimeHeaderList *headers, const char *name, const char *value, const
char *raw_value, gint64 offset);
extern void _g_mime_header_list_set (GMimeHeaderList *headers, const char *name, const char *value, const
char *raw_value, gint64 offset);
@@ -76,8 +81,8 @@ static char *object_get_headers (GMimeObject *object);
static ssize_t object_write_to_stream (GMimeObject *object, GMimeStream *stream, gboolean content_only);
static void object_encode (GMimeObject *object, GMimeEncodingConstraint constraint);
-static ssize_t write_content_type (GMimeStream *stream, const char *name, const char *value);
-static ssize_t write_disposition (GMimeStream *stream, const char *name, const char *value);
+static ssize_t write_content_type (GMimeParserOptions *options, GMimeStream *stream, const char *name, const
char *value);
+static ssize_t write_disposition (GMimeParserOptions *options, GMimeStream *stream, const char *name, const
char *value);
static void content_type_changed (GMimeContentType *content_type, gpointer args, GMimeObject *object);
static void content_disposition_changed (GMimeContentDisposition *disposition, gpointer args, GMimeObject
*object);
@@ -120,7 +125,7 @@ g_mime_object_class_init (GMimeObjectClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
parent_class = g_type_class_ref (G_TYPE_OBJECT);
-
+
object_class->finalize = g_mime_object_finalize;
klass->prepend_header = object_prepend_header;
@@ -137,7 +142,7 @@ g_mime_object_class_init (GMimeObjectClass *klass)
static void
g_mime_object_init (GMimeObject *object, GMimeObjectClass *klass)
{
- object->headers = g_mime_header_list_new ();
+ object->headers = g_mime_header_list_new (g_mime_parser_options_get_default ());
object->content_type = NULL;
object->disposition = NULL;
object->content_id = NULL;
@@ -146,6 +151,7 @@ g_mime_object_init (GMimeObject *object, GMimeObjectClass *klass)
g_mime_header_list_register_writer (object->headers, "Content-Disposition", write_disposition);
}
+
static void
g_mime_object_finalize (GObject *object)
{
@@ -171,7 +177,7 @@ g_mime_object_finalize (GObject *object)
static ssize_t
-write_content_type (GMimeStream *stream, const char *name, const char *value)
+write_content_type (GMimeParserOptions *options, GMimeStream *stream, const char *name, const char *value)
{
GMimeContentType *content_type;
ssize_t nwritten;
@@ -181,7 +187,7 @@ write_content_type (GMimeStream *stream, const char *name, const char *value)
out = g_string_new ("");
g_string_printf (out, "%s: ", name);
- content_type = g_mime_content_type_new_from_string (value);
+ content_type = g_mime_content_type_parse (options, value);
val = g_mime_content_type_to_string (content_type);
g_string_append (out, val);
@@ -221,7 +227,7 @@ content_type_changed (GMimeContentType *content_type, gpointer args, GMimeObject
}
static ssize_t
-write_disposition (GMimeStream *stream, const char *name, const char *value)
+write_disposition (GMimeParserOptions *options, GMimeStream *stream, const char *name, const char *value)
{
GMimeContentDisposition *disposition;
ssize_t nwritten;
@@ -230,7 +236,7 @@ write_disposition (GMimeStream *stream, const char *name, const char *value)
out = g_string_new ("");
g_string_printf (out, "%s: ", name);
- disposition = g_mime_content_disposition_new_from_string (value);
+ disposition = g_mime_content_disposition_parse (options, value);
g_string_append (out, disposition->disposition);
g_mime_param_write_to_string (disposition->params, TRUE, out);
@@ -296,6 +302,7 @@ g_mime_object_register_type (const char *type, const char *subtype, GType object
/**
* g_mime_object_new:
+ * @options: a #GMimeParserOptions
* @content_type: a #GMimeContentType object
*
* Performs a lookup of registered #GMimeObject subclasses, registered
@@ -310,7 +317,7 @@ g_mime_object_register_type (const char *type, const char *subtype, GType object
* parts appropriate for @content_type.
**/
GMimeObject *
-g_mime_object_new (GMimeContentType *content_type)
+g_mime_object_new (GMimeParserOptions *options, GMimeContentType *content_type)
{
struct _type_bucket *bucket;
struct _subtype_bucket *sub;
@@ -341,6 +348,7 @@ g_mime_object_new (GMimeContentType *content_type)
}
object = g_object_newv (obj_type, 0, NULL);
+ _g_mime_header_list_set_options (object->headers, options);
g_mime_object_set_content_type (object, content_type);
@@ -350,6 +358,7 @@ g_mime_object_new (GMimeContentType *content_type)
/**
* g_mime_object_new_type:
+ * @options: a #GMimeParserOptions
* @type: mime type
* @subtype: mime subtype
*
@@ -364,10 +373,11 @@ g_mime_object_new (GMimeContentType *content_type)
* of @type/@subtype.
**/
GMimeObject *
-g_mime_object_new_type (const char *type, const char *subtype)
+g_mime_object_new_type (GMimeParserOptions *options, const char *type, const char *subtype)
{
struct _type_bucket *bucket;
struct _subtype_bucket *sub;
+ GMimeObject *object;
GType obj_type;
g_return_val_if_fail (type != NULL, NULL);
@@ -393,7 +403,10 @@ g_mime_object_new_type (const char *type, const char *subtype)
return NULL;
}
- return g_object_newv (obj_type, 0, NULL);
+ object = g_object_newv (obj_type, 0, NULL);
+ _g_mime_header_list_set_options (object->headers, options);
+
+ return object;
}
@@ -739,6 +752,7 @@ static char *content_headers[] = {
static gboolean
process_header (GMimeObject *object, const char *header, const char *value, const char *raw_value, gint64
offset)
{
+ GMimeParserOptions *options = _g_mime_header_list_get_options (object->headers);
GMimeContentDisposition *disposition;
GMimeContentType *content_type;
guint i;
@@ -753,12 +767,12 @@ process_header (GMimeObject *object, const char *header, const char *value, cons
switch (i) {
case HEADER_CONTENT_DISPOSITION:
- disposition = g_mime_content_disposition_new_from_string (value);
+ disposition = g_mime_content_disposition_parse (options, value);
_g_mime_object_set_content_disposition (object, disposition);
g_object_unref (disposition);
break;
case HEADER_CONTENT_TYPE:
- content_type = g_mime_content_type_new_from_string (value);
+ content_type = g_mime_content_type_parse (options, value);
_g_mime_object_set_content_type (object, content_type);
g_object_unref (content_type);
break;
diff --git a/gmime/gmime-object.h b/gmime/gmime-object.h
index d49c947..9a3fe2a 100644
--- a/gmime/gmime-object.h
+++ b/gmime/gmime-object.h
@@ -25,6 +25,7 @@
#include <glib.h>
#include <glib-object.h>
+#include <gmime/gmime-parser-options.h>
#include <gmime/gmime-content-type.h>
#include <gmime/gmime-disposition.h>
#include <gmime/gmime-encodings.h>
@@ -98,8 +99,8 @@ GType g_mime_object_get_type (void);
void g_mime_object_register_type (const char *type, const char *subtype, GType object_type);
-GMimeObject *g_mime_object_new (GMimeContentType *content_type);
-GMimeObject *g_mime_object_new_type (const char *type, const char *subtype);
+GMimeObject *g_mime_object_new (GMimeParserOptions *options, GMimeContentType *content_type);
+GMimeObject *g_mime_object_new_type (GMimeParserOptions *options, const char *type, const char *subtype);
void g_mime_object_set_content_type (GMimeObject *object, GMimeContentType *content_type);
GMimeContentType *g_mime_object_get_content_type (GMimeObject *object);
diff --git a/gmime/gmime-param.c b/gmime/gmime-param.c
index 62f2293..3f357dd 100644
--- a/gmime/gmime-param.c
+++ b/gmime/gmime-param.c
@@ -284,7 +284,7 @@ decode_rfc2184_param (const char **in, char **paramp, int *part, gboolean *encod
}
static gboolean
-decode_param (const char **in, char **paramp, char **valuep, int *id, gboolean *encoded)
+decode_param (GMimeParserOptions *options, const char **in, char **paramp, char **valuep, int *id, gboolean
*encoded)
{
gboolean is_rfc2184 = FALSE;
const char *inptr = *in;
@@ -304,7 +304,7 @@ decode_param (const char **in, char **paramp, char **valuep, int *id, gboolean *
* this, we should handle this case.
*/
- if ((val = g_mime_utils_header_decode_text (value))) {
+ if ((val = g_mime_utils_header_decode_text (options, value))) {
g_free (value);
value = val;
}
@@ -529,7 +529,7 @@ rfc2184_param_new (char *name, char *value, int id, gboolean encoded)
}
static GMimeParam *
-decode_param_list (const char *in)
+decode_param_list (GMimeParserOptions *options, const char *in)
{
struct _rfc2184_param *rfc2184, *list, *t;
GMimeParam *param, *params, *tail;
@@ -553,7 +553,7 @@ decode_param_list (const char *in)
do {
/* invalid format? */
- if (!decode_param (&inptr, &name, &value, &id, &encoded)) {
+ if (!decode_param (options, &inptr, &name, &value, &id, &encoded)) {
decode_lwsp (&inptr);
if (*inptr == ';')
@@ -631,19 +631,20 @@ decode_param_list (const char *in)
/**
- * g_mime_param_new_from_string:
+ * g_mime_param_parse:
+ * @options: a #GMimeParserOptions
* @str: input string
*
- * Creates a parameter list based on the input string.
+ * Parses the input stringinto a parameter list.
*
- * Returns: a #GMimeParam structure based on @string.
+ * Returns: a #GMimeParam linked list based on @text.
**/
GMimeParam *
-g_mime_param_new_from_string (const char *str)
+g_mime_param_parse (GMimeParserOptions *options, const char *str)
{
g_return_val_if_fail (str != NULL, NULL);
- return decode_param_list (str);
+ return decode_param_list (options, str);
}
diff --git a/gmime/gmime-param.h b/gmime/gmime-param.h
index f095050..94a7b0e 100644
--- a/gmime/gmime-param.h
+++ b/gmime/gmime-param.h
@@ -23,6 +23,7 @@
#define __GMIME_PARAM_H__
#include <glib.h>
+#include <gmime/gmime-parser-options.h>
G_BEGIN_DECLS
@@ -44,7 +45,7 @@ struct _GMimeParam {
};
GMimeParam *g_mime_param_new (const char *name, const char *value);
-GMimeParam *g_mime_param_new_from_string (const char *str);
+GMimeParam *g_mime_param_parse (GMimeParserOptions *options, const char *str);
void g_mime_param_destroy (GMimeParam *param);
const GMimeParam *g_mime_param_next (const GMimeParam *param);
diff --git a/gmime/gmime-parser-options.c b/gmime/gmime-parser-options.c
index 786f78d..5080ba4 100644
--- a/gmime/gmime-parser-options.c
+++ b/gmime/gmime-parser-options.c
@@ -30,7 +30,7 @@
static char *default_charsets[3] = { "utf-8", "iso-8859-1", NULL };
-GMimeParserOptions g_mime_parser_options_default = {
+static GMimeParserOptions g_mime_parser_options_default = {
GMIME_RFC_COMPLIANCE_LOOSE,
GMIME_RFC_COMPLIANCE_LOOSE,
GMIME_RFC_COMPLIANCE_LOOSE,
@@ -39,6 +39,20 @@ GMimeParserOptions g_mime_parser_options_default = {
/**
+ * g_mime_parser_options_get_default:
+ *
+ * Gets the default parser options.
+ *
+ * Returns: the default parser options.
+ **/
+GMimeParserOptions *
+g_mime_parser_options_get_default (void)
+{
+ return &g_mime_parser_options_default;
+}
+
+
+/**
* @g_mime_parser_options_new:
*
* Creates a new set of #GMimeParserOptions.
@@ -65,6 +79,37 @@ g_mime_parser_options_new (void)
/**
+ * _g_mime_parser_options_clone:
+ * @options: a #GMimeParserOptions
+ *
+ * Clones a #GMimeParserOptions.
+ *
+ * Returns: a newly allocated #GMimeParserOptions.
+ **/
+GMimeParserOptions *
+_g_mime_parser_options_clone (GMimeParserOptions *options)
+{
+ GMimeParserOptions *clone;
+ guint i, n = 0;
+
+ clone = g_slice_new (GMimeParserOptions);
+ clone->addresses = options->addresses;
+ clone->parameters = options->parameters;
+ clone->rfc2047 = options->rfc2047;
+
+ while (options->charsets[n])
+ n++;
+
+ clone->charsets = g_malloc (sizeof (char *) * (n + 1));
+ for (i = 0; i < n; i++)
+ clone->charsets[i] = g_strdup (options->charsets[i]);
+ clone->charsets[i] = NULL;
+
+ return clone;
+}
+
+
+/**
* g_mime_parser_options_free:
* @options: a #GMimeParserOptions
*
@@ -75,7 +120,7 @@ g_mime_parser_options_free (GMimeParserOptions *options)
{
g_return_if_fail (options != NULL);
- g_str_freev (options->charsets);
+ g_strfreev (options->charsets);
g_slice_free (GMimeParserOptions, options);
}
@@ -229,9 +274,9 @@ g_mime_parser_options_set_rfc2047_compliance_mode (GMimeParserOptions *options,
const char **
g_mime_parser_options_get_fallback_charsets (GMimeParserOptions *options)
{
- g_return_val_if_fail (options != NULL, default_charsets);
+ g_return_val_if_fail (options != NULL, (const char **) default_charsets);
- return options->charsets;
+ return (const char **) options->charsets;
}
@@ -252,10 +297,10 @@ g_mime_parser_options_set_fallback_charsets (GMimeParserOptions *options, const
g_return_if_fail (options != NULL);
- g_str_freev (options->charsets);
+ g_strfreev (options->charsets);
if (charsets == NULL || *charsets == NULL)
- charsets = default_charsets;
+ charsets = (const char **) default_charsets;
while (charsets[n] != NULL)
n++;
diff --git a/gmime/gmime-parser-options.h b/gmime/gmime-parser-options.h
index 6beb8ed..7e614eb 100644
--- a/gmime/gmime-parser-options.h
+++ b/gmime/gmime-parser-options.h
@@ -54,6 +54,8 @@ typedef struct {
char **charsets;
} GMimeParserOptions;
+GMimeParserOptions *g_mime_parser_options_get_default (void);
+
GMimeParserOptions *g_mime_parser_options_new (void);
void g_mime_parser_options_free (GMimeParserOptions *options);
diff --git a/gmime/gmime-parser.c b/gmime/gmime-parser.c
index daaeb4f..08d0591 100644
--- a/gmime/gmime-parser.c
+++ b/gmime/gmime-parser.c
@@ -83,8 +83,6 @@ typedef struct _content_type {
gboolean exists;
} ContentType;
-extern GMimeParserOptions g_mime_parser_options_default;
-
extern void _g_mime_object_append_header (GMimeObject *object, const char *header, const char *value, const
char *raw_value, gint64 offset);
extern void _g_mime_object_set_content_type (GMimeObject *object, GMimeContentType *content_type);
@@ -1663,7 +1661,7 @@ parser_construct_leaf_part (GMimeParser *parser, GMimeParserOptions *options, Co
g_assert (priv->state >= GMIME_PARSER_STATE_HEADERS_END);
- object = g_mime_object_new_type (content_type->type, content_type->subtype);
+ object = g_mime_object_new_type (options, content_type->type, content_type->subtype);
if (!content_type->exists) {
GMimeContentType *mime_type;
@@ -1808,7 +1806,7 @@ parser_construct_multipart (GMimeParser *parser, GMimeParserOptions *options, Co
g_assert (priv->state >= GMIME_PARSER_STATE_HEADERS_END);
- object = g_mime_object_new_type (content_type->type, content_type->subtype);
+ object = g_mime_object_new_type (options, content_type->type, content_type->subtype);
header = priv->headers;
while (header) {
@@ -1898,7 +1896,7 @@ g_mime_parser_construct_part (GMimeParser *parser)
{
g_return_val_if_fail (GMIME_IS_PARSER (parser), NULL);
- return parser_construct_part (parser, &g_mime_parser_options_default);
+ return parser_construct_part (parser, g_mime_parser_options_get_default ());
}
@@ -1998,7 +1996,7 @@ g_mime_parser_construct_message (GMimeParser *parser)
{
g_return_val_if_fail (GMIME_IS_PARSER (parser), NULL);
- return parser_construct_message (parser, &g_mime_parser_options_default);
+ return parser_construct_message (parser, g_mime_parser_options_get_default ());
}
diff --git a/gmime/gmime-utils.c b/gmime/gmime-utils.c
index 229bd9f..be0168d 100644
--- a/gmime/gmime-utils.c
+++ b/gmime/gmime-utils.c
@@ -77,7 +77,6 @@
* and encodings.
**/
-extern gboolean _g_mime_enable_rfc2047_workarounds (void);
extern gboolean _g_mime_use_only_user_charsets (void);
#ifdef G_THREADS_ENABLED
@@ -1414,76 +1413,24 @@ charset_convert (iconv_t cd, const char *inbuf, size_t inleft, char **outp, size
* Returns: a UTF-8 string representation of @text.
**/
char *
-g_mime_utils_decode_8bit (const char *text, size_t len)
+g_mime_utils_decode_8bit (GMimeParserOptions *options, const char *text, size_t len)
{
- const char **charsets, **user_charsets, *locale, *best;
size_t outleft, outlen, min, ninval;
- unsigned int included = 0;
+ const char *best;
iconv_t cd;
char *out;
- int i = 0;
+ int i;
g_return_val_if_fail (text != NULL, NULL);
- locale = g_mime_locale_charset ();
- if (!g_ascii_strcasecmp (locale, "iso-8859-1") ||
- !g_ascii_strcasecmp (locale, "UTF-8")) {
- /* If the user's locale charset is either of these, we
- * don't need to include the locale charset in our list
- * of fallback charsets. */
- included |= USER_CHARSETS_INCLUDE_LOCALE;
- }
-
- if ((user_charsets = g_mime_user_charsets ())) {
- while (user_charsets[i])
- i++;
- }
-
- charsets = g_alloca (sizeof (char *) * (i + 4));
- i = 0;
-
- if (user_charsets) {
- while (user_charsets[i]) {
- /* keep a record of whether or not the user-supplied
- * charsets include UTF-8, Latin1, or the user's locale
- * charset so that we avoid doubling our efforts for
- * these 3 charsets. We could have used a hash table
- * to keep track of unique charsets, but we can
- * (hopefully) assume that user_charsets is a unique
- * list of charsets with no duplicates. */
- if (!g_ascii_strcasecmp (user_charsets[i], "iso-8859-1"))
- included |= USER_CHARSETS_INCLUDE_LATIN1;
-
- if (!g_ascii_strcasecmp (user_charsets[i], "UTF-8"))
- included |= USER_CHARSETS_INCLUDE_UTF8;
-
- if (!g_ascii_strcasecmp (user_charsets[i], locale))
- included |= USER_CHARSETS_INCLUDE_LOCALE;
-
- charsets[i] = user_charsets[i];
- i++;
- }
- }
-
- if (!(included & USER_CHARSETS_INCLUDE_UTF8))
- charsets[i++] = "UTF-8";
-
- if (!(included & USER_CHARSETS_INCLUDE_LOCALE))
- charsets[i++] = locale;
-
- if (!(included & USER_CHARSETS_INCLUDE_LATIN1))
- charsets[i++] = "iso-8859-1";
-
- charsets[i] = NULL;
-
+ best = options->charsets[0];
min = len;
- best = charsets[0];
outleft = (len * 2) + 16;
out = g_malloc (outleft + 1);
- for (i = 0; charsets[i]; i++) {
- if ((cd = g_mime_iconv_open ("UTF-8", charsets[i])) == (iconv_t) -1)
+ for (i = 0; options->charsets[i]; i++) {
+ if ((cd = g_mime_iconv_open ("UTF-8", options->charsets[i])) == (iconv_t) -1)
continue;
outlen = charset_convert (cd, text, len, &out, &outleft, &ninval);
@@ -1494,7 +1441,7 @@ g_mime_utils_decode_8bit (const char *text, size_t len)
return g_realloc (out, outlen + 1);
if (ninval < min) {
- best = charsets[i];
+ best = options->charsets[i];
min = ninval;
}
}
@@ -1767,9 +1714,8 @@ rfc2047_token_new_encoded_word (const char *word, size_t len)
}
static rfc2047_token *
-tokenize_rfc2047_phrase (const char *in, size_t *len)
+tokenize_rfc2047_phrase (GMimeParserOptions *options, const char *in, size_t *len)
{
- gboolean enable_rfc2047_workarounds = _g_mime_enable_rfc2047_workarounds ();
rfc2047_token list, *lwsp, *token, *tail;
register const char *inptr = in;
gboolean encoded = FALSE;
@@ -1794,7 +1740,7 @@ tokenize_rfc2047_phrase (const char *in, size_t *len)
word = inptr;
ascii = TRUE;
if (is_atom (*inptr)) {
- if (G_UNLIKELY (enable_rfc2047_workarounds)) {
+ if (G_LIKELY (options->rfc2047 == GMIME_RFC_COMPLIANCE_LOOSE)) {
/* Make an extra effort to detect and
* separate encoded-word tokens that
* have been merged with other
@@ -1901,9 +1847,8 @@ tokenize_rfc2047_phrase (const char *in, size_t *len)
}
static rfc2047_token *
-tokenize_rfc2047_text (const char *in, size_t *len)
+tokenize_rfc2047_text (GMimeParserOptions *options, const char *in, size_t *len)
{
- gboolean enable_rfc2047_workarounds = _g_mime_enable_rfc2047_workarounds ();
rfc2047_token list, *lwsp, *token, *tail;
register const char *inptr = in;
gboolean encoded = FALSE;
@@ -1929,7 +1874,7 @@ tokenize_rfc2047_text (const char *in, size_t *len)
word = inptr;
ascii = TRUE;
- if (G_UNLIKELY (enable_rfc2047_workarounds)) {
+ if (G_LIKELY (options->rfc2047 == GMIME_RFC_COMPLIANCE_LOOSE)) {
if (!strncmp (inptr, "=?", 2)) {
inptr += 2;
@@ -2035,7 +1980,7 @@ rfc2047_token_decode (rfc2047_token *token, unsigned char *outbuf, int *state, g
}
static char *
-rfc2047_decode_tokens (rfc2047_token *tokens, size_t buflen)
+rfc2047_decode_tokens (GMimeParserOptions *options, rfc2047_token *tokens, size_t buflen)
{
rfc2047_token *token, *next;
size_t outlen, ninval, len;
@@ -2109,7 +2054,7 @@ rfc2047_decode_tokens (rfc2047_token *tokens, size_t buflen)
"be corrupt: %s", charset[0] ? charset : "unspecified charset",
g_strerror (errno)));
- str = g_mime_utils_decode_8bit ((char *) outptr, outlen);
+ str = g_mime_utils_decode_8bit (options, (char *) outptr, outlen);
g_string_append (decoded, str);
g_free (str);
} else {
@@ -2131,7 +2076,7 @@ rfc2047_decode_tokens (rfc2047_token *tokens, size_t buflen)
}
} else if (token->is_8bit) {
/* *sigh* I hate broken mailers... */
- str = g_mime_utils_decode_8bit (token->text, token->length);
+ str = g_mime_utils_decode_8bit (options, token->text, token->length);
g_string_append (decoded, str);
g_free (str);
} else {
@@ -2150,6 +2095,7 @@ rfc2047_decode_tokens (rfc2047_token *tokens, size_t buflen)
/**
* g_mime_utils_header_decode_text:
* @text: header text to decode
+ * @options: a #GMimeParserOptions
*
* Decodes an rfc2047 encoded 'text' header.
*
@@ -2161,7 +2107,7 @@ rfc2047_decode_tokens (rfc2047_token *tokens, size_t buflen)
* header.
**/
char *
-g_mime_utils_header_decode_text (const char *text)
+g_mime_utils_header_decode_text (GMimeParserOptions *options, const char *text)
{
rfc2047_token *tokens;
char *decoded;
@@ -2170,8 +2116,8 @@ g_mime_utils_header_decode_text (const char *text)
if (text == NULL)
return g_strdup ("");
- tokens = tokenize_rfc2047_text (text, &len);
- decoded = rfc2047_decode_tokens (tokens, len);
+ tokens = tokenize_rfc2047_text (options, text, &len);
+ decoded = rfc2047_decode_tokens (options, tokens, len);
rfc2047_token_list_free (tokens);
return decoded;
@@ -2181,6 +2127,7 @@ g_mime_utils_header_decode_text (const char *text)
/**
* g_mime_utils_header_decode_phrase:
* @phrase: header to decode
+ * @options: a #GMimeParserOptions
*
* Decodes an rfc2047 encoded 'phrase' header.
*
@@ -2192,7 +2139,7 @@ g_mime_utils_header_decode_text (const char *text)
* header.
**/
char *
-g_mime_utils_header_decode_phrase (const char *phrase)
+g_mime_utils_header_decode_phrase (GMimeParserOptions *options, const char *phrase)
{
rfc2047_token *tokens;
char *decoded;
@@ -2201,8 +2148,8 @@ g_mime_utils_header_decode_phrase (const char *phrase)
if (phrase == NULL)
return g_strdup ("");
- tokens = tokenize_rfc2047_phrase (phrase, &len);
- decoded = rfc2047_decode_tokens (tokens, len);
+ tokens = tokenize_rfc2047_phrase (options, phrase, &len);
+ decoded = rfc2047_decode_tokens (options, tokens, len);
rfc2047_token_list_free (tokens);
return decoded;
@@ -2825,13 +2772,14 @@ header_fold_tokens (const char *field, const char *value, size_t vlen, rfc2047_t
/**
* g_mime_utils_structured_header_fold:
* @header: header field and value string
+ * @options: a #GMimeParserOptions
*
* Folds a structured header according to the rules in rfc822.
*
* Returns: an allocated string containing the folded header.
**/
char *
-g_mime_utils_structured_header_fold (const char *header)
+g_mime_utils_structured_header_fold (GMimeParserOptions *options, const char *header)
{
rfc2047_token *tokens;
const char *value;
@@ -2855,7 +2803,7 @@ g_mime_utils_structured_header_fold (const char *header)
while (*value && is_lwsp (*value))
value++;
- tokens = tokenize_rfc2047_phrase (value, &len);
+ tokens = tokenize_rfc2047_phrase (options, value, &len);
folded = header_fold_tokens (field, value, len, tokens, TRUE);
g_free (field);
@@ -2865,6 +2813,7 @@ g_mime_utils_structured_header_fold (const char *header)
/**
* _g_mime_utils_structured_header_fold:
+ * @options: a #GMimeParserOptions
* @field: header field
* @value: header value
*
@@ -2873,7 +2822,7 @@ g_mime_utils_structured_header_fold (const char *header)
* Returns: an allocated string containing the folded header.
**/
char *
-_g_mime_utils_structured_header_fold (const char *field, const char *value)
+_g_mime_utils_structured_header_fold (GMimeParserOptions *options, const char *field, const char *value)
{
rfc2047_token *tokens;
size_t len;
@@ -2884,7 +2833,7 @@ _g_mime_utils_structured_header_fold (const char *field, const char *value)
if (value == NULL)
return g_strdup_printf ("%s: \n", field);
- tokens = tokenize_rfc2047_phrase (value, &len);
+ tokens = tokenize_rfc2047_phrase (options, value, &len);
return header_fold_tokens (field, value, len, tokens, TRUE);
}
@@ -2892,6 +2841,7 @@ _g_mime_utils_structured_header_fold (const char *field, const char *value)
/**
* g_mime_utils_unstructured_header_fold:
+ * @options: a #GMimeParserOptions
* @header: header field and value string
*
* Folds an unstructured header according to the rules in rfc822.
@@ -2899,7 +2849,7 @@ _g_mime_utils_structured_header_fold (const char *field, const char *value)
* Returns: an allocated string containing the folded header.
**/
char *
-g_mime_utils_unstructured_header_fold (const char *header)
+g_mime_utils_unstructured_header_fold (GMimeParserOptions *options, const char *header)
{
rfc2047_token *tokens;
const char *value;
@@ -2923,7 +2873,7 @@ g_mime_utils_unstructured_header_fold (const char *header)
while (*value && is_lwsp (*value))
value++;
- tokens = tokenize_rfc2047_text (value, &len);
+ tokens = tokenize_rfc2047_text (options, value, &len);
folded = header_fold_tokens (field, value, len, tokens, FALSE);
g_free (field);
@@ -2933,6 +2883,7 @@ g_mime_utils_unstructured_header_fold (const char *header)
/**
* _g_mime_utils_unstructured_header_fold:
+ * @options: a #GMimeParserOptions
* @field: header field
* @value: header value
*
@@ -2941,7 +2892,7 @@ g_mime_utils_unstructured_header_fold (const char *header)
* Returns: an allocated string containing the folded header.
**/
char *
-_g_mime_utils_unstructured_header_fold (const char *field, const char *value)
+_g_mime_utils_unstructured_header_fold (GMimeParserOptions *options, const char *field, const char *value)
{
rfc2047_token *tokens;
size_t len;
@@ -2952,32 +2903,15 @@ _g_mime_utils_unstructured_header_fold (const char *field, const char *value)
if (value == NULL)
return g_strdup_printf ("%s: \n", field);
- tokens = tokenize_rfc2047_text (value, &len);
+ tokens = tokenize_rfc2047_text (options, value, &len);
return header_fold_tokens (field, value, len, tokens, FALSE);
}
/**
- * g_mime_utils_header_fold:
- * @header: header field and value string
- *
- * Folds a structured header according to the rules in rfc822.
- *
- * Returns: an allocated string containing the folded header.
- *
- * WARNING: This function is obsolete. Use
- * g_mime_utils_structured_header_fold() instead.
- **/
-char *
-g_mime_utils_header_fold (const char *header)
-{
- return g_mime_utils_structured_header_fold (header);
-}
-
-
-/**
* g_mime_utils_header_printf:
+ * @options: a #GMimeParserOptions
* @format: string format
* @...: arguments
*
@@ -2988,7 +2922,7 @@ g_mime_utils_header_fold (const char *header)
* by @format and the following arguments.
**/
char *
-g_mime_utils_header_printf (const char *format, ...)
+g_mime_utils_header_printf (GMimeParserOptions *options, const char *format, ...)
{
char *buf, *ret;
va_list ap;
@@ -2997,7 +2931,7 @@ g_mime_utils_header_printf (const char *format, ...)
buf = g_strdup_vprintf (format, ap);
va_end (ap);
- ret = g_mime_utils_unstructured_header_fold (buf);
+ ret = g_mime_utils_unstructured_header_fold (options, buf);
g_free (buf);
return ret;
diff --git a/gmime/gmime-utils.h b/gmime/gmime-utils.h
index 89b862c..071e380 100644
--- a/gmime/gmime-utils.h
+++ b/gmime/gmime-utils.h
@@ -26,6 +26,7 @@
#include <time.h>
#include <stdarg.h>
+#include <gmime/gmime-parser-options.h>
#include <gmime/gmime-encodings.h>
G_BEGIN_DECLS
@@ -62,10 +63,9 @@ void g_mime_references_free (GMimeReferences *refs);
const GMimeReferences *g_mime_references_get_next (const GMimeReferences *ref);
const char *g_mime_references_get_message_id (const GMimeReferences *ref);
-char *g_mime_utils_structured_header_fold (const char *header);
-char *g_mime_utils_unstructured_header_fold (const char *header);
-char *g_mime_utils_header_fold (const char *header);
-char *g_mime_utils_header_printf (const char *format, ...) G_GNUC_PRINTF (1, 2);
+char *g_mime_utils_structured_header_fold (GMimeParserOptions *options, const char *header);
+char *g_mime_utils_unstructured_header_fold (GMimeParserOptions *options, const char *header);
+char *g_mime_utils_header_printf (GMimeParserOptions *options, const char *format, ...) G_GNUC_PRINTF (2,
3);
char *g_mime_utils_quote_string (const char *str);
void g_mime_utils_unquote_string (char *str);
@@ -75,13 +75,13 @@ gboolean g_mime_utils_text_is_8bit (const unsigned char *text, size_t len);
GMimeContentEncoding g_mime_utils_best_encoding (const unsigned char *text, size_t len);
/* utility function to convert text in an unknown 8bit/multibyte charset to UTF-8 */
-char *g_mime_utils_decode_8bit (const char *text, size_t len);
+char *g_mime_utils_decode_8bit (GMimeParserOptions *options, const char *text, size_t len);
/* utilities to (de/en)code headers */
-char *g_mime_utils_header_decode_text (const char *text);
+char *g_mime_utils_header_decode_text (GMimeParserOptions *options, const char *text);
char *g_mime_utils_header_encode_text (const char *text);
-char *g_mime_utils_header_decode_phrase (const char *phrase);
+char *g_mime_utils_header_decode_phrase (GMimeParserOptions *options, const char *phrase);
char *g_mime_utils_header_encode_phrase (const char *phrase);
G_END_DECLS
diff --git a/gmime/gmime.c b/gmime/gmime.c
index 567e550..29cdcc8 100644
--- a/gmime/gmime.c
+++ b/gmime/gmime.c
@@ -47,7 +47,6 @@
* Initialization, shutdown, and version-check functions.
**/
-extern gboolean _g_mime_enable_rfc2047_workarounds (void);
extern gboolean _g_mime_use_only_user_charsets (void);
extern void g_mime_iconv_utils_shutdown (void);
@@ -251,12 +250,6 @@ g_mime_shutdown (void)
gboolean
-_g_mime_enable_rfc2047_workarounds (void)
-{
- return (enable & GMIME_ENABLE_RFC2047_WORKAROUNDS);
-}
-
-gboolean
_g_mime_use_only_user_charsets (void)
{
return (enable & GMIME_ENABLE_USE_ONLY_USER_CHARSETS);
diff --git a/gmime/gmime.h b/gmime/gmime.h
index 8b26e30..8915f0a 100644
--- a/gmime/gmime.h
+++ b/gmime/gmime.h
@@ -115,15 +115,6 @@ extern const guint gmime_binary_age;
gboolean g_mime_check_version (guint major, guint minor, guint micro);
-
-/**
- * GMIME_ENABLE_RFC2047_WORKAROUNDS:
- *
- * Initialization flag to enable workarounds for badly formed rfc2047
- * encoded-words.
- **/
-#define GMIME_ENABLE_RFC2047_WORKAROUNDS (1 << 0)
-
/**
* GMIME_ENABLE_USE_ONLY_USER_CHARSETS:
*
@@ -133,7 +124,7 @@ gboolean g_mime_check_version (guint major, guint minor, guint micro);
*
* Since: 2.6.16
**/
-#define GMIME_ENABLE_USE_ONLY_USER_CHARSETS (1 << 1)
+#define GMIME_ENABLE_USE_ONLY_USER_CHARSETS (1 << 0)
void g_mime_init (guint32 flags);
void g_mime_shutdown (void);
diff --git a/gmime/internet-address.c b/gmime/internet-address.c
index c3cd43a..5142eff 100644
--- a/gmime/internet-address.c
+++ b/gmime/internet-address.c
@@ -1234,14 +1234,14 @@ internet_address_list_writer (InternetAddressList *list, GString *str)
}
static void
-_internet_address_decode_name (InternetAddress *ia, GString *name)
+_internet_address_decode_name (GMimeParserOptions *options, InternetAddress *ia, GString *name)
{
char *value, *buf = NULL;
char *phrase;
if (!g_utf8_validate (name->str, name->len, NULL)) {
/* A (broken) mailer has sent us raw 8bit/multibyte text data... */
- buf = g_mime_utils_decode_8bit (name->str, name->len);
+ buf = g_mime_utils_decode_8bit (options, name->str, name->len);
phrase = buf;
} else {
phrase = name->str;
@@ -1249,13 +1249,13 @@ _internet_address_decode_name (InternetAddress *ia, GString *name)
/* decode the phrase */
g_mime_utils_unquote_string (phrase);
- value = g_mime_utils_header_decode_phrase (phrase);
+ value = g_mime_utils_header_decode_phrase (options, phrase);
g_free (ia->name);
ia->name = value;
g_free (buf);
}
-static InternetAddress *decode_address (const char **in);
+static InternetAddress *decode_address (GMimeParserOptions *options, const char **in);
static void
skip_lwsp (const char **in)
@@ -1348,7 +1348,7 @@ decode_addrspec (const char **in)
}
static InternetAddress *
-decode_group (const char **in)
+decode_group (GMimeParserOptions *options, const char **in)
{
InternetAddressGroup *group;
InternetAddress *addr;
@@ -1363,14 +1363,14 @@ decode_group (const char **in)
while (*inptr && *inptr != ';') {
InternetAddress *member;
- if ((member = decode_address (&inptr)))
+ if ((member = decode_address (options, &inptr)))
_internet_address_group_add_member (group, member);
decode_lwsp (&inptr);
while (*inptr == ',') {
inptr++;
decode_lwsp (&inptr);
- if ((member = decode_address (&inptr)))
+ if ((member = decode_address (options, &inptr)))
_internet_address_group_add_member (group, member);
decode_lwsp (&inptr);
@@ -1441,7 +1441,7 @@ decode_route (const char **in)
}
static InternetAddress *
-decode_address (const char **in)
+decode_address (GMimeParserOptions *options, const char **in)
{
const char *inptr, *start, *word, *comment = NULL;
InternetAddress *addr = NULL;
@@ -1485,7 +1485,7 @@ decode_address (const char **in)
if (*inptr == ':') {
/* rfc2822 group */
inptr++;
- addr = decode_group (&inptr);
+ addr = decode_group (options, &inptr);
decode_lwsp (&inptr);
if (*inptr != ';')
w(g_warning ("Invalid group spec, missing closing ';': %.*s",
@@ -1604,7 +1604,7 @@ decode_address (const char **in)
}
if (addr && name->len > 0)
- _internet_address_decode_name (addr, name);
+ _internet_address_decode_name (options, addr, name);
g_string_free (name, TRUE);
@@ -1615,7 +1615,8 @@ decode_address (const char **in)
/**
- * internet_address_list_parse_string:
+ * internet_address_list_parse:
+ * @options: a #GMimeParserOptions
* @str: a string containing internet addresses
*
* Construct a list of internet addresses from the given string.
@@ -1624,7 +1625,7 @@ decode_address (const char **in)
* input string does not contain any addresses.
**/
InternetAddressList *
-internet_address_list_parse_string (const char *str)
+internet_address_list_parse (GMimeParserOptions *options, const char *str)
{
InternetAddressList *addrlist;
const char *inptr = str;
@@ -1636,7 +1637,7 @@ internet_address_list_parse_string (const char *str)
while (inptr && *inptr) {
start = inptr;
- if ((addr = decode_address (&inptr))) {
+ if ((addr = decode_address (options, &inptr))) {
_internet_address_list_add (addrlist, addr);
} else {
w(g_warning ("Invalid or incomplete address: %.*s",
diff --git a/gmime/internet-address.h b/gmime/internet-address.h
index 676aa93..ef342ab 100644
--- a/gmime/internet-address.h
+++ b/gmime/internet-address.h
@@ -25,6 +25,8 @@
#include <glib.h>
#include <glib-object.h>
+#include <gmime/gmime-parser-options.h>
+
G_BEGIN_DECLS
#define INTERNET_ADDRESS_TYPE (internet_address_get_type ())
@@ -197,7 +199,7 @@ void internet_address_list_set_address (InternetAddressList *list, int index, In
char *internet_address_list_to_string (InternetAddressList *list, gboolean encode);
-InternetAddressList *internet_address_list_parse_string (const char *str);
+InternetAddressList *internet_address_list_parse (GMimeParserOptions *options, const char *str);
void internet_address_list_writer (InternetAddressList *list, GString *str);
diff --git a/tests/test-headers.c b/tests/test-headers.c
index 513f64e..0608457 100644
--- a/tests/test-headers.c
+++ b/tests/test-headers.c
@@ -57,7 +57,7 @@ header_list_new (void)
GMimeHeaderList *list;
guint i;
- list = g_mime_header_list_new ();
+ list = g_mime_header_list_new (g_mime_parser_options_get_default ());
for (i = 0; i < G_N_ELEMENTS (initial); i++)
g_mime_header_list_append (list, initial[i].name, initial[i].value);
diff --git a/tests/test-mime.c b/tests/test-mime.c
index 98ecc21..8c0110c 100644
--- a/tests/test-mime.c
+++ b/tests/test-mime.c
@@ -227,7 +227,7 @@ static struct {
};
static void
-test_addrspec (gboolean test_broken)
+test_addrspec (GMimeParserOptions *options, gboolean test_broken)
{
InternetAddressList *addrlist;
char *str;
@@ -239,7 +239,7 @@ test_addrspec (gboolean test_broken)
testsuite_check ("addrspec[%u]", i);
try {
- if (!(addrlist = internet_address_list_parse_string (addrspec[i].input)))
+ if (!(addrlist = internet_address_list_parse (options, addrspec[i].input)))
throw (exception_new ("could not parse addr-spec"));
str = internet_address_list_to_string (addrlist, FALSE);
@@ -268,7 +268,7 @@ test_addrspec (gboolean test_broken)
testsuite_check ("broken_addrspec[%u]", i);
try {
- if (!(addrlist = internet_address_list_parse_string
(broken_addrspec[i].input)))
+ if (!(addrlist = internet_address_list_parse (options,
broken_addrspec[i].input)))
throw (exception_new ("could not parse addr-spec"));
str = internet_address_list_to_string (addrlist, FALSE);
@@ -427,7 +427,7 @@ static struct {
#endif
static void
-test_rfc2047 (gboolean test_broken)
+test_rfc2047 (GMimeParserOptions *options, gboolean test_broken)
{
char *enc, *dec;
guint i;
@@ -436,7 +436,7 @@ test_rfc2047 (gboolean test_broken)
dec = enc = NULL;
testsuite_check ("rfc2047_text[%u]", i);
try {
- dec = g_mime_utils_header_decode_text (rfc2047_text[i].input);
+ dec = g_mime_utils_header_decode_text (options, rfc2047_text[i].input);
if (strcmp (rfc2047_text[i].decoded, dec) != 0)
throw (exception_new ("decoded text does not match: %s", dec));
@@ -444,7 +444,7 @@ test_rfc2047 (gboolean test_broken)
if (strcmp (rfc2047_text[i].encoded, enc) != 0)
throw (exception_new ("encoded text does not match: %s", enc));
- //dec2 = g_mime_utils_header_decode_text (enc);
+ //dec2 = g_mime_utils_header_decode_text (options, enc);
//if (strcmp (rfc2047_text[i].decoded, dec2) != 0)
// throw (exception_new ("decoded2 text does not match: %s", dec));
@@ -461,7 +461,7 @@ test_rfc2047 (gboolean test_broken)
dec = enc = NULL;
testsuite_check ("broken_rfc2047_text[%u]", i);
try {
- dec = g_mime_utils_header_decode_text (broken_rfc2047_text[i].input);
+ dec = g_mime_utils_header_decode_text (options, broken_rfc2047_text[i].input);
if (strcmp (broken_rfc2047_text[i].decoded, dec) != 0)
throw (exception_new ("decoded text does not match: %s", dec));
@@ -511,7 +511,7 @@ static struct {
};
static void
-test_header_folding (void)
+test_header_folding (GMimeParserOptions *options)
{
char *folded;
guint i;
@@ -520,7 +520,7 @@ test_header_folding (void)
folded = NULL;
testsuite_check ("header_folding[%u]", i);
try {
- folded = g_mime_utils_unstructured_header_fold (header_folding[i].input);
+ folded = g_mime_utils_unstructured_header_fold (options, header_folding[i].input);
if (strcmp (header_folding[i].folded, folded) != 0)
throw (exception_new ("folded text does not match: -->%s<-- vs -->%s<--",
header_folding[i].folded, folded));
@@ -545,7 +545,7 @@ static struct {
};
static void
-test_rfc2184 (void)
+test_rfc2184 (GMimeParserOptions *options)
{
GMimeParam param, *params;
GString *str;
@@ -569,7 +569,7 @@ test_rfc2184 (void)
if (strcmp (rfc2184[i].encoded, str->str) != 0)
throw (exception_new ("encoded param does not match: %s", str->str));
- if (!(params = g_mime_param_new_from_string (str->str + n + 2)))
+ if (!(params = g_mime_param_parse (options, str->str + n + 2)))
throw (exception_new ("could not parse encoded param list"));
if (params->next != NULL)
@@ -642,38 +642,50 @@ test_qstring (void)
int main (int argc, char **argv)
{
+ GMimeParserOptions *options = g_mime_parser_options_new ();
+
g_mime_init (0);
testsuite_init (argc, argv);
- testsuite_start ("addr-spec parser");
- test_addrspec (FALSE);
+ testsuite_start ("addr-spec parser (strict)");
+ options->rfc2047 = GMIME_RFC_COMPLIANCE_STRICT;
+ test_addrspec (options, FALSE);
+ testsuite_end ();
+
+ testsuite_start ("addr-spec parser (loose)");
+ options->rfc2047 = GMIME_RFC_COMPLIANCE_LOOSE;
+ test_addrspec (options, TRUE);
testsuite_end ();
testsuite_start ("date parser");
test_date_parser ();
testsuite_end ();
- testsuite_start ("rfc2047 encoding/decoding");
- test_rfc2047 (FALSE);
+ testsuite_start ("rfc2047 encoding/decoding (strict)");
+ options->rfc2047 = GMIME_RFC_COMPLIANCE_STRICT;
+ test_rfc2047 (options, FALSE);
+ testsuite_end ();
+
+ testsuite_start ("rfc2047 encoding/decoding (loose)");
+ options->rfc2047 = GMIME_RFC_COMPLIANCE_LOOSE;
+ test_rfc2047 (options, TRUE);
testsuite_end ();
testsuite_start ("rfc2184 encoding/decoding");
- test_rfc2184 ();
+ test_rfc2184 (options);
testsuite_end ();
testsuite_start ("quoted-strings");
test_qstring ();
testsuite_end ();
- g_mime_shutdown ();
-
- g_mime_init (GMIME_ENABLE_RFC2047_WORKAROUNDS);
- testsuite_start ("broken rfc2047 encoding/decoding");
- test_header_folding ();
- test_addrspec (TRUE);
- test_rfc2047 (TRUE);
+ testsuite_start ("header folding");
+ test_header_folding (options);
testsuite_end ();
+
+ g_mime_parser_options_free (options);
+
g_mime_shutdown ();
return testsuite_exit ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]