[gedit] Make sure text passed to insert_text is null terminated
- From: Paolo Borelli <pborelli src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gedit] Make sure text passed to insert_text is null terminated
- Date: Sun, 30 Mar 2014 14:37:26 +0000 (UTC)
commit d50108e57935871125cb42f275ebc2f096448452
Author: Jesse van den Kieboom <jessevdk gmail com>
Date: Wed Mar 19 13:47:54 2014 +0100
Make sure text passed to insert_text is null terminated
https://bugzilla.gnome.org/show_bug.cgi?id=726390
gedit/gedit-document-output-stream.c | 62 ++++++++++++++++++++++++++++-----
1 files changed, 52 insertions(+), 10 deletions(-)
---
diff --git a/gedit/gedit-document-output-stream.c b/gedit/gedit-document-output-stream.c
index dd5a95d..d8e4789 100644
--- a/gedit/gedit-document-output-stream.c
+++ b/gedit/gedit-document-output-stream.c
@@ -579,12 +579,14 @@ insert_fallback (GeditDocumentOutputStream *stream,
static void
validate_and_insert (GeditDocumentOutputStream *stream,
- const gchar *buffer,
- gsize count)
+ gchar *buffer,
+ gsize count,
+ gboolean owned)
{
GtkTextBuffer *text_buffer;
GtkTextIter *iter;
gsize len;
+ gchar *freetext = NULL;
text_buffer = GTK_TEXT_BUFFER (stream->priv->doc);
iter = &stream->priv->pos;
@@ -613,8 +615,9 @@ validate_and_insert (GeditDocumentOutputStream *stream,
if (ptr && *ptr == '\r' && ptr - buffer == len - 1)
{
- stream->priv->buffer = g_new (gchar, 1);
+ stream->priv->buffer = g_new (gchar, 2);
stream->priv->buffer[0] = '\r';
+ stream->priv->buffer[1] = '\0';
stream->priv->buflen = 1;
/* Decrease also the len so in the check
@@ -627,10 +630,41 @@ validate_and_insert (GeditDocumentOutputStream *stream,
/* if we've got any valid char we must tag the invalid chars */
if (nvalid > 0)
{
+ gchar orignonnull = '\0';
+
apply_error_tag (stream);
- }
- gtk_text_buffer_insert (text_buffer, iter, buffer, nvalid);
+ if (nvalid != len && buffer[nvalid] != '\0')
+ {
+ /* make sure the buffer is always properly null
+ * terminated. This is needed, at least for now,
+ * to avoid issues with pygobject marshalling of
+ * the insert-text signal of gtktextbuffer
+ *
+ * https://bugzilla.gnome.org/show_bug.cgi?id=726689
+ */
+ if (!owned)
+ {
+ /* forced to make a copy */
+ freetext = g_new (gchar, len + 1);
+ memcpy (freetext, buffer, len);
+
+ buffer = freetext;
+ owned = TRUE;
+ }
+
+ orignonnull = buffer[nvalid];
+ buffer[nvalid] = '\0';
+ }
+
+ gtk_text_buffer_insert (text_buffer, iter, buffer, nvalid);
+
+ if (orignonnull != '\0')
+ {
+ /* restore null terminated replaced byte */
+ buffer[nvalid] = orignonnull;
+ }
+ }
/* If we inserted all return */
if (nvalid == len)
@@ -660,6 +694,8 @@ validate_and_insert (GeditDocumentOutputStream *stream,
++buffer;
--len;
}
+
+ g_free (freetext);
}
/* If the last char is a newline, remove it from the buffer (otherwise
@@ -723,7 +759,9 @@ convert_text (GeditDocumentOutputStream *stream,
outbuf_size = (inbuf_len > 0) ? inbuf_len : 100;
out_left = outbuf_size;
- out = dest = g_malloc (outbuf_size);
+
+ /* keep room for null termination */
+ out = dest = g_malloc (sizeof (gchar) * (outbuf_size + 1));
done = FALSE;
have_error = FALSE;
@@ -756,7 +794,10 @@ convert_text (GeditDocumentOutputStream *stream,
gsize used = out - dest;
outbuf_size *= 2;
- dest = g_realloc (dest, outbuf_size);
+
+ /* make sure to allocate room for
+ terminating null byte */
+ dest = g_realloc (dest, outbuf_size + 1);
out = dest + used;
out_left = outbuf_size - used;
@@ -792,9 +833,10 @@ convert_text (GeditDocumentOutputStream *stream,
return FALSE;
}
- *outbuf = dest;
*outbuf_len = out - dest;
+ dest[*outbuf_len] = '\0';
+ *outbuf = dest;
return TRUE;
}
@@ -971,7 +1013,7 @@ gedit_document_output_stream_write (GOutputStream *stream,
len = outbuf_len;
}
- validate_and_insert (ostream, text, len);
+ validate_and_insert (ostream, text, len, freetext);
if (freetext)
{
@@ -1003,7 +1045,7 @@ gedit_document_output_stream_flush (GOutputStream *stream,
if (convert_text (ostream, NULL, 0, &outbuf, &outbuf_len, error))
{
- validate_and_insert (ostream, outbuf, outbuf_len);
+ validate_and_insert (ostream, outbuf, outbuf_len, TRUE);
g_free (outbuf);
}
else
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]