[gtk/wip/otte/json: 15/21] jsonparser: Don't stack overflow
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/json: 15/21] jsonparser: Don't stack overflow
- Date: Mon, 6 Dec 2021 14:05:05 +0000 (UTC)
commit c451576d6884a15a9d7be86feb73a404dbfc92c7
Author: Benjamin Otte <otte redhat com>
Date: Sun Dec 5 18:05:14 2021 +0100
jsonparser: Don't stack overflow
Handle skipping deep nested object/array trees when skipping them
without causing stack overflow.
The code is somewhat brittle, but it seems to work.
gtk/json/gtkjsonparser.c | 48 ++++++++++++++++++++++++++++++-----------
gtk/json/gtkjsonparserprivate.h | 1 +
2 files changed, 36 insertions(+), 13 deletions(-)
---
diff --git a/gtk/json/gtkjsonparser.c b/gtk/json/gtkjsonparser.c
index ab0e6c1823..6cda09ffb2 100644
--- a/gtk/json/gtkjsonparser.c
+++ b/gtk/json/gtkjsonparser.c
@@ -1012,24 +1012,40 @@ gtk_json_parser_free (GtkJsonParser *self)
static gboolean
gtk_json_parser_skip_block (GtkJsonParser *self)
{
+ gsize depth;
+
if (self->reader != self->block->value)
return TRUE;
- if (*self->reader == '{')
- {
- return gtk_json_parser_start_object (self) &&
- gtk_json_parser_end (self);
- }
- else if (*self->reader == '[')
- {
- return gtk_json_parser_start_array (self) &&
- gtk_json_parser_end (self);
- }
- else
+ depth = gtk_json_parser_get_depth (self);
+ while (TRUE)
{
- g_assert_not_reached ();
- return FALSE;
+ if (*self->reader == '{')
+ {
+ if (!gtk_json_parser_start_object (self))
+ return FALSE;
+ }
+ else if (*self->reader == '[')
+ {
+ if (!gtk_json_parser_start_array (self))
+ return FALSE;
+ }
+
+ while (self->reader != self->block->value)
+ {
+ /* This should never be reentrant to this function or we might
+ * loop causing stack overflow */
+ if (!gtk_json_parser_next (self))
+ {
+ if (!gtk_json_parser_end (self))
+ return FALSE;
+ if (depth >= gtk_json_parser_get_depth (self))
+ return TRUE;
+ }
+ }
}
+
+ return TRUE;
}
gboolean
@@ -1147,6 +1163,12 @@ gtk_json_parser_next (GtkJsonParser *self)
return TRUE;
}
+gsize
+gtk_json_parser_get_depth (GtkJsonParser *self)
+{
+ return self->block - self->blocks;
+}
+
GtkJsonNode
gtk_json_parser_get_node (GtkJsonParser *self)
{
diff --git a/gtk/json/gtkjsonparserprivate.h b/gtk/json/gtkjsonparserprivate.h
index fe737fb719..155a5b7603 100644
--- a/gtk/json/gtkjsonparserprivate.h
+++ b/gtk/json/gtkjsonparserprivate.h
@@ -55,6 +55,7 @@ GtkJsonParser * gtk_json_parser_new_for_string (const char
void gtk_json_parser_free (GtkJsonParser *self);
gboolean gtk_json_parser_next (GtkJsonParser *self);
+gsize gtk_json_parser_get_depth (GtkJsonParser *self);
GtkJsonNode gtk_json_parser_get_node (GtkJsonParser *self);
char * gtk_json_parser_get_member_name (GtkJsonParser *self);
gssize gtk_json_parser_select_member (GtkJsonParser *self,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]