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@xxxxxxxxxx> > --- > > 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
Attachment:
signature.asc
Description: Digital signature
-- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list