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.
This commit is contained in:
Benjamin Otte
2021-12-05 18:05:14 +01:00
parent 506b009925
commit a7a3ec8a16
2 changed files with 36 additions and 13 deletions

View File

@@ -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 == '{')
depth = gtk_json_parser_get_depth (self);
while (TRUE)
{
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
{
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)
{

View File

@@ -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,