webp: ensure that each transform is only used once

According to the WebP Lossless Bitstream Specification
"each transform is allowed to be used only once".

If a transform is more than once this can lead to memory
corruption.

Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Signed-off-by: Anton Khirnov <anton@khirnov.net>
pull/125/head
Andreas Cadhalpun 10 years ago committed by Anton Khirnov
parent cf18e777ae
commit 30e6abd1a8
  1. 10
      libavcodec/webp.c

@ -1081,7 +1081,7 @@ static int vp8_lossless_decode_frame(AVCodecContext *avctx, AVFrame *p,
unsigned int data_size, int is_alpha_chunk) unsigned int data_size, int is_alpha_chunk)
{ {
WebPContext *s = avctx->priv_data; WebPContext *s = avctx->priv_data;
int w, h, ret, i; int w, h, ret, i, used;
if (!is_alpha_chunk) { if (!is_alpha_chunk) {
s->lossless = 1; s->lossless = 1;
@ -1131,9 +1131,17 @@ static int vp8_lossless_decode_frame(AVCodecContext *avctx, AVFrame *p,
/* parse transformations */ /* parse transformations */
s->nb_transforms = 0; s->nb_transforms = 0;
s->reduced_width = 0; s->reduced_width = 0;
used = 0;
while (get_bits1(&s->gb)) { while (get_bits1(&s->gb)) {
enum TransformType transform = get_bits(&s->gb, 2); enum TransformType transform = get_bits(&s->gb, 2);
s->transforms[s->nb_transforms++] = transform; s->transforms[s->nb_transforms++] = transform;
if (used & (1 << transform)) {
av_log(avctx, AV_LOG_ERROR, "Transform %d used more than once\n",
transform);
ret = AVERROR_INVALIDDATA;
goto free_and_return;
}
used |= (1 << transform);
switch (transform) { switch (transform) {
case PREDICTOR_TRANSFORM: case PREDICTOR_TRANSFORM:
ret = parse_transform_predictor(s); ret = parse_transform_predictor(s);

Loading…
Cancel
Save