From ff76f6920e36f5befff270ba318bc612d1585839 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Wed, 27 Feb 2019 10:26:47 +0000 Subject: [PATCH 638/682] gbase64: Allow g_base64_encode (NULL, 0) and g_base64_decode ("", *) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Relax a precondition in g_base64_encode_step() to allow this. It’s valid to base64 encode an empty string, as per RFC 4648. Similarly for g_base64_decode(), although calling it with a NULL string has never been allowed. Instead, clarify the case of calling it with an empty string. This includes a unit test. Signed-off-by: Philip Withnall Fixes: #1698 --- glib/gbase64.c | 8 ++++---- glib/tests/base64.c | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/glib/gbase64.c b/glib/gbase64.c index d3416e310..baddae098 100644 --- a/glib/gbase64.c +++ b/glib/gbase64.c @@ -100,7 +100,7 @@ g_base64_encode_step (const guchar *in, char *outptr; const guchar *inptr; - g_return_val_if_fail (in != NULL, 0); + g_return_val_if_fail (in != NULL || len == 0, 0); g_return_val_if_fail (out != NULL, 0); g_return_val_if_fail (state != NULL, 0); g_return_val_if_fail (save != NULL, 0); @@ -244,7 +244,7 @@ g_base64_encode_close (gboolean break_lines, /** * g_base64_encode: - * @data: (array length=len) (element-type guint8): the binary data to encode + * @data: (array length=len) (element-type guint8) (nullable): the binary data to encode * @len: the length of @data * * Encode a sequence of binary data into its Base-64 stringified @@ -334,7 +334,7 @@ g_base64_decode_step (const gchar *in, unsigned int v; int i; - g_return_val_if_fail (in != NULL, 0); + g_return_val_if_fail (in != NULL || len == 0, 0); g_return_val_if_fail (out != NULL, 0); g_return_val_if_fail (state != NULL, 0); g_return_val_if_fail (save != NULL, 0); @@ -390,7 +390,7 @@ g_base64_decode_step (const gchar *in, /** * g_base64_decode: - * @text: zero-terminated string with base64 text to decode + * @text: (not nullable): zero-terminated string with base64 text to decode * @out_len: (out): The length of the decoded data is written here * * Decode a sequence of Base-64 encoded text into binary data. Note diff --git a/glib/tests/base64.c b/glib/tests/base64.c index 86875a29b..6091d1eed 100644 --- a/glib/tests/base64.c +++ b/glib/tests/base64.c @@ -406,6 +406,42 @@ test_base64_decode_smallblock (gconstpointer blocksize_p) } } +/* Test that calling g_base64_encode (NULL, 0) returns correct output. This is + * as per the first test vector in RFC 4648 §10. + * https://tools.ietf.org/html/rfc4648#section-10 */ +static void +test_base64_encode_empty (void) +{ + gchar *encoded = NULL; + + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/1698"); + + encoded = g_base64_encode (NULL, 0); + g_assert_cmpstr (encoded, ==, ""); + g_free (encoded); + + encoded = g_base64_encode ((const guchar *) "", 0); + g_assert_cmpstr (encoded, ==, ""); + g_free (encoded); +} + +/* Test that calling g_base64_decode ("", *) returns correct output. This is + * as per the first test vector in RFC 4648 §10. Note that calling + * g_base64_decode (NULL, *) is not allowed. + * https://tools.ietf.org/html/rfc4648#section-10 */ +static void +test_base64_decode_empty (void) +{ + guchar *decoded = NULL; + gsize decoded_len; + + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/1698"); + + decoded = g_base64_decode ("", &decoded_len); + g_assert_cmpstr ((gchar *) decoded, ==, ""); + g_assert_cmpuint (decoded_len, ==, 0); + g_free (decoded); +} int main (int argc, char *argv[]) @@ -455,5 +491,8 @@ main (int argc, char *argv[]) g_test_add_data_func ("/base64/incremental/smallblock/4", GINT_TO_POINTER(4), test_base64_decode_smallblock); + g_test_add_func ("/base64/encode/empty", test_base64_encode_empty); + g_test_add_func ("/base64/decode/empty", test_base64_decode_empty); + return g_test_run (); } -- 2.19.1