diff --git a/packages/addons/addon-depends/vdr/patches/vdr-40_caid-buffer-v3.patch b/packages/addons/addon-depends/vdr/patches/vdr-40_caid-buffer-v3.patch new file mode 100644 index 0000000000..e695ae0fe8 --- /dev/null +++ b/packages/addons/addon-depends/vdr/patches/vdr-40_caid-buffer-v3.patch @@ -0,0 +1,153 @@ +Description: dynamically resize buffer for caids +Forwarded: yes +Author: Lars Hanisch + +diff --git a/ci.c b/ci.c +index ffc7ff7..8bfae23 100644 +--- a/ci.c ++++ b/ci.c +@@ -25,6 +25,8 @@ + #include "skins.h" + #include "tools.h" + ++#define CAID_BUFSIZE 1024 ++ + // Set these to 'true' for debug output: + static bool DumpTPDUDataTransfer = false; + static bool DebugProtocol = false; +@@ -763,9 +765,12 @@ private: + int transponder; + int programNumber; + int caSystemIds[MAXCASYSTEMIDS + 1]; // list is zero terminated! ++ uint8_t *caDescriptors; ++ int caBufSize; + void AddCaDescriptors(int Length, const uint8_t *Data); + public: + cCiCaPmt(uint8_t CmdId, int Source, int Transponder, int ProgramNumber, const int *CaSystemIds); ++ ~cCiCaPmt(void); + uint8_t CmdId(void) { return cmdId; } + void SetListManagement(uint8_t ListManagement); + uint8_t ListManagement(void) { return capmt[0]; } +@@ -784,8 +789,15 @@ cCiCaPmt::cCiCaPmt(uint8_t CmdId, int Source, int Transponder, int ProgramNumber + caSystemIds[i] = CaSystemIds[i]; + } + caSystemIds[i] = 0; +- uint8_t caDescriptors[512]; +- int caDescriptorsLength = GetCaDescriptors(source, transponder, programNumber, caSystemIds, sizeof(caDescriptors), caDescriptors, 0); ++ caBufSize = CAID_BUFSIZE; ++ caDescriptors = new uint8_t[caBufSize]; ++ int caDescriptorsLength = GetCaDescriptors(source, transponder, programNumber, caSystemIds, caBufSize, caDescriptors, 0); ++ if (caDescriptorsLength < 0) { ++ delete [] caDescriptors; ++ caBufSize = -caDescriptorsLength + 8; ++ caDescriptors = new uint8_t[caBufSize]; ++ caDescriptorsLength = GetCaDescriptors(source, transponder, programNumber, caSystemIds, caBufSize, caDescriptors, 0); ++ } + length = 0; + capmt[length++] = CPLM_ONLY; + capmt[length++] = (ProgramNumber >> 8) & 0xFF; +@@ -797,6 +809,11 @@ cCiCaPmt::cCiCaPmt(uint8_t CmdId, int Source, int Transponder, int ProgramNumber + AddCaDescriptors(caDescriptorsLength, caDescriptors); + } + ++cCiCaPmt::~cCiCaPmt(void) ++{ ++ delete [] caDescriptors; ++} ++ + void cCiCaPmt::SetListManagement(uint8_t ListManagement) + { + capmt[0] = ListManagement; +@@ -805,21 +822,34 @@ void cCiCaPmt::SetListManagement(uint8_t ListManagement) + void cCiCaPmt::AddPid(int Pid, uint8_t StreamType) + { + if (Pid) { +- uint8_t caDescriptors[512]; +- int caDescriptorsLength = GetCaDescriptors(source, transponder, programNumber, caSystemIds, sizeof(caDescriptors), caDescriptors, Pid); +- //XXX buffer overflow check??? +- capmt[length++] = StreamType; +- capmt[length++] = (Pid >> 8) & 0xFF; +- capmt[length++] = Pid & 0xFF; +- esInfoLengthPos = length; +- capmt[length++] = 0x00; // ES_info_length H (at ES level) +- capmt[length++] = 0x00; // ES_info_length L +- AddCaDescriptors(caDescriptorsLength, caDescriptors); ++ int caDescriptorsLength = GetCaDescriptors(source, transponder, programNumber, caSystemIds, caBufSize, caDescriptors, Pid); ++ if (caDescriptorsLength < 0) { ++ delete [] caDescriptors; ++ caBufSize = -caDescriptorsLength + 8; ++ caDescriptors = new uint8_t[caBufSize]; ++ caDescriptorsLength = GetCaDescriptors(source, transponder, programNumber, caSystemIds, caBufSize, caDescriptors, Pid); ++ } ++ if (length + 5 < int(sizeof(capmt))) { ++ capmt[length++] = StreamType; ++ capmt[length++] = (Pid >> 8) & 0xFF; ++ capmt[length++] = Pid & 0xFF; ++ esInfoLengthPos = length; ++ capmt[length++] = 0x00; // ES_info_length H (at ES level) ++ capmt[length++] = 0x00; // ES_info_length L ++ AddCaDescriptors(caDescriptorsLength, caDescriptors); ++ } ++ else ++ esyslog("ERROR: buffer overflow in CA descriptor"); + } + } + + void cCiCaPmt::AddCaDescriptors(int Length, const uint8_t *Data) + { ++ if (Length < 0) { ++ dsyslog("DEBUG: calling AddCaDescriptors with Length %d", Length); ++ return; ++ } ++ + if (esInfoLengthPos) { + if (length + Length < int(sizeof(capmt))) { + if (Length || cmdId == CPCI_QUERY) { +diff --git a/pat.c b/pat.c +index 98d306e..9dfbc62 100644 +--- a/pat.c ++++ b/pat.c +@@ -165,21 +165,25 @@ int cCaDescriptors::GetCaDescriptors(const int *CaSystemIds, int BufSize, uchar + return 0; + if (BufSize > 0 && Data) { + int length = 0; ++ bool tooSmall = false; + for (cCaDescriptor *d = caDescriptors.First(); d; d = caDescriptors.Next(d)) { + if (EsPid < 0 || d->EsPid() == EsPid) { + const int *caids = CaSystemIds; + do { + if (*caids == 0xFFFF || d->CaSystem() == *caids) { +- if (length + d->Length() <= BufSize) { ++ if (length + d->Length() <= BufSize) + memcpy(Data + length, d->Data(), d->Length()); +- length += d->Length(); +- } + else +- return -1; ++ tooSmall = true; ++ length += d->Length(); + } + } while (*++caids); + } + } ++ if (tooSmall) { ++ dsyslog("DEBUG: buffer for ca-descriptors too small (%d, needed %d)", BufSize, length); ++ return -length; ++ } + return length; + } + return -1; +diff --git a/pat.h b/pat.h +index 19e60dc..8bf0738 100644 +--- a/pat.h ++++ b/pat.h +@@ -45,7 +45,7 @@ int GetCaDescriptors(int Source, int Transponder, int ServiceId, const int *CaSy + ///< are copied that match one of the given CA system IDs (or all of them, if CaSystemIds + ///< is 0xFFFF). + ///< Returns the number of bytes copied into Data (0 if no CA descriptors are +- ///< available), or -1 if BufSize was too small to hold all CA descriptors. ++ ///< available), or -(NeededBufSize) if BufSize was too small to hold all CA descriptors. + + int GetCaPids(int Source, int Transponder, int ServiceId, const int *CaSystemIds, int BufSize, int *Pids); + ///< Gets all CA pids for a given channel. +