mirror of https://git.ffmpeg.org/ffmpeg.git
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:
parent
cfcd55db16
commit
90fc00a623
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Reference in New Issue