avformat/segment: Avoid duplicating string when parsing frames list

Reviewed-by: Ridley Combs <rcombs@rcombs.me>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
This commit is contained in:
Andreas Rheinhardt
2020-09-06 12:07:39 +02:00
parent 1d090dfa91
commit 3c9382ba26

View File

@@ -524,46 +524,40 @@ end:
static int parse_frames(void *log_ctx, int **frames, int *nb_frames, static int parse_frames(void *log_ctx, int **frames, int *nb_frames,
const char *frames_str) const char *frames_str)
{ {
char *p; const char *p;
int i, ret = 0; int i;
char *frames_str1 = av_strdup(frames_str);
char *saveptr = NULL;
if (!frames_str1)
return AVERROR(ENOMEM);
#define FAIL(err) ret = err; goto end
*nb_frames = 1; *nb_frames = 1;
for (p = frames_str1; *p; p++) for (p = frames_str; *p; p++)
if (*p == ',') if (*p == ',')
(*nb_frames)++; (*nb_frames)++;
*frames = av_malloc_array(*nb_frames, sizeof(**frames)); *frames = av_malloc_array(*nb_frames, sizeof(**frames));
if (!*frames) { if (!*frames) {
av_log(log_ctx, AV_LOG_ERROR, "Could not allocate forced frames array\n"); av_log(log_ctx, AV_LOG_ERROR, "Could not allocate forced frames array\n");
FAIL(AVERROR(ENOMEM)); return AVERROR(ENOMEM);
} }
p = frames_str1; p = frames_str;
for (i = 0; i < *nb_frames; i++) { for (i = 0; i < *nb_frames; i++) {
long int f; long int f;
char *tailptr; char *tailptr;
char *fstr = av_strtok(p, ",", &saveptr);
p = NULL; if (*p == '\0' || *p == ',') {
if (!fstr) {
av_log(log_ctx, AV_LOG_ERROR, "Empty frame specification in frame list %s\n", av_log(log_ctx, AV_LOG_ERROR, "Empty frame specification in frame list %s\n",
frames_str); frames_str);
FAIL(AVERROR(EINVAL)); return AVERROR(EINVAL);
} }
f = strtol(fstr, &tailptr, 10); f = strtol(p, &tailptr, 10);
if (*tailptr || f <= 0 || f >= INT_MAX) { if (*tailptr != '\0' && *tailptr != ',' || f <= 0 || f >= INT_MAX) {
av_log(log_ctx, AV_LOG_ERROR, av_log(log_ctx, AV_LOG_ERROR,
"Invalid argument '%s', must be a positive integer < INT_MAX\n", "Invalid argument '%s', must be a positive integer < INT_MAX\n",
fstr); p);
FAIL(AVERROR(EINVAL)); return AVERROR(EINVAL);
} }
if (*tailptr == ',')
tailptr++;
p = tailptr;
(*frames)[i] = f; (*frames)[i] = f;
/* check on monotonicity */ /* check on monotonicity */
@@ -571,13 +565,11 @@ static int parse_frames(void *log_ctx, int **frames, int *nb_frames,
av_log(log_ctx, AV_LOG_ERROR, av_log(log_ctx, AV_LOG_ERROR,
"Specified frame %d is smaller than the last frame %d\n", "Specified frame %d is smaller than the last frame %d\n",
(*frames)[i], (*frames)[i-1]); (*frames)[i], (*frames)[i-1]);
FAIL(AVERROR(EINVAL)); return AVERROR(EINVAL);
} }
} }
end: return 0;
av_free(frames_str1);
return ret;
} }
static int open_null_ctx(AVIOContext **ctx) static int open_null_ctx(AVIOContext **ctx)