Merge commit 'f4a8a0080537484154bb74e08ec76cbcbd25484b'
authorMichael Niedermayer <michaelni@gmx.at>
Mon, 6 Jan 2014 13:40:26 +0000 (14:40 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Mon, 6 Jan 2014 13:43:04 +0000 (14:43 +0100)
* commit 'f4a8a0080537484154bb74e08ec76cbcbd25484b':
  sgidec: fix buffer size check in expand_rle_row()

Conflicts:
libavcodec/sgidec.c

See: 39c56ef9216c508a2c19cef93600e6590b4595cd
Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavcodec/sgidec.c

@@@ -39,17 -39,17 +40,18 @@@ typedef struct SgiState 
   * Expand an RLE row into a channel.
   * @param s the current image state
   * @param out_buf Points to one line after the output buffer.
-  * @param out_end end of line in output buffer
+  * @param len length of out_buf in bytes
   * @param pixelstride pixel stride of input buffer
 - * @return size of output in bytes, -1 if buffer overflows
 + * @return size of output in bytes, else return error code.
   */
  static int expand_rle_row(SgiState *s, uint8_t *out_buf,
-                           uint8_t *out_end, int pixelstride)
+                           int len, int pixelstride)
  {
      unsigned char pixel, count;
      unsigned char *orig = out_buf;
++    uint8_t *out_end = out_buf + len;
  
 -    while (1) {
 +    while (out_buf < out_end) {
          if (bytestream2_get_bytes_left(&s->g) < 1)
              return AVERROR_INVALIDDATA;
          pixel = bytestream2_get_byteu(&s->g);
          }
  
          /* Check for buffer overflow. */
-         if (out_end - out_buf <= pixelstride * (count - 1))
 -        if (pixelstride * (count - 1) >= len) {
++        if (out_end - out_buf <= pixelstride * (count - 1)) {
+             av_log(s->avctx, AV_LOG_ERROR, "Invalid pixel count.\n");
              return AVERROR_INVALIDDATA;
+         }
  
          if (pixel & 0x80) {
              while (count--) {
@@@ -103,7 -104,7 +107,7 @@@ static int read_rle_sgi(uint8_t *out_bu
              dest_row -= s->linesize;
              start_offset = bytestream2_get_be32(&g_table);
              bytestream2_seek(&s->g, start_offset, SEEK_SET);
-             if (expand_rle_row(s, dest_row + z, dest_row + s->width*s->depth,
 -            if (expand_rle_row(s, dest_row + z, FFABS(s->linesize) - z,
++            if (expand_rle_row(s, dest_row + z, s->width*s->depth,
                                 s->depth) != s->width) {
                  return AVERROR_INVALIDDATA;
              }
@@@ -222,15 -226,26 +226,24 @@@ static int decode_frame(AVCodecContext 
      if (rle) {
          ret = read_rle_sgi(out_end, s);
      } else {
 -        ret = read_uncompressed_sgi(out_buf, out_end, s);
 +        ret = read_uncompressed_sgi(out_buf, s);
      }
 -
 -    if (ret == 0) {
 -        *got_frame = 1;
 -        return avpkt->size;
 -    } else {
 +    if (ret)
          return ret;
 -    }
 +
 +    *got_frame = 1;
 +    return avpkt->size;
  }
  
+ static av_cold int sgi_decode_init(AVCodecContext *avctx)
+ {
+     SgiState *s = avctx->priv_data;
+     s->avctx = avctx;
+     return 0;
+ }
  AVCodec ff_sgi_decoder = {
      .name           = "sgi",
      .long_name      = NULL_IF_CONFIG_SMALL("SGI image"),