[FFmpeg-cvslog] avformat/subtitles: add a next line jumper and use it.

Clément Bœsch git at videolan.org
Mon Sep 16 21:43:06 CEST 2013


ffmpeg | branch: release/1.2 | Clément Bœsch <u at pkh.me> | Sun Sep  8 18:02:45 2013 +0200| [c09acf9882803fd17762689859032c0866568e27] | committer: Alexander Strasser

avformat/subtitles: add a next line jumper and use it.

This fixes a bunch of possible overread in avformat with the idiom p +=
strcspn(p, "\n") + 1 (strcspn() can focus on the trailing '\0' if no
'\n' is found, so the +1 leads to an overread).

Note on lavf/matroskaenc: no extra subtitles.o Makefile dependency is
added because only the header is required for ff_subtitles_next_line().

Note on lavf/mpsubdec: code gets slightly complex to avoid an infinite
loop in the probing since there is no more forced increment.

NOTE:
Code of function ff_subtitles_next_line fixed by Alexander Strasser.

The original code from master did test the wrong character, but was
corrected by a subsequent commit. That commit however is not backported,
so it had to be fixed in this commit for the backport.

Conflicts:
	libavformat/mpl2dec.c

(cherry picked from commit 90fc00a623de44e137fe1601b91356e8cd8bdd54)

Signed-off-by: Alexander Strasser <eclipse7 at gmx.net>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=c09acf9882803fd17762689859032c0866568e27
---

 libavformat/jacosubdec.c  |    2 +-
 libavformat/matroskaenc.c |    3 ++-
 libavformat/microdvddec.c |    2 +-
 libavformat/mpl2dec.c     |    2 +-
 libavformat/mpsubdec.c    |    6 +++++-
 libavformat/srtdec.c      |    7 ++++---
 libavformat/subtitles.h   |   13 +++++++++++++
 7 files changed, 27 insertions(+), 8 deletions(-)

diff --git a/libavformat/jacosubdec.c b/libavformat/jacosubdec.c
index 89e7e1b..c622dd0 100644
--- a/libavformat/jacosubdec.c
+++ b/libavformat/jacosubdec.c
@@ -63,7 +63,7 @@ static int jacosub_probe(AVProbeData *p)
                 return AVPROBE_SCORE_MAX/2 + 1;
             return 0;
         }
-        ptr += strcspn(ptr, "\n") + 1;
+        ptr += ff_subtitles_next_line(ptr);
     }
     return 0;
 }
diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index e62d534..c506835 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -27,6 +27,7 @@
 #include "avc.h"
 #include "flacenc.h"
 #include "avlanguage.h"
+#include "subtitles.h"
 #include "libavutil/samplefmt.h"
 #include "libavutil/sha.h"
 #include "libavutil/intreadwrite.h"
@@ -1179,7 +1180,7 @@ static int srt_get_duration(uint8_t **buf)
             s_hsec += 1000*s_sec;       e_hsec += 1000*e_sec;
             duration = e_hsec - s_hsec;
         }
-        *buf += strcspn(*buf, "\n") + 1;
+        *buf += ff_subtitles_next_line(*buf);
     }
     return duration;
 }
diff --git a/libavformat/microdvddec.c b/libavformat/microdvddec.c
index 4b42846..5d9b13e 100644
--- a/libavformat/microdvddec.c
+++ b/libavformat/microdvddec.c
@@ -47,7 +47,7 @@ static int microdvd_probe(AVProbeData *p)
             sscanf(ptr, "{%*d}{%*d}%c",  &c) != 1 &&
             sscanf(ptr, "{DEFAULT}{}%c", &c) != 1)
             return 0;
-        ptr += strcspn(ptr, "\n") + 1;
+        ptr += ff_subtitles_next_line(ptr);
     }
     return AVPROBE_SCORE_MAX;
 }
diff --git a/libavformat/mpl2dec.c b/libavformat/mpl2dec.c
index ce2061b..2f708e0 100644
--- a/libavformat/mpl2dec.c
+++ b/libavformat/mpl2dec.c
@@ -43,7 +43,7 @@ static int mpl2_probe(AVProbeData *p)
         if (sscanf(ptr, "[%"PRId64"][%"PRId64"]%c", &start, &end, &c) != 3 &&
             sscanf(ptr, "[%"PRId64"][]%c",          &start,       &c) != 2)
             return 0;
-        ptr += strcspn(ptr, "\r\n") + 1;
+        ptr += ff_subtitles_next_line(ptr);
         if (ptr >= ptr_end)
             return 0;
     }
diff --git a/libavformat/mpsubdec.c b/libavformat/mpsubdec.c
index 2acafaa..360a3d83 100644
--- a/libavformat/mpsubdec.c
+++ b/libavformat/mpsubdec.c
@@ -37,12 +37,16 @@ static int mpsub_probe(AVProbeData *p)
     const char *ptr_end = p->buf + p->buf_size;
 
     while (ptr < ptr_end) {
+        int inc;
         int n;
 
         if (!memcmp(ptr, "FORMAT=TIME", 11) ||
             sscanf(ptr, "FORMAT=%d", &n) == 1)
             return AVPROBE_SCORE_MAX/2;
-        ptr += strcspn(ptr, "\n") + 1;
+        inc = ff_subtitles_next_line(ptr);
+        if (!inc)
+            break;
+        ptr += inc;
     }
     return 0;
 }
diff --git a/libavformat/srtdec.c b/libavformat/srtdec.c
index 6b60052..ba79984 100644
--- a/libavformat/srtdec.c
+++ b/libavformat/srtdec.c
@@ -44,7 +44,7 @@ static int srt_probe(AVProbeData *p)
             && sscanf(ptr, "%*d:%*2d:%*2d%*1[,.]%*3d --> %*d:%*2d:%*2d%*1[,.]%3d", &v) == 1)
             return AVPROBE_SCORE_MAX;
         num = atoi(ptr);
-        ptr += strcspn(ptr, "\n") + 1;
+        ptr += ff_subtitles_next_line(ptr);
     }
     return 0;
 }
@@ -65,10 +65,11 @@ static int64_t get_pts(const char **buf, int *duration,
             int64_t start = (hh1*3600LL + mm1*60LL + ss1) * 1000LL + ms1;
             int64_t end   = (hh2*3600LL + mm2*60LL + ss2) * 1000LL + ms2;
             *duration = end - start;
-            *buf += strcspn(*buf, "\n") + 1;
+            *buf += ff_subtitles_next_line(*buf);
             return start;
         }
-        *buf += strcspn(*buf, "\n") + 1;
+        *buf += ff_subtitles_next_line(*buf);
+
     }
     return AV_NOPTS_VALUE;
 }
diff --git a/libavformat/subtitles.h b/libavformat/subtitles.h
index 455b374..8f68e7b 100644
--- a/libavformat/subtitles.h
+++ b/libavformat/subtitles.h
@@ -96,4 +96,17 @@ const char *ff_smil_get_attr_ptr(const char *s, const char *attr);
  */
 void ff_subtitles_read_chunk(AVIOContext *pb, AVBPrint *buf);
 
+/**
+ * Get the number of characters to increment to jump to the next line, or to
+ * the end of the string.
+ */
+static av_always_inline int ff_subtitles_next_line(const char *ptr)
+{
+    int n = strcspn(ptr, "\n");
+    ptr += n;
+    if (*ptr == '\n')
+        n++;
+    return n;
+}
+
 #endif /* AVFORMAT_SUBTITLES_H */



More information about the ffmpeg-cvslog mailing list