Commit 675110a6 authored by Yusuke Nakamura's avatar Yusuke Nakamura Committed by Fiona Glaser
Browse files

Fix infinite loop parsing TDecimate Mode 3 timecode v1 files

parent 2ec99b3b
......@@ -101,18 +101,18 @@ static int parse_tcfile( FILE *tcfile_in, timecode_hnd_t *h, video_info_t *info
ret = fscanf( tcfile_in, "# timecode format v%d", &tcfv );
FAIL_IF_ERROR( ret != 1 || (tcfv != 1 && tcfv != 2), "unsupported timecode format\n" )
#define NO_TIMECODE_LINE (buff[0] == '#' || buff[0] == '\n' || buff[0] == '\r')
if( tcfv == 1 )
{
uint64_t file_pos;
double assume_fps, seq_fps;
int start, end;
int start, end = -1;
int prev_start = -1, prev_end = -1;
h->assume_fps = 0;
for( num = 2; fgets( buff, sizeof(buff), tcfile_in ) != NULL; num++ )
{
if( buff[0] == '#' || buff[0] == '\n' || buff[0] == '\r' )
if( NO_TIMECODE_LINE )
continue;
FAIL_IF_ERROR( sscanf( buff, "assume %lf", &h->assume_fps ) != 1 && sscanf( buff, "Assume %lf", &h->assume_fps ) != 1,
"tcfile parsing error: assumed fps not found\n" )
......@@ -124,7 +124,7 @@ static int parse_tcfile( FILE *tcfile_in, timecode_hnd_t *h, video_info_t *info
h->stored_pts_num = 0;
for( seq_num = 0; fgets( buff, sizeof(buff), tcfile_in ) != NULL; num++ )
{
if( buff[0] == '#' || buff[0] == '\n' || buff[0] == '\r' )
if( NO_TIMECODE_LINE )
{
if( sscanf( buff, "# TDecimate Mode 3: Last Frame = %d", &end ) == 1 )
h->stored_pts_num = end + 1;
......@@ -140,7 +140,7 @@ static int parse_tcfile( FILE *tcfile_in, timecode_hnd_t *h, video_info_t *info
++seq_num;
}
if( !h->stored_pts_num )
h->stored_pts_num = end + 1;
h->stored_pts_num = end + 2;
timecodes_num = h->stored_pts_num;
fseek( tcfile_in, file_pos, SEEK_SET );
......@@ -158,10 +158,9 @@ static int parse_tcfile( FILE *tcfile_in, timecode_hnd_t *h, video_info_t *info
if( assume_fps < 0 )
goto fail;
timecodes[0] = 0;
for( num = seq_num = 0; num < timecodes_num - 1; )
for( num = seq_num = 0; num < timecodes_num - 1 && fgets( buff, sizeof(buff), tcfile_in ) != NULL; )
{
fgets( buff, sizeof(buff), tcfile_in );
if( buff[0] == '#' || buff[0] == '\n' || buff[0] == '\r' )
if( NO_TIMECODE_LINE )
continue;
ret = sscanf( buff, "%d,%d,%lf", &start, &end, &seq_fps );
if( ret != 3 )
......@@ -179,6 +178,8 @@ static int parse_tcfile( FILE *tcfile_in, timecode_hnd_t *h, video_info_t *info
timecodes[num + 1] = timecodes[num] + 1 / seq_fps;
}
}
for( ; num < timecodes_num - 1; num++ )
timecodes[num + 1] = timecodes[num] + 1 / assume_fps;
if( h->auto_timebase_den || h->auto_timebase_num )
fpss[seq_num] = h->assume_fps;
......@@ -191,10 +192,9 @@ static int parse_tcfile( FILE *tcfile_in, timecode_hnd_t *h, video_info_t *info
fseek( tcfile_in, file_pos, SEEK_SET );
assume_fps_sig = sigexp10( h->assume_fps, &exponent );
assume_fps = MKV_TIMEBASE_DEN / ( round( MKV_TIMEBASE_DEN / assume_fps_sig ) / exponent );
for( num = 0; num < timecodes_num - 1; )
for( num = 0; num < timecodes_num - 1 && fgets( buff, sizeof(buff), tcfile_in ) != NULL; )
{
fgets( buff, sizeof(buff), tcfile_in );
if( buff[0] == '#' || buff[0] == '\n' || buff[0] == '\r' )
if( NO_TIMECODE_LINE )
continue;
ret = sscanf( buff, "%d,%d,%lf", &start, &end, &seq_fps );
if( ret != 3 )
......@@ -206,6 +206,8 @@ static int parse_tcfile( FILE *tcfile_in, timecode_hnd_t *h, video_info_t *info
for( num = start; num <= end && num < timecodes_num - 1; num++ )
timecodes[num + 1] = timecodes[num] + 1 / seq_fps;
}
for( ; num < timecodes_num - 1; num++ )
timecodes[num + 1] = timecodes[num] + 1 / assume_fps;
}
if( fpss )
{
......@@ -223,7 +225,7 @@ static int parse_tcfile( FILE *tcfile_in, timecode_hnd_t *h, video_info_t *info
h->stored_pts_num = 0;
while( fgets( buff, sizeof(buff), tcfile_in ) != NULL )
{
if( buff[0] == '#' || buff[0] == '\n' || buff[0] == '\r' )
if( NO_TIMECODE_LINE )
{
if( !h->stored_pts_num )
file_pos = ftell( tcfile_in );
......@@ -239,21 +241,24 @@ static int parse_tcfile( FILE *tcfile_in, timecode_hnd_t *h, video_info_t *info
if( !timecodes )
return -1;
fgets( buff, sizeof(buff), tcfile_in );
ret = sscanf( buff, "%lf", &timecodes[0] );
timecodes[0] *= 1e-3; /* Timecode format v2 is expressed in milliseconds. */
FAIL_IF_ERROR( ret != 1, "invalid input tcfile for frame 0\n" )
for( num = 1; num < timecodes_num; )
num = 0;
if( fgets( buff, sizeof(buff), tcfile_in ) != NULL )
{
fgets( buff, sizeof(buff), tcfile_in );
if( buff[0] == '#' || buff[0] == '\n' || buff[0] == '\r' )
continue;
ret = sscanf( buff, "%lf", &timecodes[num] );
timecodes[num] *= 1e-3; /* Timecode format v2 is expressed in milliseconds. */
FAIL_IF_ERROR( ret != 1 || timecodes[num] <= timecodes[num - 1],
"invalid input tcfile for frame %d\n", num )
++num;
ret = sscanf( buff, "%lf", &timecodes[0] );
timecodes[0] *= 1e-3; /* Timecode format v2 is expressed in milliseconds. */
FAIL_IF_ERROR( ret != 1, "invalid input tcfile for frame 0\n" )
for( num = 1; num < timecodes_num && fgets( buff, sizeof(buff), tcfile_in ) != NULL; )
{
if( NO_TIMECODE_LINE )
continue;
ret = sscanf( buff, "%lf", &timecodes[num] );
timecodes[num] *= 1e-3; /* Timecode format v2 is expressed in milliseconds. */
FAIL_IF_ERROR( ret != 1 || timecodes[num] <= timecodes[num - 1],
"invalid input tcfile for frame %d\n", num )
++num;
}
}
FAIL_IF_ERROR( num < timecodes_num, "failed to read input tcfile for frame %d", num )
if( timecodes_num == 1 )
h->timebase_den = info->fps_num;
......@@ -300,7 +305,7 @@ static int parse_tcfile( FILE *tcfile_in, timecode_hnd_t *h, video_info_t *info
h->assume_fps = (double)info->fps_num / info->fps_den;
h->last_timecode = timecodes[timecodes_num - 1];
}
#undef NO_TIMECODE_LINE
if( h->auto_timebase_den || h->auto_timebase_num )
{
uint64_t i = gcd( h->timebase_num, h->timebase_den );
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment