From ad1352f109a5e20787baf99d31b1723ae200784e Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sat, 8 Mar 2014 15:04:09 +0100 Subject: [PATCH] Fixed a possible endless loop in cH264Parser::GetGolombUe() --- HISTORY | 4 +++- remux.c | 12 +++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/HISTORY b/HISTORY index 6325bd14..bd23bbd4 100644 --- a/HISTORY +++ b/HISTORY @@ -8203,7 +8203,7 @@ Video Disk Recorder Revision History - Fixed detecting broken video data streams when recording. - Fixed handling frame detection buffer length (reported by Eike Sauer). -2014-02-27: Version 2.1.6 +2014-03-08: Version 2.1.6 - Revoked "Fixed some compiler warnings with Clang 3.4.1" from ci.c, because this did not compile with older versions of gcc (thanks to Sören Moch). @@ -8211,3 +8211,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 44eec8ce..fad4f810 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 3.3 2014/02/21 11:51:55 kls Exp $ + * $Id: remux.c 3.4 2014/03/08 15:04:03 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) {