Merge commit '607ad990d31e6be52980970e5ce8cd25ab3de812'
authorMichael Niedermayer <michaelni@gmx.at>
Tue, 27 Jan 2015 19:25:40 +0000 (20:25 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Tue, 27 Jan 2015 19:25:40 +0000 (20:25 +0100)
* commit '607ad990d31e6be52980970e5ce8cd25ab3de812':
  dvbsubdec: check memory allocations and propagate errors

Conflicts:
libavcodec/dvbsubdec.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavcodec/dvbsubdec.c

@@@ -1139,12 -969,12 +1140,13 @@@ static int dvbsub_parse_clut_segment(AV
  
          if (depth & 0x80)
              clut->clut4[entry_id] = RGBA(r,g,b,255 - alpha);
 -        if (depth & 0x40)
 +        else if (depth & 0x40)
              clut->clut16[entry_id] = RGBA(r,g,b,255 - alpha);
 -        if (depth & 0x20)
 +        else if (depth & 0x20)
              clut->clut256[entry_id] = RGBA(r,g,b,255 - alpha);
      }
 +    }
      return 0;
  }
  
@@@ -1195,9 -1022,10 +1197,11 @@@ static int dvbsub_parse_region_segment(
          region->buf_size = region->width * region->height;
  
          region->pbuf = av_malloc(region->buf_size);
+         if (!region->pbuf)
+             return AVERROR(ENOMEM);
  
          fill = 1;
 +        region->dirty = 0;
      }
  
      region->depth = 1 << (((*buf++) >> 2) & 7);
  }
  
  static int dvbsub_parse_page_segment(AVCodecContext *avctx,
-                                         const uint8_t *buf, int buf_size, AVSubtitle *sub, int *got_output)
 -                                     const uint8_t *buf, int buf_size)
++                                     const uint8_t *buf, int buf_size, AVSubtitle *sub, int *got_output)
  {
      DVBSubContext *ctx = avctx->priv_data;
      DVBSubRegionDisplay *display;
@@@ -1481,13 -1298,9 +1494,13 @@@ static int dvbsub_parse_display_definit
      display_def->y       = 0;
      display_def->width   = bytestream_get_be16(&buf) + 1;
      display_def->height  = bytestream_get_be16(&buf) + 1;
 +    if (!avctx->width || !avctx->height) {
 +        avctx->width  = display_def->width;
 +        avctx->height = display_def->height;
 +    }
  
      if (buf_size < 13)
-         return 0;
+         return AVERROR_INVALIDDATA;
  
      if (info_byte & 1<<3) { // display_window_flag
          display_def->x = bytestream_get_be16(&buf);
      return 0;
  }
  
- static void dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf,
-                                         int buf_size, AVSubtitle *sub,int *got_output)
+ static int dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf,
 -                                      int buf_size, AVSubtitle *sub)
++                                      int buf_size, AVSubtitle *sub,int *got_output)
  {
      DVBSubContext *ctx = avctx->priv_data;
 -    DVBSubDisplayDefinition *display_def = ctx->display_definition;
 -
 -    DVBSubRegion *region;
 -    DVBSubRegionDisplay *display;
 -    AVSubtitleRect *rect;
 -    DVBSubCLUT *clut;
 -    uint32_t *clut_table;
 -    int i;
 -    int offset_x=0, offset_y=0;
 -
 -    sub->rects = NULL;
 -    sub->start_display_time = 0;
 -    sub->end_display_time = ctx->time_out * 1000;
 -    sub->format = 0;
 -
 -    if (display_def) {
 -        offset_x = display_def->x;
 -        offset_y = display_def->y;
 -    }
 -
 -    sub->num_rects = ctx->display_list_size;
 -    if (sub->num_rects <= 0)
 -        return AVERROR_INVALIDDATA;
 -
 -    sub->rects = av_mallocz_array(sub->num_rects * sub->num_rects,
 -                                  sizeof(*sub->rects));
 -    if (!sub->rects)
 -        return AVERROR(ENOMEM);
 -
 -    i = 0;
 -
 -    for (display = ctx->display_list; display; display = display->next) {
 -        region = get_region(ctx, display->region_id);
 -        rect = sub->rects[i];
 -
 -        if (!region)
 -            continue;
 -
 -        rect->x = display->x_pos + offset_x;
 -        rect->y = display->y_pos + offset_y;
 -        rect->w = region->width;
 -        rect->h = region->height;
 -        rect->nb_colors = 16;
 -        rect->type      = SUBTITLE_BITMAP;
 -        rect->pict.linesize[0] = region->width;
 -
 -        clut = get_clut(ctx, region->clut);
 -
 -        if (!clut)
 -            clut = &default_clut;
 -
 -        switch (region->depth) {
 -        case 2:
 -            clut_table = clut->clut4;
 -            break;
 -        case 8:
 -            clut_table = clut->clut256;
 -            break;
 -        case 4:
 -        default:
 -            clut_table = clut->clut16;
 -            break;
 -        }
 -
 -        rect->pict.data[1] = av_mallocz(AVPALETTE_SIZE);
 -        if (!rect->pict.data[1]) {
 -            av_free(sub->rects);
 -            return AVERROR(ENOMEM);
 -        }
 -        memcpy(rect->pict.data[1], clut_table, (1 << region->depth) * sizeof(uint32_t));
 -
 -        rect->pict.data[0] = av_malloc(region->buf_size);
 -        if (!rect->pict.data[0]) {
 -            av_free(rect->pict.data[1]);
 -            av_free(sub->rects);
 -            return AVERROR(ENOMEM);
 -        }
 -        memcpy(rect->pict.data[0], region->pbuf, region->buf_size);
 -
 -        i++;
 -    }
 -
 -    sub->num_rects = i;
  
 +    if(ctx->compute_edt == 0)
 +        save_subtitle_set(avctx, sub, got_output);
  #ifdef DEBUG
      save_display_set(ctx);
  #endif
--
 -    return 1;
++    return 0;
  }
  
  static int dvbsub_decode(AVCodecContext *avctx,
  
          if (page_id == ctx->composition_id || page_id == ctx->ancillary_id ||
              ctx->composition_id == -1 || ctx->ancillary_id == -1) {
+             int ret = 0;
              switch (segment_type) {
              case DVBSUB_PAGE_SEGMENT:
-                 dvbsub_parse_page_segment(avctx, p, segment_length, sub, data_size);
 -                ret = dvbsub_parse_page_segment(avctx, p, segment_length);
++                ret = dvbsub_parse_page_segment(avctx, p, segment_length, sub, data_size);
 +                got_segment |= 1;
                  break;
              case DVBSUB_REGION_SEGMENT:
-                 dvbsub_parse_region_segment(avctx, p, segment_length);
+                 ret = dvbsub_parse_region_segment(avctx, p, segment_length);
 +                got_segment |= 2;
                  break;
              case DVBSUB_CLUT_SEGMENT:
                  ret = dvbsub_parse_clut_segment(avctx, p, segment_length);
 +                if (ret < 0) goto end;
 +                got_segment |= 4;
                  break;
              case DVBSUB_OBJECT_SEGMENT:
-                 dvbsub_parse_object_segment(avctx, p, segment_length);
+                 ret = dvbsub_parse_object_segment(avctx, p, segment_length);
 +                got_segment |= 8;
                  break;
              case DVBSUB_DISPLAYDEFINITION_SEGMENT:
-                 dvbsub_parse_display_definition_segment(avctx, p, segment_length);
+                 ret = dvbsub_parse_display_definition_segment(avctx, p,
+                                                               segment_length);
                  break;
              case DVBSUB_DISPLAY_SEGMENT:
-                 dvbsub_display_end_segment(avctx, p, segment_length, sub, data_size);
 -                ret = dvbsub_display_end_segment(avctx, p, segment_length, sub);
 -                *data_size = ret;
++                ret = dvbsub_display_end_segment(avctx, p, segment_length, sub, data_size);
 +                got_segment |= 16;
                  break;
              default:
                  av_dlog(avctx, "Subtitling segment type 0x%x, page id %d, length %d\n",
                          segment_type, page_id, segment_length);
                  break;
              }
 -                return ret;
+             if (ret < 0)
++                goto end;
          }
  
          p += segment_length;