From 6224d3d2ecdbc3cacfdb8213de3cf53d6dfc8580 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 10 Jun 2009 23:50:45 -0400 Subject: [PATCH] Fix g_string_chunk_insert_len to accept nuls Contrary to what the documentation says, g_string_chunk_insert_len was stopping at the first nul. Also add a test. Fixes bug 585088. --- glib/gstring.c | 54 ++++++++++++++++++++++++++--------------------------- glib/tests/string.c | 23 +++++++++++++++++++++++ 2 files changed, 49 insertions(+), 28 deletions(-) diff --git a/glib/gstring.c b/glib/gstring.c index 9f0198b..bc2a9d2 100644 --- a/glib/gstring.c +++ b/glib/gstring.c @@ -247,22 +247,22 @@ g_string_chunk_insert (GStringChunk *chunk, * g_string_chunk_insert_const: * @chunk: a #GStringChunk * @string: the string to add - * - * Adds a copy of @string to the #GStringChunk, unless the same - * string has already been added to the #GStringChunk with + * + * Adds a copy of @string to the #GStringChunk, unless the same + * string has already been added to the #GStringChunk with * g_string_chunk_insert_const(). - * - * This function is useful if you need to copy a large number - * of strings but do not want to waste space storing duplicates. - * But you must remember that there may be several pointers to - * the same string, and so any changes made to the strings + * + * This function is useful if you need to copy a large number + * of strings but do not want to waste space storing duplicates. + * But you must remember that there may be several pointers to + * the same string, and so any changes made to the strings * should be done very carefully. - * - * Note that g_string_chunk_insert_const() will not return a - * pointer to a string added with g_string_chunk_insert(), even + * + * Note that g_string_chunk_insert_const() will not return a + * pointer to a string added with g_string_chunk_insert(), even * if they do match. - * - * Returns: a pointer to the new or existing copy of @string + * + * Returns: a pointer to the new or existing copy of @string * within the #GStringChunk */ gchar* @@ -291,26 +291,26 @@ g_string_chunk_insert_const (GStringChunk *chunk, * g_string_chunk_insert_len: * @chunk: a #GStringChunk * @string: bytes to insert - * @len: number of bytes of @string to insert, or -1 to insert a - * nul-terminated string - * - * Adds a copy of the first @len bytes of @string to the #GStringChunk. + * @len: number of bytes of @string to insert, or -1 to insert a + * nul-terminated string + * + * Adds a copy of the first @len bytes of @string to the #GStringChunk. * The copy is nul-terminated. - * + * * Since this function does not stop at nul bytes, it is the caller's - * responsibility to ensure that @string has at least @len addressable + * responsibility to ensure that @string has at least @len addressable * bytes. * - * The characters in the returned string can be changed, if necessary, + * The characters in the returned string can be changed, if necessary, * though you should not change anything after the end of the string. - * + * * Return value: a pointer to the copy of @string within the #GStringChunk - * + * * Since: 2.4 - **/ + */ gchar* g_string_chunk_insert_len (GStringChunk *chunk, - const gchar *string, + const gchar *string, gssize len) { gssize size; @@ -322,7 +322,7 @@ g_string_chunk_insert_len (GStringChunk *chunk, size = strlen (string); else size = len; - + if ((chunk->storage_next + size + 1) > chunk->this_size) { gsize new_size = nearest_power (chunk->default_size, size + 1); @@ -338,9 +338,7 @@ g_string_chunk_insert_len (GStringChunk *chunk, *(pos + size) = '\0'; - strncpy (pos, string, size); - if (len > 0) - size = strlen (pos); + memcpy (pos, string, size); chunk->storage_next += size + 1; diff --git a/glib/tests/string.c b/glib/tests/string.c index 3ee03c6..d3f289f 100644 --- a/glib/tests/string.c +++ b/glib/tests/string.c @@ -50,6 +50,28 @@ test_string_chunks (void) } static void +test_string_chunk_insert (void) +{ + const gchar s0[] = "Testing GStringChunk"; + const gchar s1[] = "a\0b\0c\0d\0"; + const gchar s2[] = "Hello, world"; + GStringChunk *chunk; + gchar *str[3]; + + chunk = g_string_chunk_new (512); + + str[0] = g_string_chunk_insert (chunk, s0); + str[1] = g_string_chunk_insert_len (chunk, s1, 8); + str[2] = g_string_chunk_insert (chunk, s2); + + g_assert (memcmp (s0, str[0], sizeof s0) == 0); + g_assert (memcmp (s1, str[1], sizeof s1) == 0); + g_assert (memcmp (s2, str[2], sizeof s2) == 0); + + g_string_chunk_free (chunk); +} + +static void test_string_new (void) { GString *string1, *string2; @@ -376,6 +398,7 @@ main (int argc, g_test_init (&argc, &argv, NULL); g_test_add_func ("/string/test-string-chunks", test_string_chunks); + g_test_add_func ("/string/test-string-chunk-insert", test_string_chunk_insert); g_test_add_func ("/string/test-string-new", test_string_new); g_test_add_func ("/string/test-string-printf", test_string_printf); g_test_add_func ("/string/test-string-assign", test_string_assign); -- 2.7.4