size_t len = strlen(jsonstring);
# ifndef WITH_YAJL2
yajl_parser_config cfg = { 0, 1 };
+ virJSONValuePtr tmp;
# endif
VIR_DEBUG("string=%s", jsonstring);
goto cleanup;
}
+ /* Yajl 2 is nice enough to default to rejecting trailing garbage.
+ * Yajl 1.0.12 has yajl_get_bytes_consumed to make that detection
+ * simpler. But we're stuck with yajl 1.0.7 on RHEL 6, which
+ * happily quits parsing at the end of a valid JSON construct,
+ * with no visibility into how much more input remains. Wrapping
+ * things in an array forces yajl to confess the truth. */
+# ifdef WITH_YAJL2
rc = yajl_parse(hand, (const unsigned char *)jsonstring, len);
+# else
+ rc = yajl_parse(hand, (const unsigned char *)"[", 1);
+ if (VIR_YAJL_STATUS_OK(rc))
+ rc = yajl_parse(hand, (const unsigned char *)jsonstring, len);
+ if (VIR_YAJL_STATUS_OK(rc))
+ rc = yajl_parse(hand, (const unsigned char *)"]", 1);
+# endif
if (!VIR_YAJL_STATUS_OK(rc) ||
yajl_complete_parse(hand) != yajl_status_ok) {
unsigned char *errstr = yajl_get_error(hand, 1,
virJSONValueFree(parser.head);
} else {
ret = parser.head;
+# ifndef WITH_YAJL2
+ /* Undo the array wrapping above */
+ tmp = ret;
+ ret = NULL;
+ if (virJSONValueArraySize(tmp) > 1)
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse json %s: too many items present"),
+ jsonstring);
+ else
+ ret = virJSONValueArraySteal(tmp, 0);
+ virJSONValueFree(tmp);
+# endif
}
cleanup:
VIR_FREE(parser.state);
}
- VIR_DEBUG("result=%p", parser.head);
+ VIR_DEBUG("result=%p", ret);
return ret;
}
DO_TEST_PARSE_FAIL("overdone keyword", "[ truest ]");
DO_TEST_PARSE_FAIL("unknown keyword", "huh");
DO_TEST_PARSE_FAIL("comments", "[ /* nope */\n1 // not this either\n]");
+ DO_TEST_PARSE_FAIL("trailing garbage", "[] []");
+ DO_TEST_PARSE_FAIL("list without array", "1, 1");
DO_TEST_PARSE_FAIL("object with numeric keys", "{ 1:1, 2:1, 3:2 }");
DO_TEST_PARSE_FAIL("unterminated object", "{ \"1\":1, \"2\":1, \"3\":2");