diff --git a/glib/giochannel.c b/glib/giochannel.c index b44fff35b..e54aea256 100644 --- a/glib/giochannel.c +++ b/glib/giochannel.c @@ -877,26 +877,31 @@ g_io_channel_set_line_term (GIOChannel *channel, const gchar *line_term, gint length) { - guint length_unsigned; - g_return_if_fail (channel != NULL); g_return_if_fail (line_term == NULL || length != 0); /* Disallow "" */ + g_free (channel->line_term); + if (line_term == NULL) - length_unsigned = 0; + { + channel->line_term = NULL; + channel->line_term_len = 0; + } else if (length >= 0) - length_unsigned = (guint) length; + { + /* We store the value nul-terminated even if the input is not */ + channel->line_term = g_malloc0 (length + 1); + memcpy (channel->line_term, line_term, length); + channel->line_term_len = (guint) length; + } else { - /* FIXME: We’re constrained by line_term_len being a guint here */ + /* We’re constrained by line_term_len being a guint here */ gsize length_size = strlen (line_term); g_return_if_fail (length_size <= G_MAXUINT); - length_unsigned = (guint) length_size; + channel->line_term = g_strdup (line_term); + channel->line_term_len = (guint) length_size; } - - g_free (channel->line_term); - channel->line_term = line_term ? g_memdup2 (line_term, length_unsigned) : NULL; - channel->line_term_len = length_unsigned; } /** @@ -906,7 +911,8 @@ g_io_channel_set_line_term (GIOChannel *channel, * * This returns the string that #GIOChannel uses to determine * where in the file a line break occurs. A value of %NULL - * indicates autodetection. + * indicates autodetection. Since 2.84, the return value is always + * nul-terminated. * * Returns: The line termination string. This value * is owned by GLib and must not be freed. diff --git a/glib/tests/io-channel.c b/glib/tests/io-channel.c index c5dd01d04..99879be1b 100644 --- a/glib/tests/io-channel.c +++ b/glib/tests/io-channel.c @@ -178,6 +178,8 @@ test_read_line_embedded_nuls (void) GError *local_error = NULL; gchar *line = NULL; gsize line_length, terminator_pos; + const gchar *line_term; + gint line_term_length; GIOStatus status; g_test_summary ("Test that reading a line containing embedded nuls works " @@ -200,6 +202,11 @@ test_read_line_embedded_nuls (void) * Use length -1 here to exercise glib#2323; the case where length > 0 * is covered in glib/tests/protocol.c. */ g_io_channel_set_line_term (channel, "\n", -1); + + line_term = g_io_channel_get_line_term (channel, &line_term_length); + g_assert_cmpstr (line_term, ==, "\n"); + g_assert_cmpint (line_term_length, ==, 1); + g_io_channel_set_encoding (channel, NULL, &local_error); g_assert_no_error (local_error);