summaryrefslogtreecommitdiff
path: root/libsi
diff options
context:
space:
mode:
authorKlaus Schmidinger <vdr@tvdr.de>2004-10-16 10:14:19 +0200
committerKlaus Schmidinger <vdr@tvdr.de>2004-10-16 10:14:19 +0200
commitac13b6e161eb7dac3ff3fb14c50d2bec4187f2d1 (patch)
treecd1bb297d3ca0fae6dfbfb5059d7c8fa84f490c0 /libsi
parent6415cc900de3361925d22f879077be687fce3858 (diff)
downloadvdr-ac13b6e161eb7dac3ff3fb14c50d2bec4187f2d1.tar.gz
vdr-ac13b6e161eb7dac3ff3fb14c50d2bec4187f2d1.tar.bz2
Fixed a possible crash with inconsistent SI data
Diffstat (limited to 'libsi')
-rw-r--r--libsi/descriptor.c14
-rw-r--r--libsi/si.c20
-rw-r--r--libsi/si.h30
-rw-r--r--libsi/util.c6
-rw-r--r--libsi/util.h9
5 files changed, 47 insertions, 32 deletions
diff --git a/libsi/descriptor.c b/libsi/descriptor.c
index eb921c95..207b7c25 100644
--- a/libsi/descriptor.c
+++ b/libsi/descriptor.c
@@ -6,7 +6,7 @@
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
- * $Id: descriptor.c 1.13 2004/06/06 14:47:30 kls Exp $
+ * $Id: descriptor.c 1.14 2004/10/16 09:51:05 kls Exp $
* *
***************************************************************************/
@@ -110,9 +110,7 @@ char *ExtendedEventDescriptors::getText(char *buffer, int size, const char *sepa
continue;
ExtendedEventDescriptor::Item item;
- for (Loop::Iterator it; d->itemLoop.hasNext(it); ) {
- item=d->itemLoop.getNext(it);
-
+ for (Loop::Iterator it; d->itemLoop.getNext(item, it); ) {
if (!separated && size > sepLen2) {
strcpy(buffer+index, separation2); // let's have a separator between the long text and the items
index += sepLen2;
@@ -207,9 +205,7 @@ char *ExtendedEventDescriptors::getTextItemized(char *buffer, int size, const ch
continue;
ExtendedEventDescriptor::Item item;
- for (Loop::Iterator it; d->itemLoop.hasNext(it); ) {
- item=d->itemLoop.getNext(it);
-
+ for (Loop::Iterator it; d->itemLoop.getNext(item, it); ) {
item.itemDescription.getText(buffer+index, size);
len = strlen(buffer+index);
index += len;
@@ -251,9 +247,7 @@ bool ExtendedEventDescriptors::getTextItemized(Loop::Iterator &it, bool &valid,
continue;
ExtendedEventDescriptor::Item item;
- if (d->itemLoop.hasNext(it)) {
- item=d->itemLoop.getNext(it);
-
+ if (d->itemLoop.getNext(item, it)) {
item.item.getText(itemDescription, sizeItemDescription);
item.itemDescription.getText(itemText, sizeItemText);
valid=true;
diff --git a/libsi/si.c b/libsi/si.c
index 40f94539..20ca1b7a 100644
--- a/libsi/si.c
+++ b/libsi/si.c
@@ -6,7 +6,7 @@
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
- * $Id: si.c 1.11 2004/06/06 14:43:56 kls Exp $
+ * $Id: si.c 1.12 2004/10/16 09:54:05 kls Exp $
* *
***************************************************************************/
@@ -30,6 +30,10 @@ void Object::setData(CharArray &d) {
data=d;
}
+bool Object::checkSize(unsigned int offset) {
+ return data.checkSize(offset);
+}
+
Section::Section(const unsigned char *data, bool doCopy) {
setData(data, getLength(data), doCopy);
}
@@ -50,15 +54,15 @@ int Section::getLength(const unsigned char *d) {
return HILO(((const SectionHeader *)d)->section_length)+sizeof(SectionHeader);
}
-bool CRCSection::isValid() {
+bool CRCSection::isCRCValid() {
return CRC32::isValid((const char *)data.getData(), getLength()/*, data.FourBytes(getLength()-4)*/);
}
bool CRCSection::CheckCRCAndParse() {
- if (!isValid())
+ if (!isCRCValid())
return false;
CheckParse();
- return true;
+ return isValid();
}
int NumberedSection::getTableIdExtension() const {
@@ -102,7 +106,7 @@ DescriptorTag Descriptor::getDescriptorTag(const unsigned char *d) {
}
Descriptor *DescriptorLoop::getNext(Iterator &it) {
- if (it.i<getLength()) {
+ if (isValid() && it.i<getLength()) {
return createDescriptor(it.i, true);
}
return 0;
@@ -110,7 +114,7 @@ Descriptor *DescriptorLoop::getNext(Iterator &it) {
Descriptor *DescriptorLoop::getNext(Iterator &it, DescriptorTag tag, bool returnUnimplemetedDescriptor) {
Descriptor *d=0;
- if (it.i<getLength()) {
+ if (isValid() && it.i<getLength()) {
const unsigned char *p=data.getData(it.i);
const unsigned char *end=p+getLength()-it.i;
while (p < end) {
@@ -128,7 +132,7 @@ Descriptor *DescriptorLoop::getNext(Iterator &it, DescriptorTag tag, bool return
Descriptor *DescriptorLoop::getNext(Iterator &it, DescriptorTag *tags, int arrayLength, bool returnUnimplementedDescriptor) {
Descriptor *d=0;
- if (it.i<getLength()) {
+ if (isValid() && it.i<getLength()) {
const unsigned char *p=data.getData(it.i);
const unsigned char *end=p+getLength()-it.i;
while (p < end) {
@@ -147,6 +151,8 @@ Descriptor *DescriptorLoop::getNext(Iterator &it, DescriptorTag *tags, int array
}
Descriptor *DescriptorLoop::createDescriptor(int &i, bool returnUnimplemetedDescriptor) {
+ if (!checkSize(Descriptor::getLength(data.getData(i))))
+ return 0;
Descriptor *d=Descriptor::getDescriptor(data+i, domain, returnUnimplemetedDescriptor);
if (!d)
return 0;
diff --git a/libsi/si.h b/libsi/si.h
index 85d16ed4..8f89c343 100644
--- a/libsi/si.h
+++ b/libsi/si.h
@@ -6,7 +6,7 @@
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
- * $Id: si.h 1.10 2004/06/06 13:35:21 kls Exp $
+ * $Id: si.h 1.11 2004/10/16 09:58:10 kls Exp $
* *
***************************************************************************/
@@ -180,12 +180,17 @@ public:
//can only be called once since data is immutable
void setData(const unsigned char*data, unsigned int size, bool doCopy=true);
CharArray getData() { return data; }
+ //returns the valid flag which indicates if data is all right or errors have been encountered
+ bool isValid() { return data.isValid(); }
virtual int getLength() = 0;
protected:
CharArray data;
//is protected - not used for sections
template <class T> friend class StructureLoop;
void setData(CharArray &d);
+ //returns whether the given offset fits within the limits of the actual data
+ //The valid flag will be set accordingly
+ bool checkSize(unsigned int offset);
};
class Section : public Object {
@@ -205,7 +210,7 @@ public:
//convenience: sets data and parses if doParse
CRCSection(const unsigned char *data, bool doCopy=true) : Section(data, doCopy) {}
CRCSection() {}
- bool isValid();
+ bool isCRCValid();
//convenience: isValid+CheckParse
bool CheckCRCAndParse();
};
@@ -229,9 +234,9 @@ public:
class VariableLengthPart : public Object {
public:
//never forget to call this
- void setData(CharArray d, int l) { Object::setData(d); length=l; }
+ void setData(CharArray d, int l) { Object::setData(d); checkSize(l); length=l; }
//convenience method
- void setDataAndOffset(CharArray d, int l, unsigned int &offset) { Object::setData(d); length=l; offset+=l; }
+ void setDataAndOffset(CharArray d, int l, unsigned int &offset) { Object::setData(d); checkSize(l); length=l; offset+=l; }
virtual int getLength() { return length; }
private:
int length;
@@ -281,29 +286,36 @@ template <class T> class StructureLoop : public Loop {
public:
//currently you must use a while-loop testing for hasNext()
//i must be 0 to get the first descriptor (with the first call)
- T getNext(Iterator &it)
+ bool getNext(T &obj, Iterator &it)
{
+ if (!isValid() || it.i >= getLength())
+ return false;
CharArray d=data;
d.addOffset(it.i);
T ret;
ret.setData(d);
ret.CheckParse();
+ if (!checkSize(ret.getLength()))
+ return false;
it.i+=ret.getLength();
- return ret;
+ obj=ret;
+ return true;
}
T* getNextAsPointer(Iterator &it)
{
- if (getLength() <= it.i)
+ if (!isValid() || it.i >= getLength())
return 0;
CharArray d=data;
d.addOffset(it.i);
T *ret=new T();
ret->setData(d);
ret->CheckParse();
+ if (!checkSize(ret->getLength()))
+ return 0;
it.i+=ret->getLength();
return ret;
}
- bool hasNext(Iterator &it) { return getLength() > it.i; }
+ //bool hasNext(Iterator &it) { return getLength() > it.i; }
};
//contains descriptors of different types
@@ -385,7 +397,7 @@ public:
it.i+=sizeof(T);
return ret;
}
- bool hasNext(Iterator &it) { return getLength() > it.i; }
+ bool hasNext(Iterator &it) { return isValid() && (getLength() > it.i); }
};
class MHP_DescriptorLoop : public DescriptorLoop {
diff --git a/libsi/util.c b/libsi/util.c
index a2a6f0d2..c6ad234a 100644
--- a/libsi/util.c
+++ b/libsi/util.c
@@ -6,7 +6,7 @@
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
- * $Id: util.c 1.3 2003/12/22 14:03:03 kls Exp $
+ * $Id: util.c 1.4 2004/10/16 09:58:41 kls Exp $
* *
***************************************************************************/
@@ -88,9 +88,7 @@ CharArray CharArray::operator+(const unsigned int offset) const {
return f;
}
-CharArray::Data::Data() : count_(1) {
- size=0;
- data=0;
+CharArray::Data::Data() : data(0), size(0), count_(1), valid(true) {
/*
lockingPid = 0;
locked = 0;
diff --git a/libsi/util.h b/libsi/util.h
index db019238..db2a0a17 100644
--- a/libsi/util.h
+++ b/libsi/util.h
@@ -6,7 +6,7 @@
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
- * $Id: util.h 1.3 2003/12/22 14:07:41 kls Exp $
+ * $Id: util.h 1.4 2004/10/16 09:59:48 kls Exp $
* *
***************************************************************************/
@@ -58,6 +58,9 @@ public:
u_int16_t TwoBytes(const unsigned int index) const { return data_->data ? data_->TwoBytes(off+index) : 0; }
u_int32_t FourBytes(const unsigned int index) const { return data_->data ? data_->FourBytes(off+index) : 0; }
+ bool isValid() const { return data_->valid; }
+ bool checkSize(unsigned int offset) { return (data_->valid && (data_->valid=(off+offset < data_->size))); }
+
void addOffset(unsigned int offset) { off+=offset; }
private:
class Data {
@@ -86,10 +89,12 @@ private:
const unsigned char*data;
unsigned int size;
- unsigned count_;
// count_ is the number of CharArray objects that point at this
// count_ must be initialized to 1 by all constructors
// (it starts as 1 since it is pointed to by the CharArray object that created it)
+ unsigned count_;
+
+ bool valid;
/*
pthread_mutex_t mutex;