diff options
author | Michael Niedermayer <michael@niedermayer.cc> | 2020-03-22 00:54:58 +0100 |
---|---|---|
committer | Michael Niedermayer <michael@niedermayer.cc> | 2022-09-25 13:51:50 +0200 |
commit | fe87396f35b67f88d4b46fda04de0fd122a411fa (patch) | |
tree | 01668eb2678ec493f9e84593fc0b1a0f8d3c028d | |
parent | 0035e034c0c7c03a07c1504974254bc74275e15c (diff) | |
download | ffmpeg-fe87396f35b67f88d4b46fda04de0fd122a411fa.tar.gz |
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@niedermayer.cc>
-rw-r--r-- | libavformat/subviewerdec.c | 36 |
1 files 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; } |