diff options
author | Josh Haberman <jhaberman@gmail.com> | 2015-05-15 09:40:06 -0700 |
---|---|---|
committer | Josh Haberman <jhaberman@gmail.com> | 2015-05-15 09:40:06 -0700 |
commit | 37cffddc5d4a9fd9eb7eaff4e1c843d379ad408b (patch) | |
tree | d278cdc769ba7e2bd9908d2af81e55d7cfbe847d /upb | |
parent | eace8e32954eb6152e8df06f5a18905c235f0156 (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.c | 13 |
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 |