Skip to content

Commit

Permalink
tidy: Fix a bunch of null dereference warnings related to MPEG descri…
Browse files Browse the repository at this point in the history
…ptors.

The clang-tidy "null dereference" checker pointed out a bunch of
potential null dereferences in the mpeg descriptor/tables code.  These
are the result of the code creating various objects, and then blindly
dereferencing the _data pointer in those objects (mostly via member
functions).  The problem with those dereferences is that the object
constructor clears the _data pointer if the information passed into
the constructor was too short.  Add a number of tests to check the
validity of the _data pointer before dereferencing it.

This change also tightens up the code to select Australian and Greek
category names from the EIT information, replacing switch statements
with table lookups.
  • Loading branch information
linuxdude42 committed Apr 1, 2019
1 parent 2098739 commit a418d34
Show file tree
Hide file tree
Showing 12 changed files with 144 additions and 124 deletions.
4 changes: 4 additions & 0 deletions mythtv/libs/libmythtv/avformatdecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1900,6 +1900,8 @@ void AvFormatDecoder::ScanATSCCaptionStreams(int av_index)
for (uint j = 0; j < desc_list.size(); j++)
{
const CaptionServiceDescriptor csd(desc_list[j]);
if (!csd.IsValid())
continue;
for (uint k = 0; k < csd.ServicesCount(); k++)
{
int lang = csd.CanonicalLanguageKey(k);
Expand Down Expand Up @@ -2011,6 +2013,8 @@ void AvFormatDecoder::ScanTeletextCaptions(int av_index)
for (uint j = 0; j < desc_list.size(); j++)
{
const TeletextDescriptor td(desc_list[j]);
if (!td.IsValid())
continue;
for (uint k = 0; k < td.StreamCount(); k++)
{
int type = td.TeletextType(k);
Expand Down
33 changes: 22 additions & 11 deletions mythtv/libs/libmythtv/channelscan/channelscan_sm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,8 @@ void ChannelScanSM::HandleBAT(const BouquetAssociationTable *bat)
{
DefaultAuthorityDescriptor authority(def_auth);
ServiceListDescriptor services(serv_list);
if (!authority.IsValid() || !services.IsValid())
continue;

for (uint j = 0; j < services.ServiceCount(); ++j)
{
Expand Down Expand Up @@ -546,6 +548,8 @@ void ChannelScanSM::HandleSDTo(uint tsid, const ServiceDescriptionTable *sdt)
if (def_auth)
{
DefaultAuthorityDescriptor authority(def_auth);
if (!authority.IsValid())
continue;
LOG(VB_CHANSCAN, LOG_INFO, LOC +
QString("found default authority(SDTo) for service %1 %2 %3")
.arg(netid).arg(tsid).arg(serviceId));
Expand Down Expand Up @@ -1137,18 +1141,20 @@ static void update_info(ChannelInsertInfo &info,
if (def_auth)
{
DefaultAuthorityDescriptor authority(def_auth);
LOG(VB_CHANSCAN, LOG_INFO, QString("ChannelScanSM: found default "
"authority(SDT) for service %1 %2 %3")
if (authority.IsValid())
{
LOG(VB_CHANSCAN, LOG_INFO, QString("ChannelScanSM: found default "
"authority(SDT) for service %1 %2 %3")
.arg(info.m_orig_netid).arg(info.m_sdt_tsid).arg(info.m_service_id));
info.m_default_authority = authority.DefaultAuthority();
}
else
{
uint64_t index = (uint64_t)info.m_orig_netid << 32 |
info.m_sdt_tsid << 16 | info.m_service_id;
if (defAuthorities.contains(index))
info.m_default_authority = defAuthorities[index];
info.m_default_authority = authority.DefaultAuthority();
return;
}
}

uint64_t index = (uint64_t)info.m_orig_netid << 32 |
info.m_sdt_tsid << 16 | info.m_service_id;
if (defAuthorities.contains(index))
info.m_default_authority = defAuthorities[index];
}

uint ChannelScanSM::GetCurrentTransportInfo(
Expand Down Expand Up @@ -1258,6 +1264,8 @@ ChannelScanSM::GetChannelList(transport_scan_items_it_t trans_info,
for (uint i = 0; i < descs.size(); ++i)
{
RegistrationDescriptor reg(descs[i]);
if (!reg.IsValid())
continue;
if (reg.FormatIdentifierString() == "CUEI" ||
reg.FormatIdentifierString() == "SCTE")
info.m_could_be_opencable = true;
Expand Down Expand Up @@ -1348,6 +1356,8 @@ ChannelScanSM::GetChannelList(transport_scan_items_it_t trans_info,
if (desc)
{
DVBLogicalChannelDescriptor uklist(desc);
if (!uklist.IsValid())
continue;
for (uint j = 0; j < uklist.ChannelCount(); ++j)
{
ukChanNums[((qlonglong)info.m_orig_netid<<32) |
Expand All @@ -1366,7 +1376,8 @@ ChannelScanSM::GetChannelList(transport_scan_items_it_t trans_info,
if (desc)
{
DVBSimulcastChannelDescriptor scnlist(desc);

if (!scnlist.IsValid())
continue;
for (uint j = 0; j < scnlist.ChannelCount(); ++j)
{
scnChanNums[((qlonglong)info.m_orig_netid<<32) |
Expand Down
137 changes: 52 additions & 85 deletions mythtv/libs/libmythtv/eithelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -298,15 +298,18 @@ static void parse_dvb_event_descriptors(desc_list_t list, FixupValue fix,
if (bestShortEvent)
{
ShortEventDescriptor sed(bestShortEvent);
if (enc)
if (sed.IsValid())
{
title = sed.EventName(enc, enc_len);
subtitle = sed.Text(enc, enc_len);
}
else
{
title = sed.EventName();
subtitle = sed.Text();
if (enc)
{
title = sed.EventName(enc, enc_len);
subtitle = sed.Text(enc, enc_len);
}
else
{
title = sed.EventName();
subtitle = sed.Text();
}
}
}

Expand All @@ -324,11 +327,13 @@ static void parse_dvb_event_descriptors(desc_list_t list, FixupValue fix,
}

ExtendedEventDescriptor eed(bestExtendedEvents[j]);
if (enc)
description += eed.Text(enc, enc_len);
else
description += eed.Text();

if (eed.IsValid())
{
if (enc)
description += eed.Text(enc, enc_len);
else
description += eed.Text();
}
// add items from the decscriptor to the items
items.unite (eed.Items());
}
Expand All @@ -344,6 +349,8 @@ static inline void parse_dvb_component_descriptors(desc_list_t list,
for (uint j = 0; j < components.size(); j++)
{
ComponentDescriptor component(components[j]);
if (!component.IsValid())
continue;
video_properties |= component.VideoProperties();
audio_properties |= component.AudioProperties();
subtitle_type |= component.SubtitleType();
Expand Down Expand Up @@ -417,7 +424,7 @@ void EITHelper::AddEIT(const DVBEventInformationTable *eit)
if (dish_event_name)
{
DishEventNameDescriptor dend(dish_event_name);
if (dend.HasName())
if (dend.IsValid() && dend.HasName())
title = dend.Name(descCompression);

const unsigned char *dish_event_description =
Expand Down Expand Up @@ -534,90 +541,43 @@ void EITHelper::AddEIT(const DVBEventInformationTable *eit)
}
else if (EITFixUp::kFixAUDescription & fix)//AU Freeview assigned genres
{
static const char *AUGenres[] =
{/* 0*/"Unknown", "Movie", "News", "Entertainment",
/* 4*/"Sport", "Children", "Music", "Arts/Culture",
/* 8*/"Current Affairs", "Education", "Infotainment",
/*11*/"Special", "Comedy", "Drama", "Documentary",
/*15*/"Unknown"};
ContentDescriptor content(content_data);
switch (content.Nibble1(0))
if (content.IsValid())
{
case 0x01:
category = "Movie";
break;
case 0x02:
category = "News";
break;
case 0x03:
category = "Entertainment";
break;
case 0x04:
category = "Sport";
break;
case 0x05:
category = "Children";
break;
case 0x06:
category = "Music";
break;
case 0x07:
category = "Arts/Culture";
break;
case 0x08:
category = "Current Affairs";
break;
case 0x09:
category = "Education";
break;
case 0x0A:
category = "Infotainment";
break;
case 0x0B:
category = "Special";
break;
case 0x0C:
category = "Comedy";
break;
case 0x0D:
category = "Drama";
break;
case 0x0E:
category = "Documentary";
break;
default:
category = "";
break;
category = AUGenres[content.Nibble1(0)];
category_type = content.GetMythCategory(0);
}
category_type = content.GetMythCategory(0);
}
else if (EITFixUp::kFixGreekEIT & fix)//Greek
{
static const char *GrGenres[] =
{/* 0*/"Unknown", "Ταινία", "Ενημερωτικό", "Unknown",
/* 4*/"Αθλητικό", "Παιδικό", "Unknown", "Unknown",
/* 8*/"Unknown", "Ντοκιμαντέρ", "Unknown", "Unknown",
/*12*/"Unknown", "Unknown", "Unknown", "Unknown"};
ContentDescriptor content(content_data);
switch (content.Nibble2(0))
if (content.IsValid())
{
case 0x01:
category = "Ταινία"; // confirmed
break;
case 0x02:
category = "Ενημερωτικό"; // confirmed
break;
case 0x04:
category = "Αθλητικό"; // confirmed
break;
case 0x05:
category = "Παιδικό"; // confirmed
break;
case 0x09:
category = "Ντοκιμαντέρ"; // confirmed
break;
default:
category = "";
break;
category = GrGenres[content.Nibble2(0)];
category_type = content.GetMythCategory(2);
}
category_type = content.GetMythCategory(2);
}
else
{
ContentDescriptor content(content_data);
category = content.GetDescription(0);
if (content.IsValid())
{
category = content.GetDescription(0);
#if 0 /* there is no category_type in DVB EIT */
category_type = content.GetMythCategory(0);
category_type = content.GetMythCategory(0);
#endif
}
}
}

Expand All @@ -626,6 +586,8 @@ void EITHelper::AddEIT(const DVBEventInformationTable *eit)
for (uint j = 0; j < contentIds.size(); j++)
{
DVBContentIdentifierDescriptor desc(contentIds[j]);
if (!desc.IsValid())
continue;
for (uint k = 0; k < desc.CRIDCount(); k++)
{
if (desc.ContentEncoding(k) == 0)
Expand Down Expand Up @@ -660,6 +622,8 @@ void EITHelper::AddEIT(const DVBEventInformationTable *eit)
desc_list_t private_data_specifiers = MPEGDescriptor::FindAll(list, DescriptorID::private_data_specifier);
for (uint j = 0; j < private_data_specifiers.size(); j++) {
PrivateDataSpecifierDescriptor desc(private_data_specifiers[j]);
if (!desc.IsValid())
continue;
if (desc.PrivateDataSpecifier() == PrivateDataSpecifierID::UPC1) {
isUPC = true;
}
Expand All @@ -669,7 +633,8 @@ void EITHelper::AddEIT(const DVBEventInformationTable *eit)
desc_list_t subtitles = MPEGDescriptor::FindAll(list, PrivateDescriptorID::upc_event_episode_title);
for (uint j = 0; j < subtitles.size(); j++) {
PrivateUPCCablecomEpisodeTitleDescriptor desc(subtitles[j]);

if (!desc.IsValid())
continue;
subtitle = desc.Text();
}
}
Expand Down Expand Up @@ -731,7 +696,7 @@ void EITHelper::AddEIT(const PremiereContentInformationTable *cit)
{
ContentDescriptor content(content_data);
// fix events without real content data
if (content.Nibble(0)==0x00)
if (content.IsValid() && (content.Nibble(0)==0x00))
{
if(content.UserNibble(0)==0x1)
{
Expand Down Expand Up @@ -767,6 +732,8 @@ void EITHelper::AddEIT(const PremiereContentInformationTable *cit)
for(uint j=0; j< transmissions.size(); j++)
{
PremiereContentTransmissionDescriptor transmission(transmissions[j]);
if (!transmission.IsValid())
continue;
uint networkid = transmission.OriginalNetworkID();
uint tsid = transmission.TSID();
uint serviceid = transmission.ServiceID();
Expand Down
13 changes: 8 additions & 5 deletions mythtv/libs/libmythtv/mpeg/dvbdescriptors.h
Original file line number Diff line number Diff line change
Expand Up @@ -2111,12 +2111,15 @@ class DVBContentIdentifierDescriptor : public MPEGDescriptor

memset ((void *) m_crid, 0, sizeof(m_crid));

while (_data[1] >= position)
if (IsValid())
{
size_t length = _data[position+1];
m_crid[count] = &_data[position];
count++;
position+=length+2;
while (_data[1] >= position)
{
size_t length = _data[position+1];
m_crid[count] = &_data[position];
count++;
position+=length+2;
}
}
m_cridCount = count;
}
Expand Down
8 changes: 6 additions & 2 deletions mythtv/libs/libmythtv/mpeg/dvbtables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,12 @@ QString NetworkInformationTable::NetworkName() const
MPEGDescriptor::Find(parsed, DescriptorID::network_name);

if (desc)
_cached_network_name = NetworkNameDescriptor(desc).Name();
else
{
auto nndesc = NetworkNameDescriptor(desc);
if (nndesc.IsValid())
_cached_network_name = nndesc.Name();
}
if (_cached_network_name.isEmpty())
_cached_network_name = QString("Net ID 0x%1")
.arg(NetworkID(), 0, 16);
}
Expand Down
Loading

0 comments on commit a418d34

Please sign in to comment.