Merge commit '5891fd017aa7bed4c423b8511090cf8641a0afa4' into release/2.4
authorMichael Niedermayer <michaelni@gmx.at>
Sun, 18 Jan 2015 01:14:57 +0000 (02:14 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Sun, 18 Jan 2015 01:15:10 +0000 (02:15 +0100)
* commit '5891fd017aa7bed4c423b8511090cf8641a0afa4':
  dvdsubdec: Do not leak on failure path

Conflicts:
libavcodec/dvdsubdec.c

See: 7fa9f7ef1c2f0cee81ec6ea6a4ff10af4c4fc62c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavcodec/dvdsubdec.c

@@@ -570,99 -499,49 +570,99 @@@ static int dvdsub_decode(AVCodecContex
      return buf_size;
  }
  
 -static av_cold int dvdsub_init(AVCodecContext *avctx)
 +static void parse_palette(DVDSubContext *ctx, char *p)
  {
 -    DVDSubContext *ctx = avctx->priv_data;
 -    char *data, *cur;
 -    int ret = 0;
 +    int i;
 +
 +    ctx->has_palette = 1;
 +    for(i=0;i<16;i++) {
 +        ctx->palette[i] = strtoul(p, &p, 16);
 +        while(*p == ',' || av_isspace(*p))
 +            p++;
 +    }
 +}
 +
 +static int dvdsub_parse_extradata(AVCodecContext *avctx)
 +{
 +    DVDSubContext *ctx = (DVDSubContext*) avctx->priv_data;
 +    char *dataorig, *data;
++    int ret = 1;
  
      if (!avctx->extradata || !avctx->extradata_size)
 -        return 0;
 +        return 1;
  
 -    data = av_malloc(avctx->extradata_size + 1);
 +    dataorig = data = av_malloc(avctx->extradata_size+1);
      if (!data)
          return AVERROR(ENOMEM);
      memcpy(data, avctx->extradata, avctx->extradata_size);
      data[avctx->extradata_size] = '\0';
 -    cur = data;
 -
 -    while (*cur) {
 -        if (strncmp("palette:", cur, 8) == 0) {
 -            int i;
 -            char *p = cur + 8;
 -            ctx->has_palette = 1;
 -            for (i = 0; i < 16; i++) {
 -                ctx->palette[i] = strtoul(p, &p, 16);
 -                while (*p == ',' || av_isspace(*p))
 -                    p++;
 -            }
 -        } else if (!strncmp("size:", cur, 5)) {
 +
 +    for(;;) {
 +        int pos = strcspn(data, "\n\r");
 +        if (pos==0 && *data==0)
 +            break;
 +
 +        if (strncmp("palette:", data, 8) == 0) {
 +            parse_palette(ctx, data + 8);
 +        } else if (strncmp("size:", data, 5) == 0) {
              int w, h;
 -            if (sscanf(cur + 5, "%dx%d", &w, &h) == 2) {
 +            if (sscanf(data + 5, "%dx%d", &w, &h) == 2) {
-                int ret = ff_set_dimensions(avctx, w, h);
-                if (ret < 0) {
-                    av_free(dataorig);
-                    return ret;
-                }
+                ret = ff_set_dimensions(avctx, w, h);
+                if (ret < 0)
+                    goto fail;
              }
          }
 -        cur += strcspn(cur, "\n\r");
 -        cur += strspn(cur, "\n\r");
 +
 +        data += pos;
 +        data += strspn(data, "\n\r");
      }
  
 -    av_free(data);
+ fail:
-     return 1;
 +    av_free(dataorig);
+     return ret;
  }
  
 +static av_cold int dvdsub_init(AVCodecContext *avctx)
 +{
 +    DVDSubContext *ctx = avctx->priv_data;
 +    int ret;
 +
 +    if ((ret = dvdsub_parse_extradata(avctx)) < 0)
 +        return ret;
 +
 +    if (ctx->palette_str)
 +        parse_palette(ctx, ctx->palette_str);
 +    if (ctx->has_palette) {
 +        int i;
 +        av_log(avctx, AV_LOG_DEBUG, "palette:");
 +        for(i=0;i<16;i++)
 +            av_log(avctx, AV_LOG_DEBUG, " 0x%06x", ctx->palette[i]);
 +        av_log(avctx, AV_LOG_DEBUG, "\n");
 +    }
 +
 +    return 1;
 +}
 +
 +static av_cold int dvdsub_close(AVCodecContext *avctx)
 +{
 +    DVDSubContext *ctx = avctx->priv_data;
 +    ctx->buf_size = 0;
 +    return 0;
 +}
 +
 +#define OFFSET(field) offsetof(DVDSubContext, field)
 +#define VD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM
 +static const AVOption options[] = {
 +    { "palette", "set the global palette", OFFSET(palette_str), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, VD },
 +    { NULL }
 +};
 +static const AVClass dvdsub_class = {
 +    .class_name = "dvdsubdec",
 +    .item_name  = av_default_item_name,
 +    .option     = options,
 +    .version    = LIBAVUTIL_VERSION_INT,
 +};
 +
  AVCodec ff_dvdsub_decoder = {
      .name           = "dvdsub",
      .long_name      = NULL_IF_CONFIG_SMALL("DVD subtitles"),