[FFmpeg-cvslog] avformat/subviewerdec: Make read_ts() more flexible
Michael Niedermayer
git at videolan.org
Mon Sep 26 18:13:48 EEST 2022
ffmpeg | branch: release/4.3 | Michael Niedermayer <michael at niedermayer.cc> | Sun Mar 22 00:54:58 2020 +0100| [ace963dd18a51830c54a93f8237599cb5df9f83b] | committer: Michael Niedermayer
avformat/subviewerdec: Make read_ts() more flexible
Fixes: signed integer overflow: -1948269928 * 10 cannot be represented in type 'int'
Fixes: 49451/clusterfuzz-testcase-minimized-ffmpeg_dem_SUBVIEWER_fuzzer-6344614822412288
Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
(cherry picked from commit 58a8e739ef93f8b42f8139e73227508256929d20)
Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=ace963dd18a51830c54a93f8237599cb5df9f83b
---
libavformat/subviewerdec.c | 36 +++++++++++++++++++++---------------
1 file changed, 21 insertions(+), 15 deletions(-)
diff --git a/libavformat/subviewerdec.c b/libavformat/subviewerdec.c
index 5c2fe676f1..0a2f0da3b1 100644
--- a/libavformat/subviewerdec.c
+++ b/libavformat/subviewerdec.c
@@ -51,26 +51,32 @@ static int subviewer_probe(const AVProbeData *p)
return 0;
}
+static int get_multiplier(int e) {
+ switch (e) {
+ case 1 : return 100;
+ case 2 : return 10;
+ case 3 : return 1;
+ default : return -1;
+ }
+}
+
static int read_ts(const char *s, int64_t *start, int *duration)
{
int64_t end;
int hh1, mm1, ss1, ms1;
int hh2, mm2, ss2, ms2;
- int multiplier = 1;
-
- if (sscanf(s, "%u:%u:%u.%2u,%u:%u:%u.%2u",
- &hh1, &mm1, &ss1, &ms1, &hh2, &mm2, &ss2, &ms2) == 8) {
- multiplier = 10;
- } else if (sscanf(s, "%u:%u:%u.%1u,%u:%u:%u.%1u",
- &hh1, &mm1, &ss1, &ms1, &hh2, &mm2, &ss2, &ms2) == 8) {
- multiplier = 100;
- }
- if (sscanf(s, "%u:%u:%u.%u,%u:%u:%u.%u",
- &hh1, &mm1, &ss1, &ms1, &hh2, &mm2, &ss2, &ms2) == 8) {
- ms1 = FFMIN(ms1, 999);
- ms2 = FFMIN(ms2, 999);
- end = (hh2*3600LL + mm2*60LL + ss2) * 1000LL + ms2 * multiplier;
- *start = (hh1*3600LL + mm1*60LL + ss1) * 1000LL + ms1 * multiplier;
+ int multiplier1, multiplier2;
+ int ms1p1, ms1p2, ms2p1, ms2p2;
+
+ if (sscanf(s, "%u:%u:%u.%n%u%n,%u:%u:%u.%n%u%n",
+ &hh1, &mm1, &ss1, &ms1p1, &ms1, &ms1p2, &hh2, &mm2, &ss2, &ms2p1, &ms2, &ms2p2) == 8) {
+ multiplier1 = get_multiplier(ms1p2 - ms1p1);
+ multiplier2 = get_multiplier(ms2p2 - ms2p1);
+ if (multiplier1 <= 0 ||multiplier2 <= 0)
+ return -1;
+
+ end = (hh2*3600LL + mm2*60LL + ss2) * 1000LL + ms2 * multiplier2;
+ *start = (hh1*3600LL + mm1*60LL + ss1) * 1000LL + ms1 * multiplier1;
*duration = end - *start;
return 0;
}
More information about the ffmpeg-cvslog
mailing list