diff --git a/src/Makefile.am b/src/Makefile.am index 1bed0f3..6db1e1a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -17,8 +17,6 @@ libgabble_convenience_la_SOURCES = \ addressing-util.c \ auth-manager.h \ auth-manager.c \ - base64.h \ - base64.c \ bytestream-factory.h \ bytestream-factory.c \ bytestream-ibb.h \ diff --git a/src/base64.c b/src/base64.c deleted file mode 100644 index 600fa39..0000000 --- a/src/base64.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * base64.c - Base 64 encoding/decoding implementation - * Copyright (C) 2006 Collabora Ltd. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" -#include "base64.h" - -#define DEBUG_FLAG GABBLE_DEBUG_VCARD -#include "debug.h" - -#include -#include - - -/* -|AAAA AABB|BBBB CCCC|CCDD DDDD| - -0xFC = 1111 1100 -0x03 = 0000 0011 -0xF0 = 1111 0000 -0x0F = 0000 1111 -0xC0 = 1100 0000 -0x3F = 0011 1111 - -3 input bytes = 4 output bytes; -2 input bytes = 2 output bytes; -1 input byte = 1 output byte. -*/ - -static const gchar *encoding = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -static const guint decoding[256] = -{ - /* ... */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, - /* + */ - 62, - /* ... */ - 0, 0, 0, - /* / , 0-9 */ - 63, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, - /* ... */ - 0, 0, 0, 0, 0, 0, 0, - /* A */ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - /* ... */ - 0, 0, 0, 0, 0, 0, - /* a */ - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 -}; - -#define GET_6_BITS_0(s) (((s)[0] & 0xFC) >> 2) -#define GET_6_BITS_1(s) (((s)[0] & 0x03) << 4) | \ - (((s)[1] & 0xF0) >> 4) -#define GET_6_BITS_2(s) (((s)[1] & 0x0F) << 2) | \ - (((s)[2] & 0xC0) >> 6) -#define GET_6_BITS_3(s) (((s)[2] & 0x3F) << 0) - -#define GET_BYTE_0(s) (((decoding[(guchar)(s)[0]] & 0x3F) << 2) | \ - ((decoding[(guchar)(s)[1]] & 0x30) >> 4)) -#define GET_BYTE_1(s) (((decoding[(guchar)(s)[1]] & 0x0F) << 4) | \ - ((decoding[(guchar)(s)[2]] & 0x3C) >> 2)) -#define GET_BYTE_2(s) (((decoding[(guchar)(s)[2]] & 0x03) << 6) | \ - ((decoding[(guchar)(s)[3]] & 0xFF) << 0)) - -gchar *base64_encode (guint len, const gchar *str, gboolean split_lines) -{ - guint i; - GString *tmp; - - /* TODO: calculate requisite output string length and allocate that big a - * GString */ - tmp = g_string_new (""); - - for (i = 0; i < len; i += 3) - { - guint c1, c2, c3, c4; - - if (split_lines && i > 0 && (i * 4) % 76 == 0) - g_string_append_c (tmp, '\n'); - - switch (i + 3 - len) - { - case 1: - c1 = encoding[GET_6_BITS_0 (str + i)]; - c2 = encoding[GET_6_BITS_1 (str + i)]; - /* can't use GET_6_BITS_2 because str[i+2] is out of range */ - c3 = encoding[(str[i + 1] & 0x0f) << 2]; - c4 = '='; - break; - case 2: - c1 = encoding[GET_6_BITS_0 (str + i)]; - /* can't use GET_6_BITS_1 because str[i+1] is out of range */ - c2 = encoding[(str[i] & 0x03) << 4]; - c3 = '='; - c4 = '='; - break; - default: - c1 = encoding[GET_6_BITS_0 (str + i)]; - c2 = encoding[GET_6_BITS_1 (str + i)]; - c3 = encoding[GET_6_BITS_2 (str + i)]; - c4 = encoding[GET_6_BITS_3 (str + i)]; - } - - g_string_append_printf (tmp, "%c%c%c%c", c1, c2, c3, c4); - } - - return g_string_free (tmp, FALSE); -} - -GString *base64_decode (const gchar *str) -{ - guint i; - GString *tmp; - char group[4]; - guint filled = 0; - - for (i = 0; str[i]; i++) - { - if (str[i] != 'A' && - str[i] != '=' && - !isspace (str[i]) && - decoding[(guchar) str[i]] == 0) - { - DEBUG ("bad character %x at byte %u", (guchar)str[i], i); - return NULL; - } - } - - tmp = g_string_new (""); - - for (i = 0; str[i]; i++) - { - if (isspace (str[i])) - continue; - - group[filled++] = str[i]; - - if (filled == 4) - { - if (group[3] == '=') - { - if (group[2] == '=') - { - g_string_append_c (tmp, GET_BYTE_0(group)); - } - else - { - g_string_append_c (tmp, GET_BYTE_0(group)); - g_string_append_c (tmp, GET_BYTE_1(group)); - } - } - else - { - g_string_append_c (tmp, GET_BYTE_0(group)); - g_string_append_c (tmp, GET_BYTE_1(group)); - g_string_append_c (tmp, GET_BYTE_2(group)); - } - filled = 0; - } - } - - if (filled) - { - DEBUG ("insufficient padding at end of base64 string:\n%s", str); - g_string_free (tmp, TRUE); - return NULL; - } - - return tmp; -} - - diff --git a/src/base64.h b/src/base64.h deleted file mode 100644 index 35bd8f4..0000000 --- a/src/base64.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * base64.h - Base 64 encoding/decoding implementation - * Copyright (C) 2006 Collabora Ltd. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __BASE64_H__ -#define __BASE64_H__ - -#include - -gchar *base64_encode (guint len, const gchar *str, gboolean split_lines); -GString *base64_decode (const gchar *str); - -#endif /* __BASE64_H__ */ diff --git a/src/bytestream-ibb.c b/src/bytestream-ibb.c index a479eb2..d885dea 100644 --- a/src/bytestream-ibb.c +++ b/src/bytestream-ibb.c @@ -29,7 +29,6 @@ #define DEBUG_FLAG GABBLE_DEBUG_BYTESTREAM -#include "base64.h" #include "bytestream-factory.h" #include "bytestream-iface.h" #include "connection.h" @@ -506,7 +505,7 @@ send_data (GabbleBytestreamIBB *self, send_now = remaining; } - encoded = base64_encode (send_now, str + sent, FALSE); + encoded = g_base64_encode (str + sent, send_now); seq = g_strdup_printf ("%u", priv->seq++); iq = wocky_stanza_build (WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, @@ -608,6 +607,8 @@ gabble_bytestream_ibb_receive (GabbleBytestreamIBB *self, GabbleBytestreamIBBPrivate *priv = GABBLE_BYTESTREAM_IBB_GET_PRIVATE (self); WockyNode *data; GString *str; + guchar *st; + gsize outlen; TpHandle sender; /* caller must have checked for this in order to know which bytestream to @@ -633,7 +634,9 @@ gabble_bytestream_ibb_receive (GabbleBytestreamIBB *self, /* FIXME: check sequence number */ - str = base64_decode (data->content); + st = g_base64_decode (data->content, &outlen); + str = g_string_new_len (st, outlen); + g_free (st); if (str == NULL) { DEBUG ("base64 decoding failed"); diff --git a/src/bytestream-muc.c b/src/bytestream-muc.c index 84ade62..73902af 100644 --- a/src/bytestream-muc.c +++ b/src/bytestream-muc.c @@ -29,7 +29,6 @@ #define DEBUG_FLAG GABBLE_DEBUG_BYTESTREAM -#include "base64.h" #include "bytestream-factory.h" #include "bytestream-iface.h" #include "connection.h" @@ -340,7 +339,7 @@ send_data_to (GabbleBytestreamMuc *self, frag = FRAG_LAST; } - encoded = base64_encode (send_now, str + sent, FALSE); + encoded = g_base64_encode (str + sent, send_now); wocky_node_set_content (data, encoded); switch (frag) @@ -406,6 +405,8 @@ gabble_bytestream_muc_receive (GabbleBytestreamMuc *self, const gchar *from; WockyNode *data; GString *str; + guchar *st; + gsize outlen; TpHandle sender; GString *buffer; const gchar *frag_val; @@ -454,7 +455,9 @@ gabble_bytestream_muc_receive (GabbleBytestreamMuc *self, return; } - str = base64_decode (data->content); + st = g_base64_decode (data->content, &outlen); + str = g_string_new_len (st, outlen); + g_free (st); if (str == NULL) { DEBUG ("base64 decoding failed"); diff --git a/src/bytestream-multiple.c b/src/bytestream-multiple.c index 4fa1cb8..49bdc59 100644 --- a/src/bytestream-multiple.c +++ b/src/bytestream-multiple.c @@ -28,7 +28,6 @@ #define DEBUG_FLAG GABBLE_DEBUG_BYTESTREAM -#include "base64.h" #include "bytestream-factory.h" #include "bytestream-iface.h" #include "connection.h" diff --git a/src/bytestream-socks5.c b/src/bytestream-socks5.c index dfebc2a..67a87ad 100644 --- a/src/bytestream-socks5.c +++ b/src/bytestream-socks5.c @@ -54,7 +54,6 @@ #define DEBUG_FLAG GABBLE_DEBUG_BYTESTREAM -#include "base64.h" #include "bytestream-factory.h" #include "bytestream-iface.h" #include "connection.h" diff --git a/src/caps-hash.c b/src/caps-hash.c index 12d302e..ec2efc9 100644 --- a/src/caps-hash.c +++ b/src/caps-hash.c @@ -33,7 +33,6 @@ #define DEBUG_FLAG GABBLE_DEBUG_PRESENCE -#include "base64.h" #include "gabble/capabilities.h" #include "debug.h" #include "namespaces.h" diff --git a/src/conn-avatars.c b/src/conn-avatars.c index 7504c63..5e5db58 100644 --- a/src/conn-avatars.c +++ b/src/conn-avatars.c @@ -27,7 +27,6 @@ #include #include -#include "base64.h" #include "presence.h" #include "presence-cache.h" #include "conn-presence.h" @@ -415,6 +414,8 @@ parse_avatar (WockyNode *vcard, WockyNode *type_node; WockyNode *binval_node; const gchar *binval_value; + guchar *st; + gsize outlen; photo_node = wocky_node_get_child (vcard, "PHOTO"); @@ -454,7 +455,9 @@ parse_avatar (WockyNode *vcard, return FALSE; } - *avatar = base64_decode (binval_value); + st = g_base64_decode (binval_value, &outlen); + *avatar = g_string_new_len (st, outlen); + g_free (st); if (NULL == *avatar) { @@ -832,8 +835,15 @@ gabble_connection_set_avatar (TpSvcConnectionInterfaceAvatars *iface, if (avatar != NULL && avatar->len > 0) { + gint state = 0, save = 0, outlen; + ctx->avatar = g_string_new_len (avatar->data, avatar->len); - base64 = base64_encode (avatar->len, avatar->data, TRUE); + base64 = g_malloc ((avatar->len / 3 + 1) * 4 + 1); + outlen = g_base64_encode_step (avatar->data, avatar->len, TRUE, + base64, &state, &save); + outlen += g_base64_encode_close (TRUE, base64 + outlen, + &state, &save); + base64[outlen] = '\0'; DEBUG ("Replacing avatar"); diff --git a/src/tube-dbus.c b/src/tube-dbus.c index 5223d47..387ae82 100644 --- a/src/tube-dbus.c +++ b/src/tube-dbus.c @@ -34,7 +34,6 @@ #define DEBUG_FLAG GABBLE_DEBUG_TUBES -#include "base64.h" #include "bytestream-factory.h" #include "bytestream-ibb.h" #include "bytestream-iface.h" @@ -1590,7 +1589,7 @@ _gabble_generate_dbus_unique_name (const gchar *nick) if (len <= 186) { - encoded = base64_encode (len, nick, FALSE); + encoded = g_base64_encode (nick, len); } else { @@ -1603,7 +1602,7 @@ _gabble_generate_dbus_unique_name (const gchar *nick) g_string_append_len (tmp, nick, 169); g_string_append_len (tmp, (const gchar *) sha1, 20); - encoded = base64_encode (tmp->len, tmp->str, FALSE); + encoded = g_base64_encode (tmp->str, tmp->len); g_string_free (tmp, TRUE); } diff --git a/src/util.c b/src/util.c index 57b4660..3069b2d 100644 --- a/src/util.c +++ b/src/util.c @@ -36,7 +36,6 @@ #define DEBUG_FLAG GABBLE_DEBUG_JID -#include "base64.h" #include "conn-aliasing.h" #include "connection.h" #include "debug.h" @@ -404,8 +403,12 @@ lm_message_node_extract_properties (WockyNode *node, { GArray *arr; GString *decoded; + guchar *st; + gsize outlen; - decoded = base64_decode (value); + st = g_base64_decode (value, &outlen); + decoded = g_string_new_len (st, outlen); + g_free (st); if (!decoded) continue; @@ -525,7 +528,7 @@ set_child_from_property (gpointer key, type = "bytes"; arr = g_value_get_boxed (gvalue); - str = base64_encode (arr->len, arr->data, FALSE); + str = g_base64_encode (arr->data, arr->len); wocky_node_set_content (child, str); g_free (str); diff --git a/src/vcard-manager.c b/src/vcard-manager.c index b8777a4..c9f5ab2 100644 --- a/src/vcard-manager.c +++ b/src/vcard-manager.c @@ -30,7 +30,6 @@ #define DEBUG_FLAG GABBLE_DEBUG_VCARD -#include "base64.h" #include "conn-aliasing.h" #include "conn-contact-info.h" #include "connection.h" @@ -642,7 +641,8 @@ vcard_get_avatar_sha1 (WockyNode *vcard) { gchar *sha1; const gchar *binval_value; - GString *avatar; + guchar *avatar; + gsize outlen; WockyNode *node; WockyNode *binval; @@ -662,12 +662,12 @@ vcard_get_avatar_sha1 (WockyNode *vcard) if (!binval_value) return g_strdup (""); - avatar = base64_decode (binval_value); + avatar = g_base64_decode (binval_value, &outlen); if (avatar) { - sha1 = sha1_hex (avatar->str, avatar->len); - g_string_free (avatar, TRUE); + sha1 = sha1_hex (avatar, outlen); + g_free (avatar); DEBUG ("Successfully decoded PHOTO.BINVAL, SHA-1 %s", sha1); } else diff --git a/tests/Makefile.am b/tests/Makefile.am index 2d2860e..c97e5d1 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,7 +1,6 @@ SUBDIRS = twisted suppressions tests_list = \ - test-base64 \ test-dtube-unique-names \ test-gabble-idle-weak \ test-handles \ @@ -53,7 +52,6 @@ check-valgrind: $(TESTS) check_c_sources = \ $(dbus_test_sources) \ - test-base64.c \ test-dtube-unique-names.c \ test-presence.c \ test-jid-decode.c \ diff --git a/tests/test-base64.c b/tests/test-base64.c deleted file mode 100644 index 49ebbf3..0000000 --- a/tests/test-base64.c +++ /dev/null @@ -1,106 +0,0 @@ - -#include "config.h" - -#include -#include - -#include - -#include "src/base64.h" - -struct test { - gchar *str; - size_t len; - gchar *encoded; -}; - -struct test tests[] = { - { "c", 0, "Yw==" }, - { "ca", 0, "Y2E=" }, - { "car", 0, "Y2Fy" }, - { "carnal pleasure.", 0, "Y2FybmFsIHBsZWFzdXJlLg==" }, - { "carnal pleasure", 0, "Y2FybmFsIHBsZWFzdXJl" }, - { "carnal pleasur", 0, "Y2FybmFsIHBsZWFzdXI=" }, - { "carnal pleasu", 0, "Y2FybmFsIHBsZWFzdQ==" }, - /* test long (> 76 / 4 * 3) string */ - { - "1234567890" - "1234567890" - "1234567890" - "1234567890" - "1234567890" - "1234567890", - 0, - "MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM" - "0NTY3\nODkw" }, - /* regression test: formerly we assumed that there was a NUL immediately - * after the data */ - { "hello", 5, "aGVsbG8=" }, - { "hello\xff\xff", 5, "aGVsbG8=" }, - - { NULL, 0, NULL } -}; - -int -main (void) -{ - gchar *s; - GString *tmp1, *tmp2; - struct test *t; - - g_type_init (); - - for (t = tests; t->str != NULL; t++) - { - if (t->len == 0) - t->len = strlen (t->str); - s = base64_encode (t->len, t->str, TRUE); - g_assert (0 == strcmp (s, t->encoded)); - g_free (s); - } - - /* test string with valid characters but invalid length */ - tmp1 = base64_decode ("AAA"); - g_assert (tmp1 == NULL); - - /* test string with valid length but invalid characters */ - tmp1 = base64_decode ("????"); - g_assert (tmp1 == NULL); - - /* test string with embedded newline */ - tmp1 = base64_decode ("bWF6\ndWxlbQ=="); - tmp2 = g_string_new ("mazulem"); - g_assert (tmp1); - g_assert (g_string_equal (tmp1, tmp2)); - g_string_free (tmp1, TRUE); - g_string_free (tmp2, TRUE); - - /* test string with misc whitespace */ - tmp1 = base64_decode ("bW F\r6\r\ndW\nxlbQ==\r\n"); - tmp2 = g_string_new ("mazulem"); - g_assert (tmp1); - g_assert (g_string_equal (tmp1, tmp2)); - g_string_free (tmp1, TRUE); - g_string_free (tmp2, TRUE); - - /* test string with embedded NULL */ - tmp1 = base64_decode ("Zm9vAGJhcg=="); - tmp2 = g_string_new_len ("foo\0bar", 7); - g_assert (tmp1); - g_assert (g_string_equal (tmp1, tmp2)); - g_string_free (tmp1, TRUE); - g_string_free (tmp2, TRUE); - - for (t = tests; t->str != NULL; t++) - { - tmp1 = base64_decode (t->encoded); - g_assert (tmp1); - tmp2 = g_string_new_len (t->str, t->len); - g_assert (g_string_equal (tmp1, tmp2)); - g_string_free (tmp1, TRUE); - g_string_free (tmp2, TRUE); - } - - return 0; -} -