diff --git a/lib/stream.c b/lib/stream.c index 6e62e11380..dc207c16a4 100644 --- a/lib/stream.c +++ b/lib/stream.c @@ -268,6 +268,30 @@ bool stream_forward_getp2(struct stream *s, size_t size) return true; } +void stream_rewind_getp(struct stream *s, size_t size) +{ + STREAM_VERIFY_SANE(s); + + if (size > s->getp || !GETP_VALID(s, s->getp - size)) { + STREAM_BOUND_WARN(s, "rewind getp"); + return; + } + + s->getp -= size; +} + +bool stream_rewind_getp2(struct stream *s, size_t size) +{ + STREAM_VERIFY_SANE(s); + + if (size > s->getp || !GETP_VALID(s, s->getp - size)) + return false; + + s->getp -= size; + + return true; +} + void stream_forward_endp(struct stream *s, size_t size) { STREAM_VERIFY_SANE(s); diff --git a/lib/stream.h b/lib/stream.h index f2c16b3486..e78006fbcc 100644 --- a/lib/stream.h +++ b/lib/stream.h @@ -174,6 +174,8 @@ extern void stream_set_getp(struct stream *, size_t); extern void stream_set_endp(struct stream *, size_t); extern void stream_forward_getp(struct stream *, size_t); extern bool stream_forward_getp2(struct stream *, size_t); +extern void stream_rewind_getp(struct stream *s, size_t size); +extern bool stream_rewind_getp2(struct stream *s, size_t size); extern void stream_forward_endp(struct stream *, size_t); extern bool stream_forward_endp2(struct stream *, size_t); @@ -461,6 +463,12 @@ static inline const uint8_t *ptr_get_be32(const uint8_t *ptr, uint32_t *out) goto stream_failure; \ } while (0) +#define STREAM_REWIND_GETP(STR, SIZE) \ + do { \ + if (!stream_rewind_getp2((STR), (SIZE))) \ + goto stream_failure; \ + } while (0) + #define STREAM_FORWARD_ENDP(STR, SIZE) \ do { \ if (!stream_forward_endp2((STR), (SIZE))) \