mirror of https://github.com/xiph/flac
Add more overflow checks to cuesheet parsing
Credit: Oss-Fuzz Issue: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=57315
This commit is contained in:
parent
1faa4924e2
commit
29d1460a38
|
@ -24,6 +24,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include "FLAC/assert.h"
|
||||
#include "share/compat.h"
|
||||
#include "share/grabbag.h"
|
||||
|
@ -43,24 +44,6 @@ void grabbag__cuesheet_frame_to_msf(uint32_t frame, uint32_t *minutes, uint32_t
|
|||
*minutes = frame;
|
||||
}
|
||||
|
||||
/* since we only care about values >= 0 or error, returns < 0 for any illegal string, else value */
|
||||
static int local__parse_int_(const char *s)
|
||||
{
|
||||
int ret = 0;
|
||||
char c;
|
||||
|
||||
if(*s == '\0')
|
||||
return -1;
|
||||
|
||||
while('\0' != (c = *s++))
|
||||
if(c >= '0' && c <= '9')
|
||||
ret = ret * 10 + (c - '0');
|
||||
else
|
||||
return -1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* since we only care about values >= 0 or error, returns < 0 for any illegal string, else value */
|
||||
static FLAC__int64 local__parse_int64_(const char *s)
|
||||
{
|
||||
|
@ -71,14 +54,33 @@ static FLAC__int64 local__parse_int64_(const char *s)
|
|||
return -1;
|
||||
|
||||
while('\0' != (c = *s++))
|
||||
if(c >= '0' && c <= '9')
|
||||
ret = ret * 10 + (c - '0');
|
||||
if(c >= '0' && c <= '9') {
|
||||
if(ret > (INT64_MAX / 10))
|
||||
return false;
|
||||
else if(ret == (INT64_MAX/10)) {
|
||||
FLAC__int64 tmp = ret;
|
||||
ret = ret * 10 + (c - '0');
|
||||
if(ret < tmp)
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
ret = ret * 10 + (c - '0');
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* since we only care about values >= 0 or error, returns < 0 for any illegal string, else value */
|
||||
static int local__parse_int_(const char *s)
|
||||
{
|
||||
FLAC__int64 ret64 = local__parse_int64_(s);
|
||||
if(ret64 < 0 || ret64 > INT_MAX)
|
||||
return -1;
|
||||
return ret64;
|
||||
}
|
||||
|
||||
/* accept minute:second:frame syntax of '[0-9]+:[0-9][0-9]?:[0-9][0-9]?', but max second of 59 and max frame of 74, e.g. 0:0:0, 123:45:67
|
||||
* return sample number or <0 for error
|
||||
* WATCHOUT: if sample rate is not evenly divisible by 75, the resulting sample number will be approximate
|
||||
|
@ -94,12 +96,24 @@ static FLAC__int64 local__parse_msf_(const char *s, uint32_t sample_rate)
|
|||
else
|
||||
return -1;
|
||||
while(':' != (c = *s++)) {
|
||||
if(c >= '0' && c <= '9')
|
||||
field = field * 10 + (c - '0');
|
||||
if(c >= '0' && c <= '9') {
|
||||
if(field > (INT64_MAX / 10))
|
||||
return false;
|
||||
else if(field == (INT64_MAX/10)) {
|
||||
FLAC__int64 tmp = field;
|
||||
field = field * 10 + (c - '0');
|
||||
if(field < tmp)
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
field = field * 10 + (c - '0');
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(field > INT64_MAX / (60 * sample_rate))
|
||||
return -1;
|
||||
ret = field * 60 * sample_rate;
|
||||
|
||||
c = *s++;
|
||||
|
@ -121,7 +135,12 @@ static FLAC__int64 local__parse_msf_(const char *s, uint32_t sample_rate)
|
|||
if(field >= 60)
|
||||
return -1;
|
||||
|
||||
ret += field * sample_rate;
|
||||
{
|
||||
FLAC__int64 tmp = ret;
|
||||
ret += field * sample_rate;
|
||||
if(ret < tmp)
|
||||
return -1;
|
||||
}
|
||||
|
||||
c = *s++;
|
||||
if(c >= '0' && c <= '9')
|
||||
|
@ -143,7 +162,12 @@ static FLAC__int64 local__parse_msf_(const char *s, uint32_t sample_rate)
|
|||
if(field >= 75)
|
||||
return -1;
|
||||
|
||||
ret += field * (sample_rate / 75);
|
||||
{
|
||||
FLAC__int64 tmp = ret;
|
||||
ret += field * (sample_rate / 75);
|
||||
if(ret < tmp)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -164,8 +188,18 @@ static FLAC__int64 local__parse_ms_(const char *s, uint32_t sample_rate)
|
|||
else
|
||||
return -1;
|
||||
while(':' != (c = *s++)) {
|
||||
if(c >= '0' && c <= '9')
|
||||
field = field * 10 + (c - '0');
|
||||
if(c >= '0' && c <= '9') {
|
||||
if(field > (INT64_MAX / 10))
|
||||
return false;
|
||||
else if(field == (INT64_MAX/10)) {
|
||||
FLAC__int64 tmp = field;
|
||||
field = field * 10 + (c - '0');
|
||||
if(field < tmp)
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
field = field * 10 + (c - '0');
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue