gbase64: Allow g_base64_encode (NULL, 0) and g_base64_decode ("", *)

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 <withnall@endlessm.com>

Fixes: #1698
This commit is contained in:
Philip Withnall 2019-02-27 10:26:47 +00:00
parent 86e099c134
commit ff76f6920e
2 changed files with 43 additions and 4 deletions

View File

@ -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

View File

@ -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 ();
}