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.
This commit is contained in:
Clément Bœsch 2013-09-08 18:02:45 +02:00
parent cfcd55db16
commit 90fc00a623
7 changed files with 24 additions and 10 deletions

View File

@ -63,7 +63,7 @@ static int jacosub_probe(AVProbeData *p)
return AVPROBE_SCORE_EXTENSION + 1; return AVPROBE_SCORE_EXTENSION + 1;
return 0; return 0;
} }
ptr += strcspn(ptr, "\n") + 1; ptr += ff_subtitles_next_line(ptr);
} }
return 0; return 0;
} }

View File

@ -28,6 +28,7 @@
#include "isom.h" #include "isom.h"
#include "matroska.h" #include "matroska.h"
#include "riff.h" #include "riff.h"
#include "subtitles.h"
#include "wv.h" #include "wv.h"
#include "libavutil/avstring.h" #include "libavutil/avstring.h"
@ -1363,7 +1364,7 @@ static int srt_get_duration(uint8_t **buf)
s_hsec += 1000*s_sec; e_hsec += 1000*e_sec; s_hsec += 1000*s_sec; e_hsec += 1000*e_sec;
duration = e_hsec - s_hsec; duration = e_hsec - s_hsec;
} }
*buf += strcspn(*buf, "\n") + 1; *buf += ff_subtitles_next_line(*buf);
} }
return duration; return duration;
} }

View File

@ -47,7 +47,7 @@ static int microdvd_probe(AVProbeData *p)
sscanf(ptr, "{%*d}{%*d}%c", &c) != 1 && sscanf(ptr, "{%*d}{%*d}%c", &c) != 1 &&
sscanf(ptr, "{DEFAULT}{}%c", &c) != 1) sscanf(ptr, "{DEFAULT}{}%c", &c) != 1)
return 0; return 0;
ptr += strcspn(ptr, "\n") + 1; ptr += ff_subtitles_next_line(ptr);
} }
return AVPROBE_SCORE_MAX; return AVPROBE_SCORE_MAX;
} }

View File

@ -43,7 +43,7 @@ static int mpl2_probe(AVProbeData *p)
if (sscanf(ptr, "[%"SCNd64"][%"SCNd64"]%c", &start, &end, &c) != 3 && if (sscanf(ptr, "[%"SCNd64"][%"SCNd64"]%c", &start, &end, &c) != 3 &&
sscanf(ptr, "[%"SCNd64"][]%c", &start, &c) != 2) sscanf(ptr, "[%"SCNd64"][]%c", &start, &c) != 2)
return 0; return 0;
ptr += strcspn(ptr, "\n") + 1; ptr += ff_subtitles_next_line(ptr);
if (ptr >= ptr_end) if (ptr >= ptr_end)
return 0; return 0;
} }

View File

@ -37,11 +37,16 @@ static int mpsub_probe(AVProbeData *p)
const char *ptr_end = p->buf + p->buf_size; const char *ptr_end = p->buf + p->buf_size;
while (ptr < ptr_end) { while (ptr < ptr_end) {
int inc;
if (!memcmp(ptr, "FORMAT=TIME", 11)) if (!memcmp(ptr, "FORMAT=TIME", 11))
return AVPROBE_SCORE_EXTENSION; return AVPROBE_SCORE_EXTENSION;
if (!memcmp(ptr, "FORMAT=", 7)) if (!memcmp(ptr, "FORMAT=", 7))
return AVPROBE_SCORE_EXTENSION / 3; return AVPROBE_SCORE_EXTENSION / 3;
ptr += strcspn(ptr, "\n") + 1; inc = ff_subtitles_next_line(ptr);
if (!inc)
break;
ptr += inc;
} }
return 0; return 0;
} }

View File

@ -44,7 +44,7 @@ static int srt_probe(AVProbeData *p)
&& sscanf(ptr, "%*d:%*2d:%*2d%*1[,.]%*3d --> %*d:%*2d:%*2d%*1[,.]%3d", &v) == 1) && sscanf(ptr, "%*d:%*2d:%*2d%*1[,.]%*3d --> %*d:%*2d:%*2d%*1[,.]%3d", &v) == 1)
return AVPROBE_SCORE_MAX; return AVPROBE_SCORE_MAX;
num = atoi(ptr); num = atoi(ptr);
ptr += strcspn(ptr, "\n") + 1; ptr += ff_subtitles_next_line(ptr);
} }
return 0; return 0;
} }
@ -65,12 +65,10 @@ static int64_t get_pts(const char **buf, int *duration,
int64_t start = (hh1*3600LL + mm1*60LL + ss1) * 1000LL + ms1; int64_t start = (hh1*3600LL + mm1*60LL + ss1) * 1000LL + ms1;
int64_t end = (hh2*3600LL + mm2*60LL + ss2) * 1000LL + ms2; int64_t end = (hh2*3600LL + mm2*60LL + ss2) * 1000LL + ms2;
*duration = end - start; *duration = end - start;
*buf += strcspn(*buf, "\n"); *buf += ff_subtitles_next_line(*buf);
*buf += !!**buf;
return start; return start;
} }
*buf += strcspn(*buf, "\n"); *buf += ff_subtitles_next_line(*buf);
*buf += !!**buf;
} }
return AV_NOPTS_VALUE; return AV_NOPTS_VALUE;
} }

View File

@ -96,4 +96,14 @@ const char *ff_smil_get_attr_ptr(const char *s, const char *attr);
*/ */
void ff_subtitles_read_chunk(AVIOContext *pb, AVBPrint *buf); 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");
return n + !!*ptr;
}
#endif /* AVFORMAT_SUBTITLES_H */ #endif /* AVFORMAT_SUBTITLES_H */