Bug Summary

File:lapiz/lapiz-document-output-stream.c
Warning:line 331, column 26
Out of bound memory access (access exceeds upper limit of memory block)

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name lapiz-document-output-stream.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/lapiz -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I .. -I .. -I . -I ./smclient -I /usr/include/libxml2 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/ctk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/gio-unix-2.0 -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/local/include/ctksourceview-4 -I /usr/local/include/libbean-1.0 -I /usr/include/gobject-introspection-1.0 -I /usr/include/gobject-introspection-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -D DATADIR="/usr/share" -D LAPIZ_DATADIR="/usr/share/lapiz" -D LIBDIR="/usr/lib" -D PIC -internal-isystem /usr/lib/llvm-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/rootdir/lapiz -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2024-08-17-001006-33765-1 -x c lapiz-document-output-stream.c
1/*
2 * lapiz-document-output-stream.c
3 * This file is part of lapiz
4 *
5 * Copyright (C) 2010 - Ignacio Casal Quinteiro
6 *
7 * lapiz is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * lapiz is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with lapiz; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor,
20 * Boston, MA 02110-1301 USA
21 */
22
23#include "config.h"
24
25#include <string.h>
26#include <glib.h>
27#include <glib/gi18n.h>
28#include <gio/gio.h>
29#include "lapiz-document-output-stream.h"
30
31/* NOTE: never use async methods on this stream, the stream is just
32 * a wrapper around CtkTextBuffer api so that we can use GIO Stream
33 * methods, but the undelying code operates on a CtkTextBuffer, so
34 * there is no I/O involved and should be accessed only by the main
35 * thread */
36
37#define MAX_UNICHAR_LEN6 6
38
39struct _LapizDocumentOutputStreamPrivate
40{
41 LapizDocument *doc;
42 CtkTextIter pos;
43
44 gchar *buffer;
45 gsize buflen;
46
47 guint is_initialized : 1;
48 guint is_closed : 1;
49};
50
51enum
52{
53 PROP_0,
54 PROP_DOCUMENT
55};
56
57G_DEFINE_TYPE_WITH_PRIVATE (LapizDocumentOutputStream, lapiz_document_output_stream, G_TYPE_OUTPUT_STREAM)static void lapiz_document_output_stream_init (LapizDocumentOutputStream
*self); static void lapiz_document_output_stream_class_init (
LapizDocumentOutputStreamClass *klass); static GType lapiz_document_output_stream_get_type_once
(void); static gpointer lapiz_document_output_stream_parent_class
= ((void*)0); static gint LapizDocumentOutputStream_private_offset
; static void lapiz_document_output_stream_class_intern_init (
gpointer klass) { lapiz_document_output_stream_parent_class =
g_type_class_peek_parent (klass); if (LapizDocumentOutputStream_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &LapizDocumentOutputStream_private_offset
); lapiz_document_output_stream_class_init ((LapizDocumentOutputStreamClass
*) klass); } __attribute__ ((__unused__)) static inline gpointer
lapiz_document_output_stream_get_instance_private (LapizDocumentOutputStream
*self) { return (((gpointer) ((guint8*) (self) + (glong) (LapizDocumentOutputStream_private_offset
)))); } GType lapiz_document_output_stream_get_type (void) { static
GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); (void) (0 ? (gpointer) * (
&static_g_define_type_id) : ((void*)0)); (!(__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= lapiz_document_output_stream_get_type_once (); (__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); 0 ? (void
) (*(&static_g_define_type_id) = (g_define_type_id)) : (void
) 0; g_once_init_leave_pointer ((&static_g_define_type_id
), (gpointer) (guintptr) (g_define_type_id)); })) ; } return static_g_define_type_id
; } __attribute__ ((__noinline__)) static GType lapiz_document_output_stream_get_type_once
(void) { GType g_define_type_id = g_type_register_static_simple
((g_output_stream_get_type ()), g_intern_static_string ("LapizDocumentOutputStream"
), sizeof (LapizDocumentOutputStreamClass), (GClassInitFunc)(
void (*)(void)) lapiz_document_output_stream_class_intern_init
, sizeof (LapizDocumentOutputStream), (GInstanceInitFunc)(void
(*)(void)) lapiz_document_output_stream_init, (GTypeFlags) 0
); { {{ LapizDocumentOutputStream_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (LapizDocumentOutputStreamPrivate)
); };} } return g_define_type_id; }
58
59static gssize lapiz_document_output_stream_write (GOutputStream *stream,
60 const void *buffer,
61 gsize count,
62 GCancellable *cancellable,
63 GError **error);
64
65static gboolean lapiz_document_output_stream_flush (GOutputStream *stream,
66 GCancellable *cancellable,
67 GError **error);
68
69static gboolean lapiz_document_output_stream_close (GOutputStream *stream,
70 GCancellable *cancellable,
71 GError **error);
72
73static void
74lapiz_document_output_stream_set_property (GObject *object,
75 guint prop_id,
76 const GValue *value,
77 GParamSpec *pspec)
78{
79 LapizDocumentOutputStream *stream = LAPIZ_DOCUMENT_OUTPUT_STREAM (object)((((LapizDocumentOutputStream*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((object)), ((lapiz_document_output_stream_get_type
()))))))
;
80
81 switch (prop_id)
82 {
83 case PROP_DOCUMENT:
84 stream->priv->doc = LAPIZ_DOCUMENT (g_value_get_object (value))((((LapizDocument*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((g_value_get_object (value))), ((lapiz_document_get_type(
)))))))
;
85 break;
86
87 default:
88 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "lapiz-document-output-stream.c", 88, ("property"), _glib__property_id
, _glib__pspec->name, g_type_name ((((((GTypeClass*) (((GTypeInstance
*) (_glib__pspec))->g_class))->g_type)))), (g_type_name
((((((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
;
89 break;
90 }
91}
92
93static void
94lapiz_document_output_stream_get_property (GObject *object,
95 guint prop_id,
96 GValue *value,
97 GParamSpec *pspec)
98{
99 LapizDocumentOutputStream *stream = LAPIZ_DOCUMENT_OUTPUT_STREAM (object)((((LapizDocumentOutputStream*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((object)), ((lapiz_document_output_stream_get_type
()))))))
;
100
101 switch (prop_id)
102 {
103 case PROP_DOCUMENT:
104 g_value_set_object (value, stream->priv->doc);
105 break;
106
107 default:
108 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "lapiz-document-output-stream.c", 108, ("property"), _glib__property_id
, _glib__pspec->name, g_type_name ((((((GTypeClass*) (((GTypeInstance
*) (_glib__pspec))->g_class))->g_type)))), (g_type_name
((((((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
;
109 break;
110 }
111}
112
113static void
114lapiz_document_output_stream_finalize (GObject *object)
115{
116 LapizDocumentOutputStream *stream = LAPIZ_DOCUMENT_OUTPUT_STREAM (object)((((LapizDocumentOutputStream*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((object)), ((lapiz_document_output_stream_get_type
()))))))
;
117
118 g_free (stream->priv->buffer);
119
120 G_OBJECT_CLASS (lapiz_document_output_stream_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((lapiz_document_output_stream_parent_class)), (((GType) (
(20) << (2))))))))
->finalize (object);
121}
122
123static void
124lapiz_document_output_stream_constructed (GObject *object)
125{
126 LapizDocumentOutputStream *stream = LAPIZ_DOCUMENT_OUTPUT_STREAM (object)((((LapizDocumentOutputStream*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((object)), ((lapiz_document_output_stream_get_type
()))))))
;
127
128 if (!stream->priv->doc)
129 {
130 g_critical ("This should never happen, a problem happened constructing the Document Output Stream!");
131 return;
132 }
133
134 /* Init the undoable action */
135 ctk_source_buffer_begin_not_undoable_action (CTK_SOURCE_BUFFER (stream->priv->doc)((((CtkSourceBuffer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((stream->priv->doc)), ((ctk_source_buffer_get_type (
)))))))
);
136 /* clear the buffer */
137 ctk_text_buffer_set_text (CTK_TEXT_BUFFER (stream->priv->doc)((((CtkTextBuffer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((stream->priv->doc)), ((ctk_text_buffer_get_type ()
))))))
,
138 "", 0);
139 ctk_text_buffer_set_modified (CTK_TEXT_BUFFER (stream->priv->doc)((((CtkTextBuffer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((stream->priv->doc)), ((ctk_text_buffer_get_type ()
))))))
,
140 FALSE(0));
141
142 ctk_source_buffer_end_not_undoable_action (CTK_SOURCE_BUFFER (stream->priv->doc)((((CtkSourceBuffer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((stream->priv->doc)), ((ctk_source_buffer_get_type (
)))))))
);
143}
144
145static void
146lapiz_document_output_stream_class_init (LapizDocumentOutputStreamClass *klass)
147{
148 GObjectClass *object_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), (((GType) ((20) << (2))))))))
;
149 GOutputStreamClass *stream_class = G_OUTPUT_STREAM_CLASS (klass)((((GOutputStreamClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), ((g_output_stream_get_type ()))))))
;
150
151 object_class->get_property = lapiz_document_output_stream_get_property;
152 object_class->set_property = lapiz_document_output_stream_set_property;
153 object_class->finalize = lapiz_document_output_stream_finalize;
154 object_class->constructed = lapiz_document_output_stream_constructed;
155
156 stream_class->write_fn = lapiz_document_output_stream_write;
157 stream_class->flush = lapiz_document_output_stream_flush;
158 stream_class->close_fn = lapiz_document_output_stream_close;
159
160 g_object_class_install_property (object_class,
161 PROP_DOCUMENT,
162 g_param_spec_object ("document",
163 "Document",
164 "The document which is written",
165 LAPIZ_TYPE_DOCUMENT(lapiz_document_get_type()),
166 G_PARAM_READWRITE |
167 G_PARAM_CONSTRUCT_ONLY));
168}
169
170static void
171lapiz_document_output_stream_init (LapizDocumentOutputStream *stream)
172{
173 stream->priv = lapiz_document_output_stream_get_instance_private (stream);
174
175 stream->priv->buffer = NULL((void*)0);
176 stream->priv->buflen = 0;
177
178 stream->priv->is_initialized = FALSE(0);
179 stream->priv->is_closed = FALSE(0);
180}
181
182static LapizDocumentNewlineType
183get_newline_type (CtkTextIter *end)
184{
185 LapizDocumentNewlineType res;
186 CtkTextIter copy;
187 gunichar c;
188
189 copy = *end;
190 c = ctk_text_iter_get_char (&copy);
191
192 if (g_unichar_break_type (c) == G_UNICODE_BREAK_CARRIAGE_RETURN)
193 {
194 if (ctk_text_iter_forward_char (&copy) &&
195 g_unichar_break_type (ctk_text_iter_get_char (&copy)) == G_UNICODE_BREAK_LINE_FEED)
196 {
197 res = LAPIZ_DOCUMENT_NEWLINE_TYPE_CR_LF;
198 }
199 else
200 {
201 res = LAPIZ_DOCUMENT_NEWLINE_TYPE_CR;
202 }
203 }
204 else
205 {
206 res = LAPIZ_DOCUMENT_NEWLINE_TYPE_LF;
207 }
208
209 return res;
210}
211
212GOutputStream *
213lapiz_document_output_stream_new (LapizDocument *doc)
214{
215 return G_OUTPUT_STREAM (g_object_new (LAPIZ_TYPE_DOCUMENT_OUTPUT_STREAM,((((GOutputStream*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((g_object_new ((lapiz_document_output_stream_get_type ())
, "document", doc, ((void*)0)))), ((g_output_stream_get_type (
)))))))
216 "document", doc, NULL))((((GOutputStream*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((g_object_new ((lapiz_document_output_stream_get_type ())
, "document", doc, ((void*)0)))), ((g_output_stream_get_type (
)))))))
;
217}
218
219LapizDocumentNewlineType
220lapiz_document_output_stream_detect_newline_type (LapizDocumentOutputStream *stream)
221{
222 LapizDocumentNewlineType type;
223 CtkTextIter iter;
224
225 g_return_val_if_fail (LAPIZ_IS_DOCUMENT_OUTPUT_STREAM (stream),do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((stream)); GType __t = ((lapiz_document_output_stream_get_type
())); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "LAPIZ_IS_DOCUMENT_OUTPUT_STREAM (stream)"
); return (LAPIZ_DOCUMENT_NEWLINE_TYPE_LF); } } while (0)
226 LAPIZ_DOCUMENT_NEWLINE_TYPE_DEFAULT)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((stream)); GType __t = ((lapiz_document_output_stream_get_type
())); gboolean __r; if (!__inst) __r = (0); else if (__inst->
g_class && __inst->g_class->g_type == __t) __r =
(!(0)); else __r = g_type_check_instance_is_a (__inst, __t);
__r; })))))) { } else { g_return_if_fail_warning (((gchar*) 0
), ((const char*) (__func__)), "LAPIZ_IS_DOCUMENT_OUTPUT_STREAM (stream)"
); return (LAPIZ_DOCUMENT_NEWLINE_TYPE_LF); } } while (0)
;
227
228 type = LAPIZ_DOCUMENT_NEWLINE_TYPE_DEFAULTLAPIZ_DOCUMENT_NEWLINE_TYPE_LF;
229
230 ctk_text_buffer_get_start_iter (CTK_TEXT_BUFFER (stream->priv->doc)((((CtkTextBuffer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((stream->priv->doc)), ((ctk_text_buffer_get_type ()
))))))
,
231 &iter);
232
233 if (ctk_text_iter_ends_line (&iter) || ctk_text_iter_forward_to_line_end (&iter))
234 {
235 type = get_newline_type (&iter);
236 }
237
238 return type;
239}
240
241/* If the last char is a newline, remove it from the buffer (otherwise
242 CtkTextView shows it as an empty line). See bug #324942. */
243static void
244remove_ending_newline (LapizDocumentOutputStream *stream)
245{
246 CtkTextIter end;
247 CtkTextIter start;
248
249 ctk_text_buffer_get_end_iter (CTK_TEXT_BUFFER (stream->priv->doc)((((CtkTextBuffer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((stream->priv->doc)), ((ctk_text_buffer_get_type ()
))))))
, &end);
250 start = end;
251
252 ctk_text_iter_set_line_offset (&start, 0);
253
254 if (ctk_text_iter_ends_line (&start) &&
255 ctk_text_iter_backward_line (&start))
256 {
257 if (!ctk_text_iter_ends_line (&start))
258 {
259 ctk_text_iter_forward_to_line_end (&start);
260 }
261
262 /* Delete the empty line which is from 'start' to 'end' */
263 ctk_text_buffer_delete (CTK_TEXT_BUFFER (stream->priv->doc)((((CtkTextBuffer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((stream->priv->doc)), ((ctk_text_buffer_get_type ()
))))))
,
264 &start,
265 &end);
266 }
267}
268
269static void
270end_append_text_to_document (LapizDocumentOutputStream *stream)
271{
272 remove_ending_newline (stream);
273
274 ctk_text_buffer_set_modified (CTK_TEXT_BUFFER (stream->priv->doc)((((CtkTextBuffer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((stream->priv->doc)), ((ctk_text_buffer_get_type ()
))))))
,
275 FALSE(0));
276
277 ctk_source_buffer_end_not_undoable_action (CTK_SOURCE_BUFFER (stream->priv->doc)((((CtkSourceBuffer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((stream->priv->doc)), ((ctk_source_buffer_get_type (
)))))))
);
278}
279
280static gssize
281lapiz_document_output_stream_write (GOutputStream *stream,
282 const void *buffer,
283 gsize count,
284 GCancellable *cancellable,
285 GError **error)
286{
287 LapizDocumentOutputStream *ostream;
288 gchar *text;
289 gsize len;
290 gboolean freetext = FALSE(0);
291 const gchar *end;
292 gboolean valid;
293
294 if (g_cancellable_set_error_if_cancelled (cancellable, error))
5
Assuming the condition is false
6
Taking false branch
295 return -1;
296
297 ostream = LAPIZ_DOCUMENT_OUTPUT_STREAM (stream)((((LapizDocumentOutputStream*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((stream)), ((lapiz_document_output_stream_get_type
()))))))
;
298
299 if (!ostream->priv->is_initialized)
7
Assuming field 'is_initialized' is not equal to 0
8
Taking false branch
300 {
301 /* Init the undoable action */
302 ctk_source_buffer_begin_not_undoable_action (CTK_SOURCE_BUFFER (ostream->priv->doc)((((CtkSourceBuffer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ostream->priv->doc)), ((ctk_source_buffer_get_type
()))))))
);
303
304 ctk_text_buffer_get_start_iter (CTK_TEXT_BUFFER (ostream->priv->doc)((((CtkTextBuffer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ostream->priv->doc)), ((ctk_text_buffer_get_type (
)))))))
,
305 &ostream->priv->pos);
306 ostream->priv->is_initialized = TRUE(!(0));
307 }
308
309 if (ostream->priv->buflen > 0)
9
Assuming field 'buflen' is > 0
10
Taking true branch
310 {
311 len = ostream->priv->buflen + count;
312 text = g_new (gchar , len + 1)((gchar *) g_malloc_n ((len + 1), sizeof (gchar)));
313 memcpy (text, ostream->priv->buffer, ostream->priv->buflen);
314 memcpy (text + ostream->priv->buflen, buffer, count);
315 text[len] = '\0';
316 g_free (ostream->priv->buffer);
317 ostream->priv->buffer = NULL((void*)0);
318 ostream->priv->buflen = 0;
319 freetext = TRUE(!(0));
320 }
321 else
322 {
323 text = (gchar *) buffer;
324 len = count;
325 }
326
327 /* validate */
328 valid = g_utf8_validate (text, len, &end);
329
330 /* Avoid keeping a CRLF across two buffers. */
331 if (valid && len > 1 && end[-1] == '\r')
11
Assuming 'valid' is not equal to 0
12
Assuming 'len' is > 1
13
Out of bound memory access (access exceeds upper limit of memory block)
332 {
333 valid = FALSE(0);
334 end--;
335 }
336
337 if (!valid)
338 {
339 gsize nvalid = end - text;
340 gsize remainder = len - nvalid;
341 gunichar ch;
342
343 if ((remainder < MAX_UNICHAR_LEN6) &&
344 ((ch = g_utf8_get_char_validated (text + nvalid, remainder)) == (gunichar)-2 ||
345 ch == (gunichar)'\r'))
346 {
347 ostream->priv->buffer = g_strndup (end, remainder);
348 ostream->priv->buflen = remainder;
349 len -= remainder;
350 }
351 else
352 {
353 /* TODO: we could escape invalid text and tag it in red
354 * and make the doc readonly.
355 */
356 g_set_error (error, G_IO_ERRORg_io_error_quark(), G_IO_ERROR_INVALID_DATA,
357 _("Invalid UTF-8 sequence in input")gettext ("Invalid UTF-8 sequence in input"));
358
359 if (freetext)
360 g_free (text);
361
362 return -1;
363 }
364 }
365
366 ctk_text_buffer_insert (CTK_TEXT_BUFFER (ostream->priv->doc)((((CtkTextBuffer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ostream->priv->doc)), ((ctk_text_buffer_get_type (
)))))))
,
367 &ostream->priv->pos, text, len);
368
369 if (freetext)
370 g_free (text);
371
372 return count;
373}
374
375static gboolean
376lapiz_document_output_stream_flush (GOutputStream *stream,
377 GCancellable *cancellable,
378 GError **error)
379{
380 LapizDocumentOutputStream *ostream = LAPIZ_DOCUMENT_OUTPUT_STREAM (stream)((((LapizDocumentOutputStream*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((stream)), ((lapiz_document_output_stream_get_type
()))))))
;
381
382 /* Flush deferred data if some. */
383 if (!ostream->priv->is_closed && ostream->priv->is_initialized &&
1
Assuming field 'is_closed' is 0
2
Assuming field 'is_initialized' is not equal to 0
384 ostream->priv->buflen > 0 &&
3
Assuming field 'buflen' is > 0
385 lapiz_document_output_stream_write (stream, "", 0, cancellable,
4
Calling 'lapiz_document_output_stream_write'
386 error) == -1)
387 return FALSE(0);
388
389 return TRUE(!(0));
390}
391
392static gboolean
393lapiz_document_output_stream_close (GOutputStream *stream,
394 GCancellable *cancellable G_GNUC_UNUSED__attribute__ ((__unused__)),
395 GError **error)
396{
397 LapizDocumentOutputStream *ostream = LAPIZ_DOCUMENT_OUTPUT_STREAM (stream)((((LapizDocumentOutputStream*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((stream)), ((lapiz_document_output_stream_get_type
()))))))
;
398
399 if (!ostream->priv->is_closed && ostream->priv->is_initialized)
400 {
401 end_append_text_to_document (ostream);
402 ostream->priv->is_closed = TRUE(!(0));
403 }
404
405 if (ostream->priv->buflen > 0)
406 {
407 g_set_error (error, G_IO_ERRORg_io_error_quark(), G_IO_ERROR_INVALID_DATA,
408 _("Incomplete UTF-8 sequence in input")gettext ("Incomplete UTF-8 sequence in input"));
409 return FALSE(0);
410 }
411
412 return TRUE(!(0));
413}