From 4280b7c9324b39f6d35a09faeae3d113257b4ad5 Mon Sep 17 00:00:00 2001 From: Adam Sutton Date: Tue, 9 Apr 2013 14:59:22 +0100 Subject: [PATCH] dvb: redo sdt parser to make it more robust Fixes some problems reported in #hts regarding missing services (cherry picked from commit 13fad234d5a6a9325fe6275e35d67ef613895e82) Conflicts: src/dvb/dvb_tables.c --- src/dvb/dvb_tables.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/dvb/dvb_tables.c b/src/dvb/dvb_tables.c index 64ca69fa..83376252 100644 --- a/src/dvb/dvb_tables.c +++ b/src/dvb/dvb_tables.c @@ -334,6 +334,7 @@ dvb_sdt_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len, uint8_t running_status; #endif int l; + uint8_t *dlptr, *dptr; th_dvb_adapter_t *tda = tdmi->tdmi_adapter; @@ -356,6 +357,7 @@ dvb_sdt_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len, if (!tdmi) return -1; } TRACE("sdt", "onid %04X tsid %04X", onid, tsid); + //hexdump("sdt", ptr, len); // version = ptr[2] >> 1 & 0x1f; // section_number = ptr[3]; @@ -370,7 +372,6 @@ dvb_sdt_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len, len -= 8; ptr += 8; - while(len >= 5) { int save = 0; service_id = ptr[0] << 8 | ptr[1]; @@ -380,13 +381,13 @@ dvb_sdt_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len, #endif free_ca_mode = (ptr[3] >> 4) & 0x1; dllen = ((ptr[3] & 0x0f) << 8) | ptr[4]; + dlptr = ptr + 5; TRACE("sdt", " sid %04X running %d free_ca %d", service_id, running_status, free_ca_mode); - len -= 5; - ptr += 5; - - if(dllen > len) + ptr += (5 + dllen); + len -= (5 + dllen); + if (len < 0) break; stype = 0; @@ -394,16 +395,18 @@ dvb_sdt_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len, *crid = 0; while(dllen > 2) { - dtag = ptr[0]; - dlen = ptr[1]; + dtag = dlptr[0]; + dlen = dlptr[1]; + dptr = dlptr + 2; - len -= 2; ptr += 2; dllen -= 2; + dlptr += (2 + dlen); + dllen -= (2 + dlen); - if(dlen > len) break; + if(dllen < 0) break; switch(dtag) { case DVB_DESC_SERVICE: - if(dvb_desc_service(ptr, dlen, &stype, + if(dvb_desc_service(dptr, dlen, &stype, provider, sizeof(provider), chname0, sizeof(chname0)) == 0) { TRACE("sdt", " stype = %d, provider = %s, name = %s", @@ -427,10 +430,9 @@ dvb_sdt_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len, } break; case DVB_DESC_DEF_AUTHORITY: - dvb_desc_def_authority(ptr, dlen, crid, sizeof(crid)); + dvb_desc_def_authority(dptr, dlen, crid, sizeof(crid)); break; } - len -= dlen; ptr += dlen; dllen -= dlen; } if (!servicetype_is_tv(stype) &&