You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	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:
		| @@ -63,7 +63,7 @@ static int jacosub_probe(AVProbeData *p) | ||||
|                 return AVPROBE_SCORE_EXTENSION + 1; | ||||
|             return 0; | ||||
|         } | ||||
|         ptr += strcspn(ptr, "\n") + 1; | ||||
|         ptr += ff_subtitles_next_line(ptr); | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
|   | ||||
| @@ -28,6 +28,7 @@ | ||||
| #include "isom.h" | ||||
| #include "matroska.h" | ||||
| #include "riff.h" | ||||
| #include "subtitles.h" | ||||
| #include "wv.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; | ||||
|             duration = e_hsec - s_hsec; | ||||
|         } | ||||
|         *buf += strcspn(*buf, "\n") + 1; | ||||
|         *buf += ff_subtitles_next_line(*buf); | ||||
|     } | ||||
|     return duration; | ||||
| } | ||||
|   | ||||
| @@ -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; | ||||
| } | ||||
|   | ||||
| @@ -43,7 +43,7 @@ static int mpl2_probe(AVProbeData *p) | ||||
|         if (sscanf(ptr, "[%"SCNd64"][%"SCNd64"]%c", &start, &end, &c) != 3 && | ||||
|             sscanf(ptr, "[%"SCNd64"][]%c",          &start,       &c) != 2) | ||||
|             return 0; | ||||
|         ptr += strcspn(ptr, "\n") + 1; | ||||
|         ptr += ff_subtitles_next_line(ptr); | ||||
|         if (ptr >= ptr_end) | ||||
|             return 0; | ||||
|     } | ||||
|   | ||||
| @@ -37,11 +37,16 @@ static int mpsub_probe(AVProbeData *p) | ||||
|     const char *ptr_end = p->buf + p->buf_size; | ||||
|  | ||||
|     while (ptr < ptr_end) { | ||||
|         int inc; | ||||
|  | ||||
|         if (!memcmp(ptr, "FORMAT=TIME", 11)) | ||||
|             return AVPROBE_SCORE_EXTENSION; | ||||
|         if (!memcmp(ptr, "FORMAT=", 7)) | ||||
|             return AVPROBE_SCORE_EXTENSION / 3; | ||||
|         ptr += strcspn(ptr, "\n") + 1; | ||||
|         inc = ff_subtitles_next_line(ptr); | ||||
|         if (!inc) | ||||
|             break; | ||||
|         ptr += inc; | ||||
|     } | ||||
|     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) | ||||
|             return AVPROBE_SCORE_MAX; | ||||
|         num = atoi(ptr); | ||||
|         ptr += strcspn(ptr, "\n") + 1; | ||||
|         ptr += ff_subtitles_next_line(ptr); | ||||
|     } | ||||
|     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 end   = (hh2*3600LL + mm2*60LL + ss2) * 1000LL + ms2; | ||||
|             *duration = end - start; | ||||
|             *buf += strcspn(*buf, "\n"); | ||||
|             *buf += !!**buf; | ||||
|             *buf += ff_subtitles_next_line(*buf); | ||||
|             return start; | ||||
|         } | ||||
|         *buf += strcspn(*buf, "\n"); | ||||
|         *buf += !!**buf; | ||||
|         *buf += ff_subtitles_next_line(*buf); | ||||
|     } | ||||
|     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); | ||||
|  | ||||
| /** | ||||
|  * 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 */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user