aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClément Bœsch <u@pkh.me>2013-09-08 18:02:45 +0200
committerAlexander Strasser <eclipse7@gmx.net>2013-09-16 21:39:34 +0200
commitc09acf9882803fd17762689859032c0866568e27 (patch)
tree5bbaf9d809b24e74c57a0794149d4d579e36a78f
parenta0779a2ee504e9f38cab91296ba96fa189804f9b (diff)
downloadffmpeg-c09acf9882803fd17762689859032c0866568e27.tar.gz
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@gmx.net>
-rw-r--r--libavformat/jacosubdec.c2
-rw-r--r--libavformat/matroskaenc.c3
-rw-r--r--libavformat/microdvddec.c2
-rw-r--r--libavformat/mpl2dec.c2
-rw-r--r--libavformat/mpsubdec.c6
-rw-r--r--libavformat/srtdec.c7
-rw-r--r--libavformat/subtitles.h13
7 files changed, 27 insertions, 8 deletions
diff --git a/libavformat/jacosubdec.c b/libavformat/jacosubdec.c
index 89e7e1bf54..c622dd04ee 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 e62d5347ca..c506835dfb 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 4b428461cb..5d9b13ee68 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 ce2061bb8b..2f708e0194 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 2acafaa81b..360a3d837f 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 6b60052148..ba799846c1 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 455b374f25..8f68e7bda1 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 */