diff options
author | Klaus Schmidinger <vdr@tvdr.de> | 2004-10-16 10:14:19 +0200 |
---|---|---|
committer | Klaus Schmidinger <vdr@tvdr.de> | 2004-10-16 10:14:19 +0200 |
commit | ac13b6e161eb7dac3ff3fb14c50d2bec4187f2d1 (patch) | |
tree | cd1bb297d3ca0fae6dfbfb5059d7c8fa84f490c0 /libsi | |
parent | 6415cc900de3361925d22f879077be687fce3858 (diff) | |
download | vdr-ac13b6e161eb7dac3ff3fb14c50d2bec4187f2d1.tar.gz vdr-ac13b6e161eb7dac3ff3fb14c50d2bec4187f2d1.tar.bz2 |
Fixed a possible crash with inconsistent SI data
Diffstat (limited to 'libsi')
-rw-r--r-- | libsi/descriptor.c | 14 | ||||
-rw-r--r-- | libsi/si.c | 20 | ||||
-rw-r--r-- | libsi/si.h | 30 | ||||
-rw-r--r-- | libsi/util.c | 6 | ||||
-rw-r--r-- | libsi/util.h | 9 |
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; @@ -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; @@ -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; |