This commit also makes sure the extradata and subtitle_header are NUL terminated, without taking into account the trailing '\0' in account in the size. At the same time, it should fix 'warning: dereferencing type-punned pointer will break strict-aliasing rules' warning for compilers who don't consider uint8_t** and char** compatibles.tags/n1.1
@@ -29,10 +29,11 @@ | |||||
static av_cold int ass_decode_init(AVCodecContext *avctx) | static av_cold int ass_decode_init(AVCodecContext *avctx) | ||||
{ | { | ||||
avctx->subtitle_header = av_malloc(avctx->extradata_size); | |||||
avctx->subtitle_header = av_malloc(avctx->extradata_size + 1); | |||||
if (!avctx->subtitle_header) | if (!avctx->subtitle_header) | ||||
return AVERROR(ENOMEM); | return AVERROR(ENOMEM); | ||||
memcpy(avctx->subtitle_header, avctx->extradata, avctx->extradata_size); | memcpy(avctx->subtitle_header, avctx->extradata, avctx->extradata_size); | ||||
avctx->subtitle_header[avctx->extradata_size] = 0; | |||||
avctx->subtitle_header_size = avctx->extradata_size; | avctx->subtitle_header_size = avctx->extradata_size; | ||||
avctx->priv_data = ff_ass_split(avctx->extradata); | avctx->priv_data = ff_ass_split(avctx->extradata); | ||||
if(!avctx->priv_data) | if(!avctx->priv_data) | ||||
@@ -28,11 +28,12 @@ | |||||
static av_cold int ass_encode_init(AVCodecContext *avctx) | static av_cold int ass_encode_init(AVCodecContext *avctx) | ||||
{ | { | ||||
avctx->extradata = av_malloc(avctx->subtitle_header_size); | |||||
avctx->extradata = av_malloc(avctx->subtitle_header_size + 1); | |||||
if (!avctx->extradata) | if (!avctx->extradata) | ||||
return AVERROR(ENOMEM); | return AVERROR(ENOMEM); | ||||
memcpy(avctx->extradata, avctx->subtitle_header, avctx->subtitle_header_size); | memcpy(avctx->extradata, avctx->subtitle_header, avctx->subtitle_header_size); | ||||
avctx->extradata_size = avctx->subtitle_header_size; | avctx->extradata_size = avctx->subtitle_header_size; | ||||
avctx->extradata[avctx->extradata_size] = 0; | |||||
return 0; | return 0; | ||||
} | } | ||||
@@ -20,6 +20,7 @@ | |||||
*/ | */ | ||||
#include "avcodec.h" | #include "avcodec.h" | ||||
#include "bytestream.h" | #include "bytestream.h" | ||||
#include "internal.h" | |||||
#include "libavutil/avassert.h" | #include "libavutil/avassert.h" | ||||
#include "libavutil/bprint.h" | #include "libavutil/bprint.h" | ||||
#include "libavutil/imgutils.h" | #include "libavutil/imgutils.h" | ||||
@@ -408,9 +409,9 @@ static int dvdsub_init(AVCodecContext *avctx) | |||||
av_bprintf(&extradata, " %06"PRIx32"%c", | av_bprintf(&extradata, " %06"PRIx32"%c", | ||||
dvdc->global_palette[i] & 0xFFFFFF, i < 15 ? ',' : '\n'); | dvdc->global_palette[i] & 0xFFFFFF, i < 15 ? ',' : '\n'); | ||||
if ((ret = av_bprint_finalize(&extradata, (char **)&avctx->extradata)) < 0) | |||||
ret = ff_bprint_to_extradata(avctx, &extradata); | |||||
if (ret < 0) | |||||
return ret; | return ret; | ||||
avctx->extradata_size = extradata.len; | |||||
return 0; | return 0; | ||||
} | } | ||||
@@ -201,4 +201,9 @@ int ff_codec_open2_recursive(AVCodecContext *avctx, const AVCodec *codec, AVDict | |||||
*/ | */ | ||||
int ff_codec_close_recursive(AVCodecContext *avctx); | int ff_codec_close_recursive(AVCodecContext *avctx); | ||||
/** | |||||
* Finalize buf into extradata and set its size appropriately. | |||||
*/ | |||||
int ff_bprint_to_extradata(AVCodecContext *avctx, struct AVBPrint *buf); | |||||
#endif /* AVCODEC_INTERNAL_H */ | #endif /* AVCODEC_INTERNAL_H */ |
@@ -27,6 +27,7 @@ | |||||
#include "libavutil/avassert.h" | #include "libavutil/avassert.h" | ||||
#include "libavutil/avstring.h" | #include "libavutil/avstring.h" | ||||
#include "libavutil/bprint.h" | |||||
#include "libavutil/channel_layout.h" | #include "libavutil/channel_layout.h" | ||||
#include "libavutil/crc.h" | #include "libavutil/crc.h" | ||||
#include "libavutil/mathematics.h" | #include "libavutil/mathematics.h" | ||||
@@ -2684,3 +2685,21 @@ int avcodec_is_open(AVCodecContext *s) | |||||
{ | { | ||||
return !!s->internal; | return !!s->internal; | ||||
} | } | ||||
int ff_bprint_to_extradata(AVCodecContext *avctx, struct AVBPrint *buf) | |||||
{ | |||||
int ret; | |||||
char *str; | |||||
ret = av_bprint_finalize(buf, &str); | |||||
if (ret < 0) | |||||
return ret; | |||||
avctx->extradata = str; | |||||
/* Note: the string is NUL terminated (so extradata can be read as a | |||||
* string), but the ending character is not accounted in the size (in | |||||
* binary formats you are likely not supposed to mux that character). When | |||||
* extradata is copied, it is also padded with FF_INPUT_BUFFER_PADDING_SIZE | |||||
* zeros. */ | |||||
avctx->extradata_size = buf->len; | |||||
return 0; | |||||
} |
@@ -22,6 +22,7 @@ | |||||
#include "avformat.h" | #include "avformat.h" | ||||
#include "internal.h" | #include "internal.h" | ||||
#include "subtitles.h" | #include "subtitles.h" | ||||
#include "libavcodec/internal.h" | |||||
#include "libavutil/bprint.h" | #include "libavutil/bprint.h" | ||||
typedef struct ASSContext{ | typedef struct ASSContext{ | ||||
@@ -132,12 +133,9 @@ static int ass_read_header(AVFormatContext *s) | |||||
av_bprint_finalize(&line, NULL); | av_bprint_finalize(&line, NULL); | ||||
av_bprint_finalize(&header, (char **)&st->codec->extradata); | |||||
if (!st->codec->extradata) { | |||||
res = AVERROR(ENOMEM); | |||||
res = ff_bprint_to_extradata(st->codec, &header); | |||||
if (res < 0) | |||||
goto end; | goto end; | ||||
} | |||||
st->codec->extradata_size = header.len + 1; | |||||
ff_subtitles_queue_finalize(&ass->q); | ff_subtitles_queue_finalize(&ass->q); | ||||
@@ -28,6 +28,7 @@ | |||||
#include "avformat.h" | #include "avformat.h" | ||||
#include "internal.h" | #include "internal.h" | ||||
#include "subtitles.h" | #include "subtitles.h" | ||||
#include "libavcodec/internal.h" | |||||
#include "libavcodec/jacosub.h" | #include "libavcodec/jacosub.h" | ||||
#include "libavutil/avstring.h" | #include "libavutil/avstring.h" | ||||
#include "libavutil/bprint.h" | #include "libavutil/bprint.h" | ||||
@@ -159,7 +160,7 @@ static int jacosub_read_header(AVFormatContext *s) | |||||
JACOsubContext *jacosub = s->priv_data; | JACOsubContext *jacosub = s->priv_data; | ||||
int shift_set = 0; // only the first shift matters | int shift_set = 0; // only the first shift matters | ||||
int merge_line = 0; | int merge_line = 0; | ||||
int i; | |||||
int i, ret; | |||||
AVStream *st = avformat_new_stream(s, NULL); | AVStream *st = avformat_new_stream(s, NULL); | ||||
if (!st) | if (!st) | ||||
@@ -228,8 +229,9 @@ static int jacosub_read_header(AVFormatContext *s) | |||||
} | } | ||||
/* general/essential directives in the extradata */ | /* general/essential directives in the extradata */ | ||||
av_bprint_finalize(&header, (char **)&st->codec->extradata); | |||||
st->codec->extradata_size = header.len + 1; | |||||
ret = ff_bprint_to_extradata(st->codec, &header); | |||||
if (ret < 0) | |||||
return ret; | |||||
/* SHIFT and TIMERES affect the whole script so packet timing can only be | /* SHIFT and TIMERES affect the whole script so packet timing can only be | ||||
* done in a second pass */ | * done in a second pass */ | ||||
@@ -27,6 +27,7 @@ | |||||
#include "avformat.h" | #include "avformat.h" | ||||
#include "internal.h" | #include "internal.h" | ||||
#include "subtitles.h" | #include "subtitles.h" | ||||
#include "libavcodec/internal.h" | |||||
#include "libavutil/avstring.h" | #include "libavutil/avstring.h" | ||||
#include "libavutil/bprint.h" | #include "libavutil/bprint.h" | ||||
#include "libavutil/intreadwrite.h" | #include "libavutil/intreadwrite.h" | ||||
@@ -91,13 +92,9 @@ static int sami_read_header(AVFormatContext *s) | |||||
av_bprint_clear(&buf); | av_bprint_clear(&buf); | ||||
} | } | ||||
st->codec->extradata_size = hdr_buf.len + 1; | |||||
av_bprint_finalize(&hdr_buf, (char **)&st->codec->extradata); | |||||
if (!st->codec->extradata) { | |||||
st->codec->extradata_size = 0; | |||||
res = AVERROR(ENOMEM); | |||||
res = ff_bprint_to_extradata(st->codec, &hdr_buf); | |||||
if (res < 0) | |||||
goto end; | goto end; | ||||
} | |||||
ff_subtitles_queue_finalize(&sami->q); | ff_subtitles_queue_finalize(&sami->q); | ||||
@@ -27,6 +27,7 @@ | |||||
#include "avformat.h" | #include "avformat.h" | ||||
#include "internal.h" | #include "internal.h" | ||||
#include "subtitles.h" | #include "subtitles.h" | ||||
#include "libavcodec/internal.h" | |||||
#include "libavutil/avstring.h" | #include "libavutil/avstring.h" | ||||
#include "libavutil/bprint.h" | #include "libavutil/bprint.h" | ||||
#include "libavutil/intreadwrite.h" | #include "libavutil/intreadwrite.h" | ||||
@@ -99,12 +100,9 @@ static int subviewer_read_header(AVFormatContext *s) | |||||
av_bprintf(&header, "%s", line); | av_bprintf(&header, "%s", line); | ||||
if (!strncmp(line, "[END INFORMATION]", 17) || !strncmp(line, "[SUBTITLE]", 10)) { | if (!strncmp(line, "[END INFORMATION]", 17) || !strncmp(line, "[SUBTITLE]", 10)) { | ||||
/* end of header */ | /* end of header */ | ||||
av_bprint_finalize(&header, (char **)&st->codec->extradata); | |||||
if (!st->codec->extradata) { | |||||
res = AVERROR(ENOMEM); | |||||
res = ff_bprint_to_extradata(st->codec, &header); | |||||
if (res < 0) | |||||
goto end; | goto end; | ||||
} | |||||
st->codec->extradata_size = header.len + 1; | |||||
} else if (strncmp(line, "[INFORMATION]", 13)) { | } else if (strncmp(line, "[INFORMATION]", 13)) { | ||||
/* assume file metadata at this point */ | /* assume file metadata at this point */ | ||||
int i, j = 0; | int i, j = 0; | ||||