From 90101548ec43fd50ddc143eb0cbe99bdd0b47c6f Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Mon, 2 Nov 2020 14:02:01 +0100 Subject: Improve FIG0/13, add 0/7, avoid int overflows --- src/dabplussnoop.cpp | 2 +- src/ensembledatabase.cpp | 2 +- src/etianalyse.cpp | 18 ++++++++---------- src/fig0_0.cpp | 2 +- src/fig0_13.cpp | 46 +++++++++++++++++++++++++--------------------- src/fig0_2.cpp | 14 +++++--------- src/fig1.cpp | 32 +++++++++----------------------- src/fig2.cpp | 27 ++++++++------------------- src/figs.cpp | 1 + src/figs.hpp | 1 + src/utils.cpp | 12 ++++++++++++ src/utils.hpp | 2 ++ 12 files changed, 74 insertions(+), 85 deletions(-) (limited to 'src') diff --git a/src/dabplussnoop.cpp b/src/dabplussnoop.cpp index f6bb8ac..2f28982 100644 --- a/src/dabplussnoop.cpp +++ b/src/dabplussnoop.cpp @@ -149,7 +149,7 @@ bool DabPlusSnoop::decode() m_ps_flag = (audio_params & 0x08) ? true : false; m_mpeg_surround_config = (audio_params & 0x07); - int num_aus; + int num_aus = 0; if (!m_dac_rate && m_sbr_flag) num_aus = 2; // AAC core sampling rate 16 kHz else if (m_dac_rate && m_sbr_flag) num_aus = 3; diff --git a/src/ensembledatabase.cpp b/src/ensembledatabase.cpp index 735aca3..550fdf0 100644 --- a/src/ensembledatabase.cpp +++ b/src/ensembledatabase.cpp @@ -46,7 +46,7 @@ static string ucs2toutf8(const uint8_t *ucs2, size_t len_bytes) wstring ucs2label; for (size_t i = 0; i < len_bytes-1; i+=2) { - ucs2label += (wchar_t)(ucs2[i] * 256 + ucs2[i+1]); + ucs2label += (wchar_t)(ucs2[i] * 256uL + ucs2[i+1]); } // Can throw range_error diff --git a/src/etianalyse.cpp b/src/etianalyse.cpp index 69f4cf7..d84a4f1 100644 --- a/src/etianalyse.cpp +++ b/src/etianalyse.cpp @@ -282,7 +282,7 @@ void ETI_Analyser::eti_analyse() } // LIDATA - FC - FL - fl = (p[6] & 0x07) * 256 + p[7]; + fl = (p[6] & 0x07) * 256uL + p[7]; { printbuf("FL", 2, nullptr, 0, "Frame Length in words", to_string(fl)); } @@ -306,7 +306,7 @@ void ETI_Analyser::eti_analyse() scid = (p[8 + 4*i] & 0xFC) >> 2; printvalue("SCID", 3, "Sub-channel Identifier", to_string(scid)); - sad[i] = (p[8+4*i] & 0x03) * 256 + p[9+4*i]; + sad[i] = (p[8+4*i] & 0x03) * 256uL + p[9+4*i]; printvalue("SAD", 3, "Sub-channel Start Address", to_string(sad[i])); tpl = (p[10+4*i] & 0xFC) >> 2; @@ -384,7 +384,7 @@ void ETI_Analyser::eti_analyse() printvalue("Table switch", 5, "", to_string(tsw)); printvalue("Index", 5, "", to_string(uepidx)); } - stl[i] = (p[10+4*i] & 0x03) * 256 + \ + stl[i] = (p[10+4*i] & 0x03) * 256uL + p[11+4*i]; printvalue("STL", 3, "Sub-channel Stream Length", to_string(stl[i])); printvalue("bitrate", 3, "kbit/s", to_string(stl[i]*8/3)); @@ -405,10 +405,10 @@ void ETI_Analyser::eti_analyse() // EOH printbuf("EOH", 1, p + 8 + 4*nst, 4, "End Of Header"); - uint16_t mnsc = p[8 + 4*nst] * 256 + p[8 + 4*nst + 1]; + uint16_t mnsc = read_u16_from_buf(p + (8 + 4*nst)); printbuf("MNSC", 2, p+8+4*nst, 2, "Multiplex Network Signalling Channel", strprintf("%04x", mnsc)); - crch = p[8 + 4*nst + 2]*256 + p[8 + 4*nst + 3]; + crch = read_u16_from_buf(p + (8 + 4*nst + 2)); crc = 0xffff; for (int i=4; i < 8 + 4*nst + 2; i++) { @@ -444,7 +444,7 @@ void ETI_Analyser::eti_analyse() figs.set_fib(i); rate_new_fib(i); - const uint16_t figcrc = fib[30]*256 + fib[31]; + const uint16_t figcrc = read_u16_from_buf(fib + 30); crc = 0xffff; for (int j = 0; j < 30; j++) { crc = update_crc_ccitt(crc, fib[j]); @@ -515,9 +515,7 @@ void ETI_Analyser::eti_analyse() printbuf("EOF", 1, p + 12 + 4*nst + ficf*ficl*4 + offset, 4); // CRC (2 Bytes) - crch = p[12 + 4*nst + ficf*ficl*4 + offset] * 256 + \ - p[12 + 4*nst + ficf*ficl*4 + offset + 1]; - + crch = read_u16_from_buf(p + (12 + 4*nst + ficf*ficl*4 + offset)); crc = 0xffff; for (int i = 12 + 4*nst; i < 12 + 4*nst + ficf*ficl*4 + offset; i++) { @@ -685,7 +683,7 @@ void ETI_Analyser::fic_analyse() figs.set_fib(i); rate_new_fib(i); - const uint16_t figcrc = fib[30]*256 + fib[31]; + const uint16_t figcrc = read_u16_from_buf(fib + 30); uint16_t crc = 0xffff; for (int j = 0; j < 30; j++) { crc = update_crc_ccitt(crc, fib[j]); diff --git a/src/fig0_0.cpp b/src/fig0_0.cpp index 96724f1..6f60c3b 100644 --- a/src/fig0_0.cpp +++ b/src/fig0_0.cpp @@ -35,7 +35,7 @@ fig_result_t fig0_0(fig0_common_t& fig0, const display_settings_t &disp) fig_result_t r; uint8_t* f = fig0.f; - const uint16_t eid = f[1]*256+f[2]; + const uint16_t eid = read_u16_from_buf(f + 1); r.msgs.push_back(strprintf("Ensemble ID=0x%02x", eid)); if (fig0.fibcrccorrect) { fig0.ensemble.EId = eid; diff --git a/src/fig0_13.cpp b/src/fig0_13.cpp index 9a715af..9b8c2c0 100644 --- a/src/fig0_13.cpp +++ b/src/fig0_13.cpp @@ -125,33 +125,37 @@ fig_result_t fig0_13(fig0_common_t& fig0, const display_settings_t &disp) r.msgs.emplace_back(2, strprintf("length=%u", user_app_len)); if (user_app_len >= 2) { - bool ca_flag = (f[k] >> 7) & 0x1; - r.msgs.emplace_back(2, strprintf("CAflag=%d", ca_flag)); + size_t effective_uadata_len = user_app_len; - bool ca_org_flag = (f[k] >> 6) & 0x1; - r.msgs.emplace_back(2, strprintf("CAOrgflag=%d", ca_org_flag)); + if (fig0.pd() == 0) { // Programme services contain the X-PAD data field + bool ca_flag = (f[k] >> 7) & 0x1; + r.msgs.emplace_back(2, strprintf("CAflag=%d", ca_flag)); - uint8_t xpad_appty = f[k] & 0x1F; - r.msgs.emplace_back(2, strprintf("XPAD_AppTy=%d", xpad_appty)); + bool ca_org_flag = (f[k] >> 6) & 0x1; + r.msgs.emplace_back(2, strprintf("CAOrgflag=%d", ca_org_flag)); - bool dg_flag = (f[k+1] >> 7) & 0x1; - r.msgs.emplace_back(2, strprintf("DGflag=%d", dg_flag)); + uint8_t xpad_appty = f[k] & 0x1F; + r.msgs.emplace_back(2, strprintf("XPAD_AppTy=%d", xpad_appty)); - uint8_t dscty = f[k+1] & 0x3F; - r.msgs.emplace_back(2, strprintf("DSCTy=%d", dscty)); + bool dg_flag = (f[k+1] >> 7) & 0x1; + r.msgs.emplace_back(2, strprintf("DGflag=%d", dg_flag)); - k += 2; - size_t effective_uadata_len = user_app_len - 2; + uint8_t dscty = f[k+1] & 0x3F; + r.msgs.emplace_back(2, strprintf("DSCTy=%d", dscty)); - if (ca_org_flag) { - if (user_app_len < 4) { - r.errors.push_back("User Application Data Length too short to contain CAOrg!"); - } - else { - uint16_t ca_org = (f[k] << 8) | f[k+1]; - k += 2; - effective_uadata_len -= 2; - r.msgs.emplace_back(2, strprintf("ca_org=%u", ca_org)); + k += 2; + effective_uadata_len -= 2; + + if (ca_org_flag) { + if (user_app_len < 4) { + r.errors.push_back("User Application Data Length too short to contain CAOrg!"); + } + else { + uint16_t ca_org = (f[k] << 8) | f[k+1]; + k += 2; + effective_uadata_len -= 2; + r.msgs.emplace_back(2, strprintf("ca_org=%u", ca_org)); + } } } diff --git a/src/fig0_2.cpp b/src/fig0_2.cpp index 102b74f..6d309c9 100644 --- a/src/fig0_2.cpp +++ b/src/fig0_2.cpp @@ -59,22 +59,18 @@ fig_result_t fig0_2(fig0_common_t& fig0, const display_settings_t &disp) while (k < fig0.figlen) { if (fig0.pd() == 0) { - sid = f[k] * 256 + f[k+1]; + sid = read_u16_from_buf(f + k); ecc = 0; cid = (f[k] & 0xF0) >> 4; - sref = (f[k] & 0x0F) * 256 + f[k+1]; + sref = (f[k] & 0x0F) * 256uL + f[k+1]; k += 2; } else { - sid = f[k] * 256 * 256 * 256 + \ - f[k+1] * 256 * 256 + \ - f[k+2] * 256 + \ - f[k+3]; - + sid = read_u32_from_buf(f + k); ecc = f[k]; cid = (f[k+1] & 0xF0) >> 4; - sref = (f[k+1] & 0x0F) * 256 * 256 + \ - f[k+2] * 256 + \ + sref = (f[k+1] & 0x0F) * 256uL * 256uL + + f[k+2] * 256uL + f[k+3]; k += 4; diff --git a/src/fig1.cpp b/src/fig1.cpp index bcabf94..d3d4017 100644 --- a/src/fig1.cpp +++ b/src/fig1.cpp @@ -53,7 +53,7 @@ fig_result_t fig1_select(fig1_common_t& fig1, const display_settings_t &disp) { vector label(16); fig_result_t r; - uint8_t* f = fig1.f; + uint8_t *f = fig1.f; uint8_t charset = (f[0] & 0xF0) >> 4; //oe = (f[0] & 0x08) >> 3; @@ -61,14 +61,12 @@ fig_result_t fig1_select(fig1_common_t& fig1, const display_settings_t &disp) r.msgs.push_back(strprintf("Charset=%d", charset)); memcpy(label.data(), f+fig1.figlen-18, 16); - uint16_t flag = f[fig1.figlen-2] * 256 + \ - f[fig1.figlen-1]; + uint16_t flag = read_u16_from_buf(f + (fig1.figlen-2)); switch (ext) { case 0: // FIG 1/0 Ensemble label { // ETSI EN 300 401 8.1.13 - uint16_t eid; - eid = f[1] * 256 + f[2]; + uint16_t eid = read_u16_from_buf(f + 1); r.msgs.push_back(strprintf("Ensemble ID=0x%04X", eid)); if (fig1.fibcrccorrect) { @@ -86,8 +84,7 @@ fig_result_t fig1_select(fig1_common_t& fig1, const display_settings_t &disp) case 1: // FIG 1/1 Programme service label { // ETSI EN 300 401 8.1.14.1 - uint16_t sid; - sid = f[1] * 256 + f[2]; + uint16_t sid = read_u16_from_buf(f + 1); if (fig1.fibcrccorrect) { try { @@ -115,14 +112,10 @@ fig_result_t fig1_select(fig1_common_t& fig1, const display_settings_t &disp) pd = (f[1] & 0x80) >> 7; SCIdS = f[1] & 0x0F; if (pd == 0) { - sid = f[2] * 256 + \ - f[3]; + sid = read_u16_from_buf(f + 2); } else { - sid = f[2] * 256 * 256 * 256 + \ - f[3] * 256 * 256 + \ - f[4] * 256 + \ - f[5]; + sid = read_u32_from_buf(f + 2); } r.msgs.push_back(strprintf("Service ID=0x%04X", sid)); r.msgs.push_back(strprintf("Service Component ID=0x%04X", SCIdS)); @@ -135,10 +128,7 @@ fig_result_t fig1_select(fig1_common_t& fig1, const display_settings_t &disp) case 5: // FIG 1/5 Data service label { // ETSI EN 300 401 8.1.14.2 uint32_t sid; - sid = f[1] * 256 * 256 * 256 + \ - f[2] * 256 * 256 + \ - f[3] * 256 + \ - f[4]; + sid = read_u32_from_buf(f + 1); r.msgs.push_back(strprintf("Service ID=0x%04X", sid)); // TODO put label into ensembledatabase @@ -157,15 +147,11 @@ fig_result_t fig1_select(fig1_common_t& fig1, const display_settings_t &disp) pd = (f[1] & 0x80) >> 7; SCIdS = f[1] & 0x0F; if (pd == 0) { - sid = f[2] * 256 + \ - f[3]; + sid = read_u16_from_buf(f + 2); xpadapp = f[4] & 0x1F; } else { - sid = f[2] * 256 * 256 * 256 + \ - f[3] * 256 * 256 + \ - f[4] * 256 + \ - f[5]; + sid = read_u32_from_buf(f + 2); xpadapp = f[6] & 0x1F; } diff --git a/src/fig2.cpp b/src/fig2.cpp index 6346300..399d280 100644 --- a/src/fig2.cpp +++ b/src/fig2.cpp @@ -65,7 +65,7 @@ static void handle_ext_label_data_field(fig2_common_t& fig2, ensemble_database:: if (fig2.rfu() == 0) { const uint8_t rfa = (f[0] & 0x0F); r.msgs.push_back(strprintf("rfa=%d", rfa)); - const uint16_t char_flag = f[1] * 256 + f[2]; + const uint16_t char_flag = read_u16_from_buf(f + 1); r.msgs.push_back(strprintf("character flag=%04x", char_flag)); if (len_bytes <= 3) { @@ -114,7 +114,7 @@ fig_result_t fig2_select(fig2_common_t& fig2, const display_settings_t &disp) switch (fig2.ext()) { case 0: // Ensemble label { // ETSI EN 300 401 8.1.13 - uint16_t eid = f[1] * 256 + f[2]; + uint16_t eid = read_u16_from_buf(f + 1); if (fig2.figlen <= header_length + fig2.identifier_len()) { r.errors.push_back("FIG2 length error"); } @@ -133,7 +133,7 @@ fig_result_t fig2_select(fig2_common_t& fig2, const display_settings_t &disp) case 1: // Programme service label { // ETSI EN 300 401 8.1.14.1 - uint16_t sid = f[1] * 256 + f[2]; + uint16_t sid = read_u16_from_buf(f + 1); if (fig2.figlen <= header_length + fig2.identifier_len()) { r.errors.push_back("FIG2 length error"); } @@ -162,14 +162,10 @@ fig_result_t fig2_select(fig2_common_t& fig2, const display_settings_t &disp) uint8_t pd = (f[1] & 0x80) >> 7; uint8_t SCIdS = f[1] & 0x0F; if (pd == 0) { - sid = f[2] * 256 + \ - f[3]; + sid = read_u16_from_buf(f + 2); } else { - sid = f[2] * 256 * 256 * 256 + \ - f[3] * 256 * 256 + \ - f[4] * 256 + \ - f[5]; + sid = read_u32_from_buf(f + 2); } if (fig2.figlen <= header_length + fig2.identifier_len()) { r.errors.push_back("FIG2 length error"); @@ -204,10 +200,7 @@ fig_result_t fig2_select(fig2_common_t& fig2, const display_settings_t &disp) case 5: // Data service label { // ETSI EN 300 401 8.1.14.2 - uint32_t sid = f[1] * 256 * 256 * 256 + \ - f[2] * 256 * 256 + \ - f[3] * 256 + \ - f[4]; + uint32_t sid = read_u32_from_buf(f + 1); if (fig2.figlen <= header_length + fig2.identifier_len()) { r.errors.push_back("FIG2 length error"); @@ -242,15 +235,11 @@ fig_result_t fig2_select(fig2_common_t& fig2, const display_settings_t &disp) pd = (f[1] & 0x80) >> 7; SCIdS = f[1] & 0x0F; if (pd == 0) { - sid = f[2] * 256 + \ - f[3]; + sid = read_u16_from_buf(f + 2); xpadapp = f[4] & 0x1F; } else { - sid = f[2] * 256 * 256 * 256 + \ - f[3] * 256 * 256 + \ - f[4] * 256 + \ - f[5]; + sid = read_u32_from_buf(f + 2); xpadapp = f[6] & 0x1F; } diff --git a/src/figs.cpp b/src/figs.cpp index 62b103e..2bf56bb 100644 --- a/src/figs.cpp +++ b/src/figs.cpp @@ -84,6 +84,7 @@ fig_result_t fig0_select(fig0_common_t& fig0, const display_settings_t &disp) // 4 not implemented // Component conditional access case 5: return fig0_5(fig0, disp); break; // Component language case 6: return fig0_6(fig0, disp); break; // Service linking + case 7: return fig0_7(fig0, disp); break; // Configuration information (EN 300 401 v2) case 8: return fig0_8(fig0, disp); break; // More component stuff case 9: return fig0_9(fig0, disp); break; // Country, LTO, ECC, subfield with per-service ECC and LTO case 10: return fig0_10(fig0, disp); break; // Date and Time diff --git a/src/figs.hpp b/src/figs.hpp index 72d5f35..570c535 100644 --- a/src/figs.hpp +++ b/src/figs.hpp @@ -169,6 +169,7 @@ fig_result_t fig0_3(fig0_common_t& fig0, const display_settings_t &disp); fig_result_t fig0_5(fig0_common_t& fig0, const display_settings_t &disp); void fig0_6_cleardb(); fig_result_t fig0_6(fig0_common_t& fig0, const display_settings_t &disp); +fig_result_t fig0_7(fig0_common_t& fig0, const display_settings_t &disp); fig_result_t fig0_8(fig0_common_t& fig0, const display_settings_t &disp); fig_result_t fig0_9(fig0_common_t& fig0, const display_settings_t &disp); fig_result_t fig0_10(fig0_common_t& fig0, const display_settings_t &disp); diff --git a/src/utils.cpp b/src/utils.cpp index f69b013..e7420bd 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -305,3 +305,15 @@ int absolute_to_dB(int16_t value) return value ? round(20*log10((double)value / int16_max)) : -90; } +uint32_t read_u32_from_buf(const uint8_t *buf) +{ + return buf[0] * 256uL * 256uL * 256uL + + buf[1] * 256uL * 256uL + + buf[2] * 256uL + + buf[3]; +} + +uint16_t read_u16_from_buf(const uint8_t *buf) +{ + return buf[0] * 256uL + buf[1]; +} diff --git a/src/utils.hpp b/src/utils.hpp index 524ef09..ee5f7c9 100644 --- a/src/utils.hpp +++ b/src/utils.hpp @@ -103,3 +103,5 @@ std::string pnum_to_str(uint16_t Programme_Number); // -90dB int absolute_to_dB(int16_t value); +uint32_t read_u32_from_buf(const uint8_t *buf); +uint16_t read_u16_from_buf(const uint8_t *buf); -- cgit v1.2.3