aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Niedermayer <michael@niedermayer.cc>2020-03-22 00:54:58 +0100
committerMichael Niedermayer <michael@niedermayer.cc>2022-08-28 23:07:04 +0200
commitfdc5e2329a5ba12f10c709dc7737c51819a2fa83 (patch)
tree9b9d4b5aa3cca1699acbd7f0605b72d5899eeecb
parent9eb36ab0a1135327982afb8fa6f23e60cf50906c (diff)
downloadffmpeg-fdc5e2329a5ba12f10c709dc7737c51819a2fa83.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.c36
1 files changed, 21 insertions, 15 deletions
diff --git a/libavformat/subviewerdec.c b/libavformat/subviewerdec.c
index e3a950fce3..6ffdc98c39 100644
--- a/libavformat/subviewerdec.c
+++ b/libavformat/subviewerdec.c
@@ -50,26 +50,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;
}