summaryrefslogtreecommitdiff
path: root/libavformat/segment.c
diff options
context:
space:
mode:
authorAndreas Rheinhardt <andreas.rheinhardt@gmail.com>2020-09-06 12:34:58 +0200
committerAndreas Rheinhardt <andreas.rheinhardt@gmail.com>2020-09-10 13:43:43 +0200
commit06f99cc4ddbb16f8fd9ae3d72835d542be3dbab2 (patch)
tree11a03c037d1943e2d9bdec8a3229f53aceed5c13 /libavformat/segment.c
parent4b836c86132feb67ca10e383988884dd67bcd19a (diff)
downloadffmpeg-06f99cc4ddbb16f8fd9ae3d72835d542be3dbab2.tar.gz
avformat/segment: Fix segfault on allocation error, avoid allocation
If the user has set none of the options specifying the segments' durations, a default value of 2s is used by duplicating a "2" string and using av_parse_time() on it. Yet duplicating the string was unchecked and if the allocation failed, one would get a segfault in av_parse_time(). This commit solves this by turning said option into an option of type AV_OPT_TYPE_DURATION (which also uses av_parse_time() internally), avoiding duplicating the string altogether. Reviewed-by: Ridley Combs <rcombs@rcombs.me> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
Diffstat (limited to 'libavformat/segment.c')
-rw-r--r--libavformat/segment.c14
1 files changed, 2 insertions, 12 deletions
diff --git a/libavformat/segment.c b/libavformat/segment.c
index 0c96c8c50c..e84dc7a426 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -90,7 +90,6 @@ typedef struct SegmentContext {
char *entry_prefix; ///< prefix to add to list entry filenames
int list_type; ///< set the list type
AVIOContext *list_pb; ///< list file put-byte context
- char *time_str; ///< segment duration specification string
int64_t time; ///< segment duration
int use_strftime; ///< flag to expand filename with strftime
int increment_tc; ///< flag to increment timecode if found
@@ -689,7 +688,7 @@ static int seg_init(AVFormatContext *s)
"you can use output_ts_offset instead of it\n");
}
- if (!!seg->time_str + !!seg->times_str + !!seg->frames_str > 1) {
+ if ((seg->time != 2000000) + !!seg->times_str + !!seg->frames_str > 1) {
av_log(s, AV_LOG_ERROR,
"segment_time, segment_times, and segment_frames options "
"are mutually exclusive, select just one of them\n");
@@ -703,15 +702,6 @@ static int seg_init(AVFormatContext *s)
if ((ret = parse_frames(s, &seg->frames, &seg->nb_frames, seg->frames_str)) < 0)
return ret;
} else {
- /* set default value if not specified */
- if (!seg->time_str)
- seg->time_str = av_strdup("2");
- if ((ret = av_parse_time(&seg->time, seg->time_str, 1)) < 0) {
- av_log(s, AV_LOG_ERROR,
- "Invalid time duration specification '%s' for segment_time option\n",
- seg->time_str);
- return ret;
- }
if (seg->use_clocktime) {
if (seg->time <= 0) {
av_log(s, AV_LOG_ERROR, "Invalid negative segment_time with segment_atclocktime option set\n");
@@ -1051,7 +1041,7 @@ static const AVOption options[] = {
{ "segment_atclocktime", "set segment to be cut at clocktime", OFFSET(use_clocktime), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E},
{ "segment_clocktime_offset", "set segment clocktime offset", OFFSET(clocktime_offset), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, 86400000000LL, E},
{ "segment_clocktime_wrap_duration", "set segment clocktime wrapping duration", OFFSET(clocktime_wrap_duration), AV_OPT_TYPE_DURATION, {.i64 = INT64_MAX}, 0, INT64_MAX, E},
- { "segment_time", "set segment duration", OFFSET(time_str),AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E },
+ { "segment_time", "set segment duration", OFFSET(time),AV_OPT_TYPE_DURATION, {.i64 = 2000000}, INT64_MIN, INT64_MAX, E },
{ "segment_time_delta","set approximation value used for the segment times", OFFSET(time_delta), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, INT64_MAX, E },
{ "segment_times", "set segment split time points", OFFSET(times_str),AV_OPT_TYPE_STRING,{.str = NULL}, 0, 0, E },
{ "segment_frames", "set segment split frame numbers", OFFSET(frames_str),AV_OPT_TYPE_STRING,{.str = NULL}, 0, 0, E },