mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-24 19:22:11 +01:00
Merge branch '1698-base64-encoding' into 'master'
Resolve "g_base64_encode(NULL, 0) causes critical warnings" Closes #1698 See merge request GNOME/glib!695
This commit is contained in:
commit
cdcb6c2cf1
@ -100,12 +100,12 @@ 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);
|
||||
|
||||
if (len <= 0)
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
inptr = in;
|
||||
@ -160,7 +160,8 @@ g_base64_encode_step (const guchar *in,
|
||||
*state = already;
|
||||
}
|
||||
|
||||
if (len>0)
|
||||
g_assert (len == 0 || len == 1 || len == 2);
|
||||
|
||||
{
|
||||
char *saveout;
|
||||
|
||||
@ -244,7 +245,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
|
||||
@ -268,9 +269,7 @@ g_base64_encode (const guchar *data,
|
||||
|
||||
/* We can use a smaller limit here, since we know the saved state is 0,
|
||||
+1 is needed for trailing \0, also check for unlikely integer overflow */
|
||||
if (len >= ((G_MAXSIZE - 1) / 4 - 1) * 3)
|
||||
g_error("%s: input too large for Base64 encoding (%"G_GSIZE_FORMAT" chars)",
|
||||
G_STRLOC, len);
|
||||
g_return_val_if_fail (len < ((G_MAXSIZE - 1) / 4 - 1) * 3, NULL);
|
||||
|
||||
out = g_malloc ((len / 3 + 1) * 4 + 1);
|
||||
|
||||
@ -336,12 +335,12 @@ 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);
|
||||
|
||||
if (len <= 0)
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
inend = (const guchar *)in+len;
|
||||
@ -392,7 +391,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
|
||||
|
@ -406,6 +406,85 @@ 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);
|
||||
}
|
||||
|
||||
/* Check all the RFC 4648 test vectors for base 64 encoding from §10.
|
||||
* https://tools.ietf.org/html/rfc4648#section-10 */
|
||||
static void
|
||||
test_base64_encode_decode_rfc4648 (void)
|
||||
{
|
||||
const struct
|
||||
{
|
||||
const gchar *decoded; /* technically this should be a byte array, but all the test vectors are ASCII strings */
|
||||
const gchar *encoded;
|
||||
}
|
||||
vectors[] =
|
||||
{
|
||||
{ "", "" },
|
||||
{ "f", "Zg==" },
|
||||
{ "fo", "Zm8=" },
|
||||
{ "foo", "Zm9v" },
|
||||
{ "foob", "Zm9vYg==" },
|
||||
{ "fooba", "Zm9vYmE=" },
|
||||
{ "foobar", "Zm9vYmFy" },
|
||||
};
|
||||
gsize i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (vectors); i++)
|
||||
{
|
||||
gchar *encoded = NULL;
|
||||
guchar *decoded = NULL;
|
||||
gsize expected_decoded_len = strlen (vectors[i].decoded);
|
||||
gsize decoded_len;
|
||||
|
||||
g_test_message ("Vector %" G_GSIZE_FORMAT ": %s", i, vectors[i].decoded);
|
||||
|
||||
encoded = g_base64_encode ((const guchar *) vectors[i].decoded, expected_decoded_len);
|
||||
g_assert_cmpstr (encoded, ==, vectors[i].encoded);
|
||||
|
||||
decoded = g_base64_decode (encoded, &decoded_len);
|
||||
g_assert_cmpstr ((gchar *) decoded, ==, vectors[i].decoded);
|
||||
g_assert_cmpuint (decoded_len, ==, expected_decoded_len);
|
||||
|
||||
g_free (encoded);
|
||||
g_free (decoded);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
@ -455,5 +534,10 @@ 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);
|
||||
|
||||
g_test_add_func ("/base64/encode-decode/rfc4648", test_base64_encode_decode_rfc4648);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user