summaryrefslogtreecommitdiff
path: root/upb
diff options
context:
space:
mode:
authorJosh Haberman <jhaberman@gmail.com>2015-05-15 09:40:06 -0700
committerJosh Haberman <jhaberman@gmail.com>2015-05-15 09:40:06 -0700
commit37cffddc5d4a9fd9eb7eaff4e1c843d379ad408b (patch)
treed278cdc769ba7e2bd9908d2af81e55d7cfbe847d /upb
parenteace8e32954eb6152e8df06f5a18905c235f0156 (diff)
Decoder bugfix.
Don't back up decoder after skipunknown() unless we actually successfully consumed input data.
Diffstat (limited to 'upb')
-rw-r--r--upb/pb/decoder.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/upb/pb/decoder.c b/upb/pb/decoder.c
index a780666..c37953a 100644
--- a/upb/pb/decoder.c
+++ b/upb/pb/decoder.c
@@ -587,10 +587,17 @@ static int32_t dispatch(upb_pbdecoder *d) {
if (ret == DECODE_ENDGROUP) {
goto_endmsg(d);
return DECODE_OK;
- } else {
- d->pc = d->last - 1; // Rewind to CHECKDELIM.
- return ret;
+ } else if (ret == DECODE_OK) {
+ // We just consumed some input, so we might now have consumed all the data
+ // in the delmited region. Since every opcode that can trigger dispatch is
+ // directly preceded by OP_CHECKDELIM, rewind to it now to re-check the
+ // delimited end.
+ d->pc = d->last - 1;
+ assert(getop(*d->pc) == OP_CHECKDELIM);
+ return DECODE_OK;
}
+
+ return ret;
}
// Callers know that the stack is more than one deep because the opcodes that
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback