Remove internal MIME handling code.

Sun, 31 Mar 2019 18:14:48 -0400

author
Elliott Sales de Andrade <qulogic@pidgin.im>
date
Sun, 31 Mar 2019 18:14:48 -0400
changeset 39527
32b6744e4dcf
parent 39526
4f678f514b69
child 39528
0fa64a08fd5b

Remove internal MIME handling code.

ChangeLog.API file | annotate | diff | comparison | revisions
libpurple/meson.build file | annotate | diff | comparison | revisions
libpurple/mime.c file | annotate | diff | comparison | revisions
libpurple/mime.h file | annotate | diff | comparison | revisions
libpurple/tests/test_util.c file | annotate | diff | comparison | revisions
libpurple/util.c file | annotate | diff | comparison | revisions
libpurple/util.h file | annotate | diff | comparison | revisions
--- a/ChangeLog.API	Sun Mar 31 17:45:25 2019 -0400
+++ b/ChangeLog.API	Sun Mar 31 18:14:48 2019 -0400
@@ -432,6 +432,19 @@
 		* PurpleEventLoopUiOps. Manually drive the GLib event loop
 		  yourself. See GLib Main Event Loop docs.
 		* purple_get_tzoff_str(). Use g_date_time_format, instead.
+		* PurpleMimeDocument, PurpleMimePart,
+		  purple_mime_document_new, purple_mime_document_free,
+		  purple_mime_document_parse, purple_mime_document_parsen,
+		  purple_mime_document_write, purple_mime_document_get_fields,
+		  purple_mime_document_get_field,
+		  purple_mime_document_set_field,
+		  purple_mime_document_get_parts, purple_mime_part_new,
+		  purple_mime_part_get_fields, purple_mime_part_get_field,
+		  purple_mime_part_get_field_decoded,
+		  purple_mime_part_set_field, purple_mime_part_get_data,
+		  purple_mime_part_get_data_decoded,
+		  purple_mime_part_get_length, purple_mime_part_set_data, and
+		  purple_mime_decode_field. Use the GMime library, instead.
 		* purple_network_convert_idn_to_ascii. Use g_hostname_to_ascii,
 		  instead.
 		* purple_network_listen_family. Use purple_network_listen, instead.
@@ -480,6 +493,7 @@
 		* purple_print_utf8_to_console
 		* PurplePluginProtocolInfo
 		* purple_proxy_connect_socks5
+		* purple_quotedp_decode. See the GMime library if needed.
 		* purple_request_field_list_add
 		* purple_srv_cancel
 		* purple_srv_resolve_account
--- a/libpurple/meson.build	Sun Mar 31 17:45:25 2019 -0400
+++ b/libpurple/meson.build	Sun Mar 31 18:14:48 2019 -0400
@@ -36,7 +36,6 @@
 	'mediamanager.c',
 	'memorypool.c',
 	'message.c',
-	'mime.c',
 	'nat-pmp.c',
 	'network.c',
 	'notify.c',
@@ -115,7 +114,6 @@
 	'mediamanager.h',
 	'memorypool.h',
 	'message.h',
-	'mime.h',
 	'nat-pmp.h',
 	'network.h',
 	'notify.h',
--- a/libpurple/mime.c	Sun Mar 31 17:45:25 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,586 +0,0 @@
-/*
- * Purple
- *
- * Purple is the legal property of its developers, whose names are too
- * numerous to list here. Please refer to the COPYRIGHT file distributed
- * with this source distribution
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program 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
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301,
- * USA.
- */
-
-#include "internal.h"
-
-/* this should become "util.h" if we ever get this into purple proper */
-#include "debug.h"
-#include "mime.h"
-#include "util.h"
-
-/*
- * Utility structure used in both MIME document and parts, which maps
- * field names to their values, and keeps an easily accessible list of
- * keys.
- */
-struct mime_fields {
-	GHashTable *map;
-	GList *keys;
-};
-
-struct _PurpleMimeDocument {
-	struct mime_fields fields;
-	GList *parts;
-};
-
-struct _PurpleMimePart {
-	struct mime_fields fields;
-	struct _PurpleMimeDocument *doc;
-	GString *data;
-};
-
-static void
-fields_set(struct mime_fields *mf, const char *key, const char *val)
-{
-	char *k, *v;
-
-	g_return_if_fail(mf != NULL);
-	g_return_if_fail(mf->map != NULL);
-
-	k = g_ascii_strdown(key, -1);
-	v = g_strdup(val);
-
-	/* append to the keys list only if it's not already there */
-	if(! g_hash_table_lookup(mf->map, k)) {
-		mf->keys = g_list_append(mf->keys, k);
-	}
-
-	/* important to use insert. If the key is already in the table, then
-		 it's already in the keys list. Insert will free the new instance
-		 of the key rather than the old instance. */
-	g_hash_table_insert(mf->map, k, v);
-}
-
-
-static const char *
-fields_get(struct mime_fields *mf, const char *key)
-{
-	char *kdown;
-	const char *ret;
-
-	g_return_val_if_fail(mf != NULL, NULL);
-	g_return_val_if_fail(mf->map != NULL, NULL);
-
-	kdown = g_ascii_strdown(key, -1);
-	ret = g_hash_table_lookup(mf->map, kdown);
-	g_free(kdown);
-
-	return ret;
-}
-
-
-static void
-fields_init(struct mime_fields *mf)
-{
-	g_return_if_fail(mf != NULL);
-
-	mf->map = g_hash_table_new_full(g_str_hash, g_str_equal,
-					g_free, g_free);
-}
-
-
-static void
-fields_loadline(struct mime_fields *mf, const char *line, gsize len)
-{
-	/* split the line into key: value */
-	char *key, *newkey, *val;
-	char **tokens;
-
-	/* feh, need it to be NUL terminated */
-	key = g_strndup(line, len);
-
-	/* split */
-	val = strchr(key, ':');
-	if(! val) {
-		g_free(key);
-		return;
-	}
-	*val++ = '\0';
-
-	/* normalize whitespace (sorta) and trim on key and value */
-	tokens = g_strsplit(key, "\t\r\n", 0);
-	newkey = g_strjoinv("", tokens);
-	g_strstrip(newkey);
-	g_strfreev(tokens);
-
-	tokens = g_strsplit(val, "\t\r\n", 0);
-	val = g_strjoinv("", tokens);
-	g_strstrip(val);
-	g_strfreev(tokens);
-
-	fields_set(mf, newkey, val);
-
-	g_free(newkey);
-	g_free(key);
-	g_free(val);
-}
-
-
-static void
-fields_load(struct mime_fields *mf, char **buf, gsize *len)
-{
-	char *tail;
-
-	while ((tail = g_strstr_len(*buf, *len, "\r\n")))
-	{
-		char *line;
-		gsize ln;
-
-		/* determine the current line */
-		line = *buf;
-		ln = tail - line;
-
-		/* advance our search space past the CRLF */
-		*buf = tail + 2;
-		*len -= (ln + 2);
-
-		/* empty line, end of headers */
-		if(! ln) return;
-
-		/* look out for line continuations */
-		if(line[ln-1] == ';') {
-			tail = g_strstr_len(*buf, *len, "\r\n");
-			if(tail) {
-				gsize cln;
-
-				cln = tail - *buf;
-				ln = tail - line;
-
-				/* advance our search space past the CRLF (again) */
-				*buf = tail + 2;
-				*len -= (cln + 2);
-			}
-		}
-
-		/* process our super-cool line */
-		fields_loadline(mf, line, ln);
-	}
-}
-
-
-static void
-field_write(const char *key, const char *val, GString *str)
-{
-	g_string_append_printf(str, "%s: %s\r\n", key, val);
-}
-
-
-static void
-fields_write(struct mime_fields *mf, GString *str)
-{
-	g_return_if_fail(mf != NULL);
-
-	g_hash_table_foreach(mf->map, (GHFunc) field_write, str);
-	g_string_append(str, "\r\n");
-}
-
-
-static void
-fields_destroy(struct mime_fields *mf)
-{
-	g_return_if_fail(mf != NULL);
-
-	g_hash_table_destroy(mf->map);
-	g_list_free(mf->keys);
-
-	mf->map = NULL;
-	mf->keys = NULL;
-}
-
-
-static PurpleMimePart *
-part_new(PurpleMimeDocument *doc)
-{
-	PurpleMimePart *part;
-
-	part = g_new0(PurpleMimePart, 1);
-	fields_init(&part->fields);
-	part->doc = doc;
-	part->data = g_string_new(NULL);
-
-	doc->parts = g_list_prepend(doc->parts, part);
-
-	return part;
-}
-
-
-static void
-part_load(PurpleMimePart *part, const char *buf, gsize len)
-{
-
-	char *b = (char *) buf;
-	gsize n = len;
-
-	fields_load(&part->fields, &b, &n);
-
-	/* the remainder will have a blank line, if there's anything at all,
-		 so check if there's anything then trim off the trailing four
-		 bytes, \r\n\r\n */
-	if(n > 4) n -= 4;
-	g_string_append_len(part->data, b, n);
-}
-
-
-static void
-part_write(PurpleMimePart *part, GString *str)
-{
-	fields_write(&part->fields, str);
-	g_string_append_printf(str, "%s\r\n\r\n", part->data->str);
-}
-
-
-static void
-part_free(PurpleMimePart *part)
-{
-
-	fields_destroy(&part->fields);
-
-	g_string_free(part->data, TRUE);
-	part->data = NULL;
-
-	g_free(part);
-}
-
-
-PurpleMimePart *
-purple_mime_part_new(PurpleMimeDocument *doc)
-{
-	g_return_val_if_fail(doc != NULL, NULL);
-	return part_new(doc);
-}
-
-
-GList *
-purple_mime_part_get_fields(PurpleMimePart *part)
-{
-	g_return_val_if_fail(part != NULL, NULL);
-	return part->fields.keys;
-}
-
-
-const char *
-purple_mime_part_get_field(PurpleMimePart *part, const char *field)
-{
-	g_return_val_if_fail(part != NULL, NULL);
-	return fields_get(&part->fields, field);
-}
-
-
-char *
-purple_mime_part_get_field_decoded(PurpleMimePart *part, const char *field)
-{
-	const char *f;
-
-	g_return_val_if_fail(part != NULL, NULL);
-
-	f = fields_get(&part->fields, field);
-	return purple_mime_decode_field(f);
-}
-
-
-void
-purple_mime_part_set_field(PurpleMimePart *part, const char *field, const char *value)
-{
-	g_return_if_fail(part != NULL);
-	fields_set(&part->fields, field, value);
-}
-
-
-const char *
-purple_mime_part_get_data(PurpleMimePart *part)
-{
-	g_return_val_if_fail(part != NULL, NULL);
-	g_return_val_if_fail(part->data != NULL, NULL);
-
-	return part->data->str;
-}
-
-
-void
-purple_mime_part_get_data_decoded(PurpleMimePart *part, guchar **data, gsize *len)
-{
-	const char *enc;
-
-	g_return_if_fail(part != NULL);
-	g_return_if_fail(data != NULL);
-	g_return_if_fail(len != NULL);
-
-	g_return_if_fail(part->data != NULL);
-
-	enc = purple_mime_part_get_field(part, "content-transfer-encoding");
-
-	if(! enc) {
-		*data = (guchar *)g_strdup(part->data->str);
-		*len = part->data->len;
-
-	} else if(! g_ascii_strcasecmp(enc, "7bit")) {
-		*data = (guchar *)g_strdup(part->data->str);
-		*len = part->data->len;
-
-	} else if(! g_ascii_strcasecmp(enc, "8bit")) {
-		*data = (guchar *)g_strdup(part->data->str);
-		*len = part->data->len;
-
-	} else if(! g_ascii_strcasecmp(enc, "base16")) {
-		*data = purple_base16_decode(part->data->str, len);
-
-	} else if(! g_ascii_strcasecmp(enc, "base64")) {
-		*data = g_base64_decode(part->data->str, len);
-
-	} else if(! g_ascii_strcasecmp(enc, "quoted-printable")) {
-		*data = purple_quotedp_decode(part->data->str, len);
-
-	} else {
-		purple_debug_warning("mime", "purple_mime_part_get_data_decoded:"
-					 " unknown encoding '%s'\n", enc);
-		*data = NULL;
-		*len = 0;
-	}
-}
-
-
-gsize
-purple_mime_part_get_length(PurpleMimePart *part)
-{
-	g_return_val_if_fail(part != NULL, 0);
-	g_return_val_if_fail(part->data != NULL, 0);
-
-	return part->data->len;
-}
-
-
-void
-purple_mime_part_set_data(PurpleMimePart *part, const char *data)
-{
-	g_return_if_fail(part != NULL);
-	g_string_free(part->data, TRUE);
-	part->data = g_string_new(data);
-}
-
-
-PurpleMimeDocument *
-purple_mime_document_new()
-{
-	PurpleMimeDocument *doc;
-
-	doc = g_new0(PurpleMimeDocument, 1);
-	fields_init(&doc->fields);
-
-	return doc;
-}
-
-
-static void
-doc_parts_load(PurpleMimeDocument *doc, const char *boundary, const char *buf, gsize len)
-{
-	char *b = (char *) buf;
-	gsize n = len;
-
-	char *bnd;
-	gsize bl;
-
-	bnd = g_strdup_printf("--%s", boundary);
-	bl = strlen(bnd);
-
-	for(b = g_strstr_len(b, n, bnd); b; ) {
-		char *tail;
-
-		/* skip the boundary */
-		b += bl;
-		n -= bl;
-
-		/* skip the trailing \r\n or -- as well */
-		if(n >= 2) {
-			b += 2;
-			n -= 2;
-		}
-
-		/* find the next boundary */
-		tail = g_strstr_len(b, n, bnd);
-
-		if(tail) {
-			gsize sl;
-
-			sl = tail - b;
-			if(sl) {
-				PurpleMimePart *part = part_new(doc);
-				part_load(part, b, sl);
-			}
-		}
-
-		b = tail;
-	}
-
-	g_free(bnd);
-}
-
-#define BOUNDARY "boundary="
-static char *
-parse_boundary(const char *ct)
-{
-	char *boundary_begin = g_strstr_len(ct, -1, BOUNDARY);
-	char *boundary_end;
-
-	if (!boundary_begin)
-		return NULL;
-
-	boundary_begin += sizeof(BOUNDARY) - 1;
-
-	if (*boundary_begin == '"') {
-		boundary_end = strchr(++boundary_begin, '"');
-		if (!boundary_end)
-			return NULL;
-	} else {
-		boundary_end = strchr(boundary_begin, ' ');
-		if (!boundary_end) {
-			boundary_end = strchr(boundary_begin, ';');
-			if (!boundary_end)
-				boundary_end = boundary_begin + strlen(boundary_begin);
-		}
-	}
-
-	return g_strndup(boundary_begin, boundary_end - boundary_begin);
-}
-#undef BOUNDARY
-
-PurpleMimeDocument *
-purple_mime_document_parsen(const char *buf, gsize len)
-{
-	PurpleMimeDocument *doc;
-
-	char *b = (char *) buf;
-	gsize n = len;
-
-	g_return_val_if_fail(buf != NULL, NULL);
-
-	doc = purple_mime_document_new();
-
-	if (!len)
-		return doc;
-
-	fields_load(&doc->fields, &b, &n);
-
-	{
-		const char *ct = fields_get(&doc->fields, "content-type");
-		if (ct && purple_str_has_prefix(ct, "multipart")) {
-			char *bd = parse_boundary(ct);
-			if (bd) {
-				doc_parts_load(doc, bd, b, n);
-				g_free(bd);
-			}
-		}
-	}
-
-	return doc;
-}
-
-
-PurpleMimeDocument *
-purple_mime_document_parse(const char *buf)
-{
-	g_return_val_if_fail(buf != NULL, NULL);
-	return purple_mime_document_parsen(buf, strlen(buf));
-}
-
-
-void
-purple_mime_document_write(PurpleMimeDocument *doc, GString *str)
-{
-	const char *bd = NULL;
-
-	g_return_if_fail(doc != NULL);
-	g_return_if_fail(str != NULL);
-
-	{
-		const char *ct = fields_get(&doc->fields, "content-type");
-		if(ct && purple_str_has_prefix(ct, "multipart")) {
-			char *b = strrchr(ct, '=');
-			if(b++) bd = b;
-		}
-	}
-
-	fields_write(&doc->fields, str);
-
-	if(bd) {
-		GList *l;
-
-		for(l = doc->parts; l; l = l->next) {
-			g_string_append_printf(str, "--%s\r\n", bd);
-
-			part_write(l->data, str);
-
-			if(! l->next) {
-				g_string_append_printf(str, "--%s--\r\n", bd);
-			}
-		}
-	}
-}
-
-
-GList *
-purple_mime_document_get_fields(PurpleMimeDocument *doc)
-{
-	g_return_val_if_fail(doc != NULL, NULL);
-	return doc->fields.keys;
-}
-
-
-const char *
-purple_mime_document_get_field(PurpleMimeDocument *doc, const char *field)
-{
-	g_return_val_if_fail(doc != NULL, NULL);
-	return fields_get(&doc->fields, field);
-}
-
-
-void
-purple_mime_document_set_field(PurpleMimeDocument *doc, const char *field, const char *value)
-{
-	g_return_if_fail(doc != NULL);
-	fields_set(&doc->fields, field, value);
-}
-
-
-GList *
-purple_mime_document_get_parts(PurpleMimeDocument *doc)
-{
-	g_return_val_if_fail(doc != NULL, NULL);
-	return doc->parts;
-}
-
-
-void
-purple_mime_document_free(PurpleMimeDocument *doc)
-{
-	if (!doc)
-		return;
-
-	fields_destroy(&doc->fields);
-
-	while(doc->parts) {
-		part_free(doc->parts->data);
-		doc->parts = g_list_delete_link(doc->parts, doc->parts);
-	}
-
-	g_free(doc);
-}
--- a/libpurple/mime.h	Sun Mar 31 17:45:25 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,245 +0,0 @@
-/*
- * Purple
- *
- * Purple is the legal property of its developers, whose names are too
- * numerous to list here. Please refer to the COPYRIGHT file distributed
- * with this source distribution
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program 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
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301,
- * USA.
- */
-
-#ifndef _PURPLE_MIME_H
-#define _PURPLE_MIME_H
-/**
- * SECTION:mime
- * @section_id: libpurple-mime
- * @short_description: <filename>mime.h</filename>
- * @title: Multi-part MIME Message Parsing
- *
- * Rudimentary parsing of multi-part MIME messages into more
- * accessible structures.
- */
-
-#include <glib.h>
-
-/**
- * PurpleMimeDocument:
- *
- * A MIME document.
- */
-typedef struct _PurpleMimeDocument PurpleMimeDocument;
-
-/**
- * PurpleMimePart:
- *
- * A part of a multipart MIME document.
- */
-typedef struct _PurpleMimePart PurpleMimePart;
-
-G_BEGIN_DECLS
-
-/**
- * purple_mime_document_new:
- *
- * Allocate an empty MIME document.
- */
-PurpleMimeDocument *purple_mime_document_new(void);
-
-/**
- * purple_mime_document_free:
- * @doc: The MIME document to free.
- *
- * Frees memory used in a MIME document and all of its parts and fields
- */
-void purple_mime_document_free(PurpleMimeDocument *doc);
-
-/**
- * purple_mime_document_parse:
- * @buf: The NULL-terminated string containing the MIME-encoded data.
- *
- * Parse a MIME document from a NUL-terminated string.
- *
- * Returns: A MIME document.
- */
-PurpleMimeDocument *purple_mime_document_parse(const char *buf);
-
-/**
- * purple_mime_document_parsen:
- * @buf: The string containing the MIME-encoded data.
- * @len: Length of buf.
- *
- * Parse a MIME document from a string
- *
- * Returns:   A MIME document.
- */
-PurpleMimeDocument *purple_mime_document_parsen(const char *buf, gsize len);
-
-/**
- * purple_mime_document_write:
- * @doc: The MIME document.
- * @str: The string to write the MIME document to.
- *
- * Write (append) a MIME document onto a GString.
- */
-void purple_mime_document_write(PurpleMimeDocument *doc, GString *str);
-
-/**
- * purple_mime_document_get_fields:
- * @doc: The MIME document.
- *
- * The list of fields in the header of a document
- *
- * Returns: (element-type utf8) (transfer none): A list of strings indicating
- *          the fields (but not the values of the fields) in the header of doc.
- */
-GList *purple_mime_document_get_fields(PurpleMimeDocument *doc);
-
-/**
- * purple_mime_document_get_field:
- * @doc:   The MIME document.
- * @field: Case-insensitive field name.
- *
- * Get the value of a specific field in the header of a document.
- *
- * Returns:     Value associated with the indicated header field, or
- *              NULL if the field doesn't exist.
- */
-const char *purple_mime_document_get_field(PurpleMimeDocument *doc,
-					 const char *field);
-
-/**
- * purple_mime_document_set_field:
- * @doc:   The MIME document.
- * @field: Case-insensitive field name.
- * @value: Value to associate with the indicated header field,
- *              of NULL to remove the field.
- *
- * Set or replace the value of a specific field in the header of a
- * document.
- */
-void purple_mime_document_set_field(PurpleMimeDocument *doc,
-				  const char *field,
-				  const char *value);
-
-/**
- * purple_mime_document_get_parts:
- * @doc: The MIME document.
- *
- * The list of parts in a multipart document.
- *
- * Returns: (element-type PurpleMimePart) (transfer none): List of MIME parts
- *          contained within doc.
- */
-GList *purple_mime_document_get_parts(PurpleMimeDocument *doc);
-
-/**
- * purple_mime_part_new:
- * @doc: The new part's parent MIME document.
- *
- * Create and insert a new part into a MIME document.
- */
-PurpleMimePart *purple_mime_part_new(PurpleMimeDocument *doc);
-
-
-/**
- * purple_mime_part_get_fields:
- * @part: The MIME document part.
- *
- * The list of fields in the header of a document part.
- *
- * Returns: (element-type utf8) (transfer none): List of strings indicating the
- *          fields (but not the values of the fields) in the header of part.
- */
-GList *purple_mime_part_get_fields(PurpleMimePart *part);
-
-
-/**
- * purple_mime_part_get_field:
- * @part:  The MIME document part.
- * @field: Case-insensitive name of the header field.
- *
- * Get the value of a specific field in the header of a document part.
- *
- * Returns:     Value of the specified header field, or NULL if the
- *              field doesn't exist.
- */
-const char *purple_mime_part_get_field(PurpleMimePart *part,
-				     const char *field);
-
-/**
- * purple_mime_part_get_field_decoded:
- * @part:  The MIME document part.
- * @field: Case-insensitive name of the header field.
- *
- * Get the decoded value of a specific field in the header of a
- * document part.
- */
-char *purple_mime_part_get_field_decoded(PurpleMimePart *part,
-				       const char *field);
-
-/**
- * purple_mime_part_set_field:
- * @part:  The part of the MIME document.
- * @field: Case-insensitive field name
- * @value: Value to associate with the indicated header field,
- *              of NULL to remove the field.
- *
- * Set or replace the value of a specific field in the header of a
- * document.
- */
-void purple_mime_part_set_field(PurpleMimePart *part,
-			      const char *field,
-			      const char *value);
-
-/**
- * purple_mime_part_get_data:
- * @part: The MIME document part.
- *
- * Get the (possibly encoded) data portion of a MIME document part.
- *
- * Returns:    NULL-terminated data found in the document part
- */
-const char *purple_mime_part_get_data(PurpleMimePart *part);
-
-/**
- * purple_mime_part_get_data_decoded:
- * @part: The MIME documemt part.
- * @data: Buffer for the data.
- * @len:  The length of the buffer.
- *
- * Get the data portion of a MIME document part, after attempting to
- * decode it according to the content-transfer-encoding field. If the
- * specified encoding method is not supported, this function will
- * return NULL.
- */
-void purple_mime_part_get_data_decoded(PurpleMimePart *part,
-				     guchar **data, gsize *len);
-
-/**
- * purple_mime_part_get_length:
- * @part: The MIME document part.
- *
- * Get the length of the data portion of a MIME document part.
- *
- * Returns:    Length of the data in the document part.
- */
-gsize purple_mime_part_get_length(PurpleMimePart *part);
-
-void purple_mime_part_set_data(PurpleMimePart *part, const char *data);
-
-G_END_DECLS
-
-#endif
--- a/libpurple/tests/test_util.c	Sun Mar 31 17:45:25 2019 -0400
+++ b/libpurple/tests/test_util.c	Sun Mar 31 18:14:48 2019 -0400
@@ -497,16 +497,6 @@
 }
 
 /******************************************************************************
- * MIME tests
- *****************************************************************************/
-static void
-test_util_mime_decode_field(void) {
-	gchar *result = purple_mime_decode_field("=?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?=");
-	g_assert_cmpstr("Keld Jørn Simonsen", ==, result);
-	g_free(result);
-}
-
-/******************************************************************************
  * strdup_withhtml tests
  *****************************************************************************/
 static void
@@ -584,9 +574,6 @@
 	g_test_add_func("/util/utf8/strip unprintables",
 	                test_util_utf8_strip_unprintables);
 
-	g_test_add_func("/util/mime/decode field",
-	                test_util_mime_decode_field);
-
 	g_test_add_func("/util/test_strdup_withhtml",
 	                test_util_strdup_withhtml);
 
--- a/libpurple/util.c	Sun Mar 31 17:45:25 2019 -0400
+++ b/libpurple/util.c	Sun Mar 31 18:14:48 2019 -0400
@@ -165,212 +165,6 @@
 }
 
 /**************************************************************************
- * Quoted Printable Functions (see RFC 2045).
- **************************************************************************/
-static const char xdigits[] =
-	"0123456789abcdef";
-
-guchar *
-purple_quotedp_decode(const char *str, gsize *ret_len)
-{
-	char *n, *new;
-	const char *end, *p;
-
-	n = new = g_malloc(strlen (str) + 1);
-	end = str + strlen(str);
-
-	for (p = str; p < end; p++, n++) {
-		if (*p == '=') {
-			if (p[1] == '\r' && p[2] == '\n') { /* 5.1 #5 */
-				n -= 1;
-				p += 2;
-			} else if (p[1] == '\n') { /* fuzzy case for 5.1 #5 */
-				n -= 1;
-				p += 1;
-			} else if (p[1] && p[2]) {
-				char *nibble1 = strchr(xdigits, tolower(p[1]));
-				char *nibble2 = strchr(xdigits, tolower(p[2]));
-				if (nibble1 && nibble2) { /* 5.1 #1 */
-					*n = ((nibble1 - xdigits) << 4) | (nibble2 - xdigits);
-					p += 2;
-				} else { /* This should never happen */
-					*n = *p;
-				}
-			} else { /* This should never happen */
-				*n = *p;
-			}
-		}
-		else if (*p == '_')
-			*n = ' ';
-		else
-			*n = *p;
-	}
-
-	*n = '\0';
-
-	if (ret_len != NULL)
-		*ret_len = n - new;
-
-	/* Resize to take less space */
-	/* new = realloc(new, n - new); */
-
-	return (guchar *)new;
-}
-
-/**************************************************************************
- * MIME Functions
- **************************************************************************/
-char *
-purple_mime_decode_field(const char *str)
-{
-	/*
-	 * This is wing's version, partially based on revo/shx's version
-	 * See RFC2047 [which apparently obsoletes RFC1342]
-	 */
-	typedef enum {
-		state_start, state_equal1, state_question1,
-		state_charset, state_question2,
-		state_encoding, state_question3,
-		state_encoded_text, state_question4, state_equal2 = state_start
-	} encoded_word_state_t;
-	encoded_word_state_t state = state_start;
-	const char *cur, *mark;
-	const char *charset0 = NULL, *encoding0 = NULL, *encoded_text0 = NULL;
-	GString *new;
-
-	/* token can be any CHAR (supposedly ISO8859-1/ISO2022), not just ASCII */
-	#define token_char_p(c) \
-		(c != ' ' && !iscntrl(c) && !strchr("()<>@,;:\"/[]?.=", c))
-
-	/* But encoded-text must be ASCII; alas, isascii() may not exist */
-	#define encoded_text_char_p(c) \
-		((c & 0x80) == 0 && c != '?' && c != ' ' && isgraph(c))
-
-	g_return_val_if_fail(str != NULL, NULL);
-
-	new = g_string_new(NULL);
-
-	/* Here we will be looking for encoded words and if they seem to be
-	 * valid then decode them.
-	 * They are of this form: =?charset?encoding?text?=
-	 */
-
-	for (cur = str, mark = NULL; *cur; cur += 1) {
-		switch (state) {
-		case state_equal1:
-			if (*cur == '?') {
-				state = state_question1;
-			} else {
-				g_string_append_len(new, mark, cur - mark + 1);
-				state = state_start;
-			}
-			break;
-		case state_question1:
-			if (token_char_p(*cur)) {
-				charset0 = cur;
-				state = state_charset;
-			} else { /* This should never happen */
-				g_string_append_len(new, mark, cur - mark + 1);
-				state = state_start;
-			}
-			break;
-		case state_charset:
-			if (*cur == '?') {
-				state = state_question2;
-			} else if (!token_char_p(*cur)) { /* This should never happen */
-				g_string_append_len(new, mark, cur - mark + 1);
-				state = state_start;
-			}
-			break;
-		case state_question2:
-			if (token_char_p(*cur)) {
-				encoding0 = cur;
-				state = state_encoding;
-			} else { /* This should never happen */
-				g_string_append_len(new, mark, cur - mark + 1);
-				state = state_start;
-			}
-			break;
-		case state_encoding:
-			if (*cur == '?') {
-				state = state_question3;
-			} else if (!token_char_p(*cur)) { /* This should never happen */
-				g_string_append_len(new, mark, cur - mark + 1);
-				state = state_start;
-			}
-			break;
-		case state_question3:
-			if (encoded_text_char_p(*cur)) {
-				encoded_text0 = cur;
-				state = state_encoded_text;
-			} else if (*cur == '?') { /* empty string */
-				encoded_text0 = cur;
-				state = state_question4;
-			} else { /* This should never happen */
-				g_string_append_len(new, mark, cur - mark + 1);
-				state = state_start;
-			}
-			break;
-		case state_encoded_text:
-			if (*cur == '?') {
-				state = state_question4;
-			} else if (!encoded_text_char_p(*cur)) {
-				g_string_append_len(new, mark, cur - mark + 1);
-				state = state_start;
-			}
-			break;
-		case state_question4:
-			if (*cur == '=') { /* Got the whole encoded-word */
-				char *charset = g_strndup(charset0, encoding0 - charset0 - 1);
-				char *encoding = g_strndup(encoding0, encoded_text0 - encoding0 - 1);
-				char *encoded_text = g_strndup(encoded_text0, cur - encoded_text0 - 1);
-				guchar *decoded = NULL;
-				gsize dec_len;
-				if (g_ascii_strcasecmp(encoding, "Q") == 0)
-					decoded = purple_quotedp_decode(encoded_text, &dec_len);
-				else if (g_ascii_strcasecmp(encoding, "B") == 0)
-					decoded = g_base64_decode(encoded_text, &dec_len);
-				else
-					decoded = NULL;
-				if (decoded) {
-					gsize len;
-					char *converted = g_convert((const gchar *)decoded, dec_len, "utf-8", charset, NULL, &len, NULL);
-
-					if (converted) {
-						g_string_append_len(new, converted, len);
-						g_free(converted);
-					}
-					g_free(decoded);
-				}
-				g_free(charset);
-				g_free(encoding);
-				g_free(encoded_text);
-				state = state_equal2; /* Restart the FSM */
-			} else { /* This should never happen */
-				g_string_append_len(new, mark, cur - mark + 1);
-				state = state_start;
-			}
-			break;
-		default:
-			if (*cur == '=') {
-				mark = cur;
-				state = state_equal1;
-			} else {
-				/* Some unencoded text. */
-				g_string_append_c(new, *cur);
-			}
-			break;
-		} /* switch */
-	} /* for */
-
-	if (state != state_start)
-		g_string_append_len(new, mark, cur - mark + 1);
-
-	return g_string_free(new, FALSE);;
-}
-
-
-/**************************************************************************
  * Date/Time Functions
  **************************************************************************/
 
--- a/libpurple/util.h	Sun Mar 31 17:45:25 2019 -0400
+++ b/libpurple/util.h	Sun Mar 31 18:14:48 2019 -0400
@@ -158,52 +158,6 @@
 gchar *purple_base16_encode_chunked(const guchar *data, gsize len);
 
 /**************************************************************************/
-/* Quoted Printable Functions                                             */
-/**************************************************************************/
-
-/**
- * purple_quotedp_decode:
- * @str:     The quoted printable ASCII string to convert to raw data.
- * @ret_len: The length of the returned data.
- *
- * Converts a quoted printable string back to its readable equivalent.
- * What is a quoted printable string, you ask?  It's an encoding used
- * to transmit binary data as ASCII.  It's intended purpose is to send
- * emails containing non-ASCII characters.  Wikipedia has a pretty good
- * explanation.  Also see RFC 2045.
- *
- * Returns: The readable string.  Must be g_free'd when no longer needed.
- */
-guchar *purple_quotedp_decode(const char *str, gsize *ret_len);
-
-/**************************************************************************/
-/* MIME Functions                                                         */
-/**************************************************************************/
-
-/**
- * purple_mime_decode_field:
- * @str: The ASCII string, possibly containing any number of
- *            encoded-word sections.
- *
- * Converts a MIME header field string back to its readable equivalent
- * according to RFC 2047.  Basically, a header is plain ASCII and can
- * contain any number of sections called "encoded-words."  The format
- * of an encoded word is =?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?=
- * =? designates the beginning of the encoded-word
- * ?= designates the end of the encoded-word
- *
- * An encoded word is segmented into three pieces by the use of a
- * question mark.  The first piece is the character set, the second
- * piece is the encoding, and the third piece is the encoded text.
- *
- * Returns: The string, with any encoded-word sections decoded and
- *         converted to UTF-8.  Must be g_free'd when no longer
- *         needed.
- */
-char *purple_mime_decode_field(const char *str);
-
-
-/**************************************************************************/
 /* Date/Time Functions                                                    */
 /**************************************************************************/
 

mercurial