VDR: dynamically resize buffer for caids

This commit is contained in:
oCanna 2017-05-14 01:02:49 +02:00 committed by cvh
parent 43ea8529e9
commit af7adda9e6

View File

@ -0,0 +1,153 @@
Description: dynamically resize buffer for caids
Forwarded: yes
Author: Lars Hanisch <dvb@flensrocker.de>
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.