From affa49e62f974f5ed6207730817bc8cc56a09da6 Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Sat, 12 Nov 2005 19:25:13 +0000 Subject: [PATCH] Check for resetting timecodes in the middle of Ogg/OGM files. Fixes Anthill bug #166. --- ChangeLog | 6 +++++- src/input/r_ogm.cpp | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index cda052c51..2049d029a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,11 @@ 2005-11-12 Moritz Bunkus + * mkvmerge: bug fix: Fixed a crash If the granulepos (the + timecodes) reset in the middle of an Ogg/OGM file. Fixes Anthill + bug #166. + * mkvmerge: bug fix: Fixed a division-by-zero error in the - RealMedia demuxer. + RealMedia demuxer. Fixes Anthill bug #161. * mkvmerge: bug fix: Fixed a couple of potential (and actual) segmentation faults by accessing invalid memory addresses. Initial diff --git a/src/input/r_ogm.cpp b/src/input/r_ogm.cpp index cc7c6ec0f..764a56c8a 100644 --- a/src/input/r_ogm.cpp +++ b/src/input/r_ogm.cpp @@ -802,14 +802,26 @@ ogm_reader_c::process_page(ogg_page *og) { ogg_packet op; int duration_len, eos, i; long duration; + bool last_granulepos_set; duration = 0; dmx = find_demuxer(ogg_page_serialno(og)); if ((NULL == dmx) || (-1 == dmx->ptzr)) return; + if ((-1 != ogg_page_granulepos(og)) && + (ogg_page_granulepos(og) < dmx->last_granulepos)) { + mxwarn(FMT_TID "The timecodes for this stream have been reset in the " + "middle of the file. This is not supported. The current packet " + "will be discarded.\n", ti.fname.c_str(), + (int64_t)dmx->serialno); + return; + } + debug_enter("ogm_reader_c::process_page"); + last_granulepos_set = false; + ogg_stream_pagein(&dmx->os, og); while (ogg_stream_packetout(&dmx->os, &op) == 1) { eos = op.e_o_s; @@ -841,6 +853,8 @@ ogm_reader_c::process_page(ogg_page *og) { return; } + last_granulepos_set = true; + continue; } #endif @@ -878,6 +892,8 @@ ogm_reader_c::process_page(ogg_page *og) { return; } + last_granulepos_set = true; + continue; } @@ -933,6 +949,9 @@ ogm_reader_c::process_page(ogg_page *og) { } } + if (!last_granulepos_set) + dmx->last_granulepos = ogg_page_granulepos(og); + debug_leave("ogm_reader_c::process_page"); }