mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-25 03:32:12 +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;
|
char *outptr;
|
||||||
const guchar *inptr;
|
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 (out != NULL, 0);
|
||||||
g_return_val_if_fail (state != NULL, 0);
|
g_return_val_if_fail (state != NULL, 0);
|
||||||
g_return_val_if_fail (save != NULL, 0);
|
g_return_val_if_fail (save != NULL, 0);
|
||||||
|
|
||||||
if (len <= 0)
|
if (len == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
inptr = in;
|
inptr = in;
|
||||||
@ -160,7 +160,8 @@ g_base64_encode_step (const guchar *in,
|
|||||||
*state = already;
|
*state = already;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len>0)
|
g_assert (len == 0 || len == 1 || len == 2);
|
||||||
|
|
||||||
{
|
{
|
||||||
char *saveout;
|
char *saveout;
|
||||||
|
|
||||||
@ -244,7 +245,7 @@ g_base64_encode_close (gboolean break_lines,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* g_base64_encode:
|
* 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
|
* @len: the length of @data
|
||||||
*
|
*
|
||||||
* Encode a sequence of binary data into its Base-64 stringified
|
* 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,
|
/* 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 */
|
+1 is needed for trailing \0, also check for unlikely integer overflow */
|
||||||
if (len >= ((G_MAXSIZE - 1) / 4 - 1) * 3)
|
g_return_val_if_fail (len < ((G_MAXSIZE - 1) / 4 - 1) * 3, NULL);
|
||||||
g_error("%s: input too large for Base64 encoding (%"G_GSIZE_FORMAT" chars)",
|
|
||||||
G_STRLOC, len);
|
|
||||||
|
|
||||||
out = g_malloc ((len / 3 + 1) * 4 + 1);
|
out = g_malloc ((len / 3 + 1) * 4 + 1);
|
||||||
|
|
||||||
@ -336,12 +335,12 @@ g_base64_decode_step (const gchar *in,
|
|||||||
unsigned int v;
|
unsigned int v;
|
||||||
int i;
|
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 (out != NULL, 0);
|
||||||
g_return_val_if_fail (state != NULL, 0);
|
g_return_val_if_fail (state != NULL, 0);
|
||||||
g_return_val_if_fail (save != NULL, 0);
|
g_return_val_if_fail (save != NULL, 0);
|
||||||
|
|
||||||
if (len <= 0)
|
if (len == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
inend = (const guchar *)in+len;
|
inend = (const guchar *)in+len;
|
||||||
@ -392,7 +391,7 @@ g_base64_decode_step (const gchar *in,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* g_base64_decode:
|
* 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
|
* @out_len: (out): The length of the decoded data is written here
|
||||||
*
|
*
|
||||||
* Decode a sequence of Base-64 encoded text into binary data. Note
|
* 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
|
int
|
||||||
main (int argc, char *argv[])
|
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),
|
g_test_add_data_func ("/base64/incremental/smallblock/4", GINT_TO_POINTER(4),
|
||||||
test_base64_decode_smallblock);
|
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 ();
|
return g_test_run ();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user