Commit ef5707cd authored by Philip Withnall's avatar Philip Withnall

json-parser: Fix getting immutable root nodes from empty input

If parsing an empty document, it’s allowed to return NULL from
json_parser_get_root(). This was broken for immutable parsers when
immutability support was added (an assertion fails). Fix that, and also
document that json_parser_get_root() may return NULL.

Do the same for json_parser_steal_root() too, which is another way that
the root node may be NULL.

Add a unit test.
Signed-off-by: Philip Withnall's avatarPhilip Withnall <withnall@endlessm.com>
parent 32129036
......@@ -1179,9 +1179,11 @@ json_parser_load_from_data (JsonParser *parser,
* json_parser_get_root:
* @parser: a #JsonParser
*
* Retrieves the top level node from the parsed JSON stream.
* Retrieves the top level node from the parsed JSON stream. If the parser input
* was an empty string, or if parsing failed, this will be %NULL. It will also
* be %NULL if it has been stolen using json_parser_steal_root().
*
* Return value: (transfer none): the root #JsonNode . The returned
* Return value: (transfer none) (nullable): the root #JsonNode . The returned
* node is owned by the #JsonParser and should never be modified
* or freed.
*/
......@@ -1191,7 +1193,8 @@ json_parser_get_root (JsonParser *parser)
g_return_val_if_fail (JSON_IS_PARSER (parser), NULL);
/* Sanity check. */
g_return_val_if_fail (!parser->priv->is_immutable ||
g_return_val_if_fail (parser->priv->root == NULL ||
!parser->priv->is_immutable ||
json_node_is_immutable (parser->priv->root), NULL);
return parser->priv->root;
......@@ -1201,9 +1204,10 @@ json_parser_get_root (JsonParser *parser)
* json_parser_steal_root:
* @parser: a #JsonParser
*
* Steals the top level node from the parsed JSON stream.
* Steals the top level node from the parsed JSON stream. This will be %NULL
* in the same situations as json_parser_get_root() returns %NULL.
*
* Returns: (transfer full): the top level #JsonNode
* Returns: (transfer full) (nullable): the top level #JsonNode
*
* Since: 1.4
*/
......@@ -1214,6 +1218,11 @@ json_parser_steal_root (JsonParser *parser)
g_return_val_if_fail (JSON_IS_PARSER (parser), NULL);
/* Sanity check. */
g_return_val_if_fail (parser->priv->root == NULL ||
!parser->priv->is_immutable ||
json_node_is_immutable (parser->priv->root), NULL);
return g_steal_pointer (&priv->root);
}
......
......@@ -144,14 +144,10 @@ static guint n_test_assignments = G_N_ELEMENTS (test_assignments);
static guint n_test_unicode = G_N_ELEMENTS (test_unicode);
static void
test_empty (void)
test_empty_with_parser (JsonParser *parser)
{
JsonParser *parser;
GError *error = NULL;
parser = json_parser_new ();
g_assert (JSON_IS_PARSER (parser));
if (g_test_verbose ())
g_print ("checking json_parser_load_from_data with empty string...\n");
......@@ -170,7 +166,23 @@ test_empty (void)
g_assert (NULL == json_parser_get_root (parser));
}
}
static void
test_empty (void)
{
JsonParser *parser;
/* Check with and without immutability enabled, as there have been bugs with
* NULL root nodes on immutable parsers. */
parser = json_parser_new ();
g_assert (JSON_IS_PARSER (parser));
test_empty_with_parser (parser);
g_object_unref (parser);
parser = json_parser_new_immutable ();
g_assert (JSON_IS_PARSER (parser));
test_empty_with_parser (parser);
g_object_unref (parser);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment