diff mbox series

[FFmpeg-devel,10/10] avformat/segment: Avoid duplicating string when parsing frames list

Message ID 20200907024952.11697-10-andreas.rheinhardt@gmail.com
State Superseded
Headers show
Series [FFmpeg-devel,01/10] avformat/segment: Don't overwrite AVCodecParameters after init | expand

Checks

Context Check Description
andriy/default pending
andriy/make success Make finished
andriy/make_fate success Make fate finished

Commit Message

Andreas Rheinhardt Sept. 7, 2020, 2:49 a.m. UTC
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
---
The first check in the loop could be removed btw; its only advantage is
a better error message.

 libavformat/segment.c | 38 ++++++++++++++------------------------
 1 file changed, 14 insertions(+), 24 deletions(-)
diff mbox series

Patch

diff --git a/libavformat/segment.c b/libavformat/segment.c
index 3dcbda6957..38fca253a2 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -525,46 +525,38 @@  end:
 static int parse_frames(void *log_ctx, int **frames, int *nb_frames,
                         const char *frames_str)
 {
-    char *p;
-    int i, ret = 0;
-    char *frames_str1 = av_strdup(frames_str);
-    char *saveptr = NULL;
-
-    if (!frames_str1)
-        return AVERROR(ENOMEM);
-
-#define FAIL(err) ret = err; goto end
+    const char *p;
+    int i;
 
     *nb_frames = 1;
-    for (p = frames_str1; *p; p++)
+    for (p = frames_str; *p; p++)
         if (*p == ',')
             (*nb_frames)++;
 
     *frames = av_malloc_array(*nb_frames, sizeof(**frames));
     if (!*frames) {
         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++) {
         long int f;
         char *tailptr;
-        char *fstr = av_strtok(p, ",", &saveptr);
 
-        p = NULL;
-        if (!fstr) {
+        if (*p == '\0' || *p == ',') {
             av_log(log_ctx, AV_LOG_ERROR, "Empty frame specification in frame list %s\n",
                    frames_str);
-            FAIL(AVERROR(EINVAL));
+            return AVERROR(EINVAL);
         }
-        f = strtol(fstr, &tailptr, 10);
-        if (*tailptr || f <= 0 || f >= INT_MAX) {
+        f = strtol(p, &tailptr, 10);
+        if (*tailptr != '\0' && *tailptr != ',' || f <= 0 || f >= INT_MAX) {
             av_log(log_ctx, AV_LOG_ERROR,
                    "Invalid argument '%s', must be a positive integer < INT_MAX\n",
-                   fstr);
-            FAIL(AVERROR(EINVAL));
+                   p);
+            return AVERROR(EINVAL);
         }
+        p = tailptr + 1; /* Might point one past '\0' */
         (*frames)[i] = f;
 
         /* check on monotonicity */
@@ -572,13 +564,11 @@  static int parse_frames(void *log_ctx, int **frames, int *nb_frames,
             av_log(log_ctx, AV_LOG_ERROR,
                    "Specified frame %d is smaller than the last frame %d\n",
                    (*frames)[i], (*frames)[i-1]);
-            FAIL(AVERROR(EINVAL));
+            return AVERROR(EINVAL);
         }
     }
 
-end:
-    av_free(frames_str1);
-    return ret;
+    return 0;
 }
 
 static int open_null_ctx(AVIOContext **ctx)