[libvirt] [PATCH 4/3] json: even stricter trailing garbage detection
Peter Krempa
pkrempa at redhat.com
Tue Jun 23 11:48:44 UTC 2015
On Mon, Jun 22, 2015 at 15:01:15 -0600, Eric Blake wrote:
> Since older yajl ignores trailing garbage, a client can cause
> problems by intentionally ending the wrapper array early. Since
> we already track nesting, it's not too much harder to reject
> invalid nesting pops.
>
> * src/util/virjson. (_virJSONParser): Add field.
> (virJSONValueFromString): Set witness.
> (virJSONParserHandleEndArray): Use it to catch abuse.
> * tests/jsontest.c (mymain): Test it.
>
> Signed-off-by: Eric Blake <eblake at redhat.com>
> ---
>
> Could be squashed with 3/3, if desired.
>
> src/util/virjson.c | 7 +++++--
> tests/jsontest.c | 1 +
> 2 files changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/src/util/virjson.c b/src/util/virjson.c
> index a33005a..3c6ed34 100644
> --- a/src/util/virjson.c
> +++ b/src/util/virjson.c
> @@ -64,6 +64,7 @@ struct _virJSONParser {
> virJSONValuePtr head;
> virJSONParserStatePtr state;
> size_t nstate;
> + int wrap;
Boolean?
> };
>
>
> @@ -1556,7 +1557,7 @@ virJSONParserHandleEndArray(void *ctx)
>
> VIR_DEBUG("parser=%p", parser);
>
> - if (!parser->nstate)
> + if (!(parser->nstate - parser->wrap))
Yuck! This really covers up what's happening here.
if ((parser->nstate == 1 && parser->wrap) ||
(parser->nstate == 0 && !parser->wrap))
It takes two lines but you at least don't cover up the logic.
> return 0;
>
> state = &(parser->state[parser->nstate-1]);
> @@ -1591,7 +1592,7 @@ virJSONValuePtr
> virJSONValueFromString(const char *jsonstring)
> {
> yajl_handle hand;
> - virJSONParser parser = { NULL, NULL, 0 };
> + virJSONParser parser = { NULL, NULL, 0, 0 };
> virJSONValuePtr ret = NULL;
> int rc;
> size_t len = strlen(jsonstring);
> @@ -1627,8 +1628,10 @@ virJSONValueFromString(const char *jsonstring)
> rc = yajl_parse(hand, (const unsigned char *)jsonstring, len);
> # else
> rc = yajl_parse(hand, (const unsigned char *)"[", 1);
> + parser.wrap = 1;
True?
> if (VIR_YAJL_STATUS_OK(rc))
> rc = yajl_parse(hand, (const unsigned char *)jsonstring, len);
> + parser.wrap = 0;
False?
> if (VIR_YAJL_STATUS_OK(rc))
> rc = yajl_parse(hand, (const unsigned char *)"]", 1);
> # endif
Peter
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20150623/b018cb49/attachment-0001.sig>
More information about the libvir-list
mailing list