diff --git a/HISTORY b/HISTORY index 5dfce4f2..af9d478d 100644 --- a/HISTORY +++ b/HISTORY @@ -7870,7 +7870,7 @@ Video Disk Recorder Revision History and also to use the correct directory with --edit (the latter reported by Marko Mäkelä). -2014-02-27: Version 2.0.6 +2014-03-08: Version 2.0.6 - Updated 'sources.conf' (thanks to Antti Hartikainen). - cFont::CreateFont() now returns a dummy font in case there are no fonts installed. @@ -7900,3 +7900,5 @@ Video Disk Recorder Revision History deleted in a sub folder. - Fixed handling transfer mode on full featured DVB cards for encrypted channels that have no audio pid (reported by Christian Winkler). +- Fixed a possible endless loop in cH264Parser::GetGolombUe(), which caused recordings + on some HD channels to get stuck and resulted in buffer overflows. diff --git a/remux.c b/remux.c index 5906d365..20ea57af 100644 --- a/remux.c +++ b/remux.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: remux.c 2.75.1.3 2014/02/21 14:37:51 kls Exp $ + * $Id: remux.c 2.75.1.4 2014/03/08 15:08:30 kls Exp $ */ #include "remux.h" @@ -272,7 +272,7 @@ uchar cTsPayload::GetByte(void) if (data[index] == TS_SYNC_BYTE && index + TS_SIZE <= length) { // to make sure we are at a TS header start and drop incomplete TS packets at the end uchar *p = data + index; if (TsPid(p) == pid) { // only handle TS packets for the initial PID - if (numPacketsPid++ > MAX_TS_PACKETS_FOR_VIDEO_FRAME_DETECTION) + if (++numPacketsPid > MAX_TS_PACKETS_FOR_VIDEO_FRAME_DETECTION) return SetEof(); if (TsHasPayload(p)) { if (index > 0 && TsPayloadStart(p)) // checking index to not skip the very first TS packet @@ -1252,7 +1252,7 @@ uint32_t cH264Parser::GetBits(int Bits) uint32_t cH264Parser::GetGolombUe(void) { int z = -1; - for (int b = 0; !b; z++) + for (int b = 0; !b && z < 32; z++) // limiting z to no get stuck if GetBit() always returns 0 b = GetBit(); return (1 << z) - 1 + GetBits(z); } @@ -1288,8 +1288,10 @@ int cH264Parser::Parse(const uchar *Data, int Length, int Pid) case nutAccessUnitDelimiter: ParseAccessUnitDelimiter(); gotAccessUnitDelimiter = true; break; - case nutSequenceParameterSet: ParseSequenceParameterSet(); - gotSequenceParameterSet = true; + case nutSequenceParameterSet: if (gotAccessUnitDelimiter) { + ParseSequenceParameterSet(); + gotSequenceParameterSet = true; + } break; case nutCodedSliceNonIdr: case nutCodedSliceIdr: if (gotAccessUnitDelimiter && gotSequenceParameterSet) {