Hi,
while recording the radio channel "Bayern 1" on Astra 19.2E from 0900 to
1000 this morning, I've discoverd that VDR crashed at about 0932.
After debugging the whole afternoon I've recently found the bug that
caused this crash. It's cPesAssembler that drops some data in certain
circumstances. The crash has nothing todo with recording this channel,
but with the transfer mode I'm using with vdr-xine, as it makes use of
cPesAssembler.
BTW: To reproduce this crash just tune to the mentioned channel in
transfer mode and wait for about 33 minutes.
The bug has to do with cPesAssembler's length member, as it conforms to
this equation:
length == 0 || length >=4
It's therefore impossible for cPesAssembler to store any fragments of
less than 4 bytes. But the problem is, that these bytes have modified
it's shift register "tag" which leads to wrong synchronisation on the
next fragment.
For this channel, it seems to happen that cPesAssembler sees data blocks
that end with the sequence 00 00 01. These 3 bytes are stored in
cPesAssembler's "tag" member. But when the next data block arrives,
these bytes are ignored, as "length" is still 0, and further data is
dropped, as it needs to sychronize on the next start code (00 00 01).
When the next fragment is to be stored, it results in "data" beeing
something like that
00 00 01 00 00 01 c0 ...
As a result, the expected length evaluates to 6 bytes, but "length"
containes already more than that (in the above case it was 79). This
finally leads to "Rest" beeing -73 which then causes a crash in memcpy.
The attached patch fixes this issue by introducing a new variable
"hasFragment". It helps to recognize that 1 to 3 bytes are already
stored in cPesAssembler. Feel free to drop this new variable and use
"length" instead. Where length is checked for beeing 0, it should be
checked for beeing < 4 and where "hasFragment" is set to true, "length"
should be set to any value != 0 and < 4.
Bye.
--
Dipl.-Inform. (FH) Reinhard Nissl
mailto:rnissl@gmx.de