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:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user