]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
dvb: redo sdt parser to make it more robust
authorAdam Sutton <dev@adamsutton.me.uk>
Tue, 9 Apr 2013 13:59:22 +0000 (14:59 +0100)
committerAdam Sutton <dev@adamsutton.me.uk>
Wed, 10 Apr 2013 10:42:37 +0000 (11:42 +0100)
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

index 64ca69fa30d0078c4b55fb45983dcb9fd86fac87..8337625288181933e1ab9be86e4e9e07c64b7d1f 100644 (file)
@@ -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) &&