diff --git a/include/tins/crypto.h b/include/tins/crypto.h index 94d703d..f047ac0 100644 --- a/include/tins/crypto.h +++ b/include/tins/crypto.h @@ -387,8 +387,9 @@ namespace Crypto { template RC4Key::RC4Key(ForwardIterator start, ForwardIterator end) { - for(size_t i = 0; i < data_size; ++i) - data[i] = i; + for(size_t i = 0; i < data_size; ++i) { + data[i] = static_cast(i); + } size_t j = 0; ForwardIterator iter = start; for(size_t i = 0; i < data_size; ++i) { diff --git a/include/tins/dhcpv6.h b/include/tins/dhcpv6.h index b7c8ee0..027b9b6 100644 --- a/include/tins/dhcpv6.h +++ b/include/tins/dhcpv6.h @@ -891,7 +891,7 @@ void class_option_data2option(InputIterator start, InputIterator end, uint16_t uint16_t_buffer; while(start != end) { buffer.resize(buffer.size() + sizeof(uint16_t) + start->size()); - uint16_t_buffer = Endian::host_to_be(start->size()); + uint16_t_buffer = Endian::host_to_be(static_cast(start->size())); std::memcpy(&buffer[index], &uint16_t_buffer, sizeof(uint16_t)); index += sizeof(uint16_t); std::copy(start->begin(), start->end(), buffer.begin() + index); diff --git a/include/tins/dot11/dot11_control.h b/include/tins/dot11/dot11_control.h index b8ac050..5e11068 100644 --- a/include/tins/dot11/dot11_control.h +++ b/include/tins/dot11/dot11_control.h @@ -144,7 +144,9 @@ protected: /** * \brief Getter for the control ta additional fields size. */ - uint32_t controlta_size() const { return _taddr.size() + sizeof(ieee80211_header); } + uint32_t controlta_size() const { + return static_cast(_taddr.size() + sizeof(ieee80211_header)); + } uint32_t write_ext_header(uint8_t *buffer, uint32_t total_sz); private: diff --git a/include/tins/dot11/dot11_data.h b/include/tins/dot11/dot11_data.h index ef5f013..68ad45c 100644 --- a/include/tins/dot11/dot11_data.h +++ b/include/tins/dot11/dot11_data.h @@ -246,8 +246,10 @@ protected: uint32_t write_ext_header(uint8_t *buffer, uint32_t total_sz); uint32_t data_frame_size() { - return Dot11::header_size() + sizeof(_ext_header) + - ((from_ds() && to_ds()) ? _addr4.size() : 0); + return static_cast( + Dot11::header_size() + sizeof(_ext_header) + + ((from_ds() && to_ds()) ? _addr4.size() : 0) + ); } private: ExtendedHeader _ext_header; diff --git a/include/tins/exceptions.h b/include/tins/exceptions.h index 163e056..46230ce 100644 --- a/include/tins/exceptions.h +++ b/include/tins/exceptions.h @@ -180,6 +180,17 @@ public: } }; +/** + * \brief Exception thrown when a payload is too large to fit + * into a PDUOption. + */ +class option_payload_too_large : public std::exception { +public: + const char *what() const throw() { + return "Option payload too large"; + } +}; + } // Tins #endif // TINS_EXCEPTIONS_H diff --git a/include/tins/pdu_option.h b/include/tins/pdu_option.h index 752da27..b71a479 100644 --- a/include/tins/pdu_option.h +++ b/include/tins/pdu_option.h @@ -312,7 +312,7 @@ public: * \param data The option's data(if any). */ PDUOption(option_type opt = option_type(), size_t length = 0, const data_type *data = 0) - : option_(opt), size_(length) { + : option_(opt), size_(static_cast(length)) { set_payload_contents(data, data + (data ? length : 0)); } @@ -397,7 +397,7 @@ public: */ template PDUOption(option_type opt, ForwardIterator start, ForwardIterator end) - : option_(opt), size_(std::distance(start, end)) { + : option_(opt), size_(static_cast(std::distance(start, end))) { set_payload_contents(start, end); } @@ -417,7 +417,7 @@ public: * \param end The end of the option data. */ template - PDUOption(option_type opt, size_t length, ForwardIterator start, ForwardIterator end) + PDUOption(option_type opt, uint16_t length, ForwardIterator start, ForwardIterator end) : option_(opt), size_(length) { set_payload_contents(start, end); } @@ -492,7 +492,11 @@ public: private: template void set_payload_contents(ForwardIterator start, ForwardIterator end) { - real_size_ = std::distance(start, end); + size_t total_size = std::distance(start, end); + if (total_size > std::numeric_limits::max()) { + throw option_payload_too_large(); + } + real_size_ = static_cast(total_size); if(real_size_ <= small_buffer_size) { std::copy( start, diff --git a/include/tins/pppoe.h b/include/tins/pppoe.h index 296bcd8..9cad0d6 100644 --- a/include/tins/pppoe.h +++ b/include/tins/pppoe.h @@ -240,7 +240,7 @@ public: * \param option The option to be added. */ void add_tag(tag &&option) { - _tags_size += option.data_size() + sizeof(uint16_t) * 2; + _tags_size += static_cast(option.data_size() + sizeof(uint16_t) * 2); _tags.push_back(std::move(option)); } #endif diff --git a/include/tins/rawpdu.h b/include/tins/rawpdu.h index 3404b64..77a05a9 100644 --- a/include/tins/rawpdu.h +++ b/include/tins/rawpdu.h @@ -157,7 +157,7 @@ namespace Tins { * \return uint32_t containing the payload size. */ uint32_t payload_size() const { - return _payload.size(); + return static_cast(_payload.size()); } /** @@ -184,7 +184,7 @@ namespace Tins { */ template T to() const { - return T(&_payload[0], _payload.size()); + return T(&_payload[0], static_cast(_payload.size())); } /** diff --git a/src/bootp.cpp b/src/bootp.cpp index c814953..6b5510d 100644 --- a/src/bootp.cpp +++ b/src/bootp.cpp @@ -52,7 +52,7 @@ BootP::BootP(const uint8_t *buffer, uint32_t total_sz, uint32_t vend_field_size) } uint32_t BootP::header_size() const { - return sizeof(bootphdr) + _vend.size(); + return static_cast(sizeof(bootphdr) + _vend.size()); } void BootP::opcode(uint8_t new_opcode) { diff --git a/src/crypto.cpp b/src/crypto.cpp index 459bfc2..86e024d 100644 --- a/src/crypto.cpp +++ b/src/crypto.cpp @@ -96,7 +96,8 @@ PDU *WEPDecrypter::decrypt(RawPDU &raw, const std::string &password) { // Generate the key RC4Key key(key_buffer.begin(), key_buffer.begin() + password.size() + 3); rc4(pload.begin() + 4, pload.end(), key, pload.begin()); - uint32_t crc = Utils::crc32(&pload[0], pload.size() - 8); + uint32_t payload_size = static_cast(pload.size() - 8); + uint32_t crc = Utils::crc32(&pload[0], payload_size); if(pload[pload.size() - 8] != (crc & 0xff) || pload[pload.size() - 7] != ((crc >> 8) & 0xff) || pload[pload.size() - 6] != ((crc >> 16) & 0xff) || @@ -104,7 +105,7 @@ PDU *WEPDecrypter::decrypt(RawPDU &raw, const std::string &password) { return 0; try { - return new SNAP(&pload[0], pload.size() - 8); + return new SNAP(&pload[0], payload_size); } catch(std::runtime_error&) { return 0; diff --git a/src/dhcp.cpp b/src/dhcp.cpp index 2914143..9fc0dd6 100644 --- a/src/dhcp.cpp +++ b/src/dhcp.cpp @@ -51,7 +51,7 @@ DHCP::DHCP(const uint8_t *buffer, uint32_t total_sz) : BootP(buffer, total_sz, 0), _size(sizeof(uint32_t)) { buffer += BootP::header_size() - vend().size(); - total_sz -= BootP::header_size() - vend().size(); + total_sz -= static_cast(BootP::header_size() - vend().size()); uint8_t args[2] = {0}; uint32_t uint32_t_buffer; std::memcpy(&uint32_t_buffer, buffer, sizeof(uint32_t)); @@ -86,7 +86,7 @@ void DHCP::add_option(const option &opt) { } void DHCP::internal_add_option(const option &opt) { - _size += opt.data_size() + (sizeof(uint8_t) << 1); + _size += static_cast(opt.data_size() + (sizeof(uint8_t) << 1)); } const DHCP::option *DHCP::search_option(OptionTypes opt) const { @@ -216,7 +216,7 @@ PDU::serialization_type DHCP::serialize_list(const std::vector & } uint32_t DHCP::header_size() const { - return BootP::header_size() - vend().size() + _size; + return static_cast(BootP::header_size() - vend().size() + _size); } void DHCP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) { @@ -231,7 +231,7 @@ void DHCP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *pa *((uint32_t*)&result[0]) = Endian::host_to_be(0x63825363); for(options_type::const_iterator it = _options.begin(); it != _options.end(); ++it) { *(ptr++) = it->option(); - *(ptr++) = it->length_field(); + *(ptr++) = static_cast(it->length_field()); std::copy(it->data_ptr(), it->data_ptr() + it->data_size(), ptr); ptr += it->data_size(); } diff --git a/src/dhcpv6.cpp b/src/dhcpv6.cpp index e45d7ac..eb947b5 100644 --- a/src/dhcpv6.cpp +++ b/src/dhcpv6.cpp @@ -95,7 +95,7 @@ const DHCPv6::option *DHCPv6::search_option(OptionTypes id) const { uint8_t* DHCPv6::write_option(const option &opt, uint8_t* buffer) const { uint16_t uint16_t_buffer = Endian::host_to_be(opt.option()); std::memcpy(buffer, &uint16_t_buffer, sizeof(uint16_t)); - uint16_t_buffer = Endian::host_to_be(opt.length_field()); + uint16_t_buffer = Endian::host_to_be(static_cast(opt.length_field())); std::memcpy(&buffer[sizeof(uint16_t)], &uint16_t_buffer, sizeof(uint16_t)); return std::copy( opt.data_ptr(), @@ -632,7 +632,7 @@ DHCPv6::vendor_class_type DHCPv6::vendor_class_type::from_option(const option &o output.enterprise_number = Endian::be_to_host(output.enterprise_number); output.vendor_class_data = Internals::option2class_option_data( opt.data_ptr() + sizeof(uint32_t), - opt.data_size() - sizeof(uint32_t) + static_cast(opt.data_size() - sizeof(uint32_t)) ); return output; @@ -660,7 +660,7 @@ DHCPv6::user_class_type DHCPv6::user_class_type::from_option(const option &opt) throw malformed_option(); user_class_type output; output.data = Internals::option2class_option_data( - opt.data_ptr(), opt.data_size() + opt.data_ptr(), static_cast(opt.data_size()) ); return output; } diff --git a/src/dns.cpp b/src/dns.cpp index 3c830da..849ed84 100644 --- a/src/dns.cpp +++ b/src/dns.cpp @@ -72,9 +72,13 @@ DNS::DNS(const uint8_t *buffer, uint32_t total_sz) throw malformed_packet(); buffer += sizeof(uint16_t) * 2; } - answers_idx = buffer - prev_start; - authority_idx = find_section_end(&records_data[0] + answers_idx, answers_count()) - &records_data[0]; - additional_idx = find_section_end(&records_data[0] + authority_idx, authority_count()) - &records_data[0]; + answers_idx = static_cast(buffer - prev_start); + authority_idx = static_cast( + find_section_end(&records_data[0] + answers_idx, answers_count()) - &records_data[0] + ); + additional_idx = static_cast( + find_section_end(&records_data[0] + authority_idx, authority_count()) - &records_data[0] + ); } } @@ -118,7 +122,7 @@ const uint8_t *DNS::find_section_end(const uint8_t *ptr, const uint32_t num_reco } uint32_t DNS::header_size() const { - return sizeof(dns) + records_data.size(); + return static_cast(sizeof(dns) + records_data.size()); } void DNS::id(uint16_t new_id) { @@ -180,7 +184,7 @@ void DNS::add_query(const Query &query) { uint16_t_buffer = Endian::host_to_be(query.query_class()); std::memcpy(&new_str[new_str.size() - 2], &uint16_t_buffer, sizeof(uint16_t)); - uint32_t offset = new_str.size(), threshold = answers_idx; + uint32_t offset = static_cast(new_str.size()), threshold = answers_idx; update_records(answers_idx, answers_count(), threshold, offset); update_records(authority_idx, authority_count(), threshold, offset); update_records(additional_idx, additional_count(), threshold, offset); @@ -189,9 +193,7 @@ void DNS::add_query(const Query &query) { new_str.begin(), new_str.end() ); - dns.questions = Endian::host_to_be( - questions_count() + 1 - ); + dns.questions = Endian::host_to_be(static_cast(questions_count() + 1)); } void DNS::add_answer(const Resource &resource) { @@ -211,7 +213,7 @@ void DNS::add_record(const Resource &resource, const sections_type §ions) { IPv6Address v6_addr; std::string buffer = encode_domain_name(resource.dname()), encoded_data; // By default the data size is the length of the data field. - uint32_t data_size = resource.data().size(); + size_t data_size = resource.data().size(); if(resource.type() == A) { v4_addr = resource.data(); data_size = 4; @@ -224,14 +226,15 @@ void DNS::add_record(const Resource &resource, const sections_type §ions) { encoded_data = encode_domain_name(resource.data()); data_size = encoded_data.size(); } - uint32_t offset = buffer.size() + sizeof(uint16_t) * 3 + sizeof(uint32_t) + data_size, + size_t offset = buffer.size() + sizeof(uint16_t) * 3 + sizeof(uint32_t) + data_size, threshold = sections.empty() ? records_data.size() : *sections.front().first; // Skip the preference field if(resource.type() == MX) { offset += sizeof(uint16_t); } for(size_t i = 0; i < sections.size(); ++i) { - update_records(*sections[i].first, sections[i].second, threshold, offset); + update_records(*sections[i].first, sections[i].second, + static_cast(threshold), static_cast(offset)); } records_data.insert( @@ -257,8 +260,8 @@ void DNS::add_record(const Resource &resource, const sections_type §ions) { uint32_t_buffer = Endian::host_to_be(resource.ttl()); std::memcpy(ptr, &uint32_t_buffer, sizeof(uint32_t)); ptr += sizeof(uint32_t); - uint16_t_buffer = Endian::host_to_be( - data_size + (resource.type() == MX ? 2 : 0) + uint16_t_buffer = Endian::host_to_be( + static_cast(data_size + (resource.type() == MX ? 2 : 0)) ); std::memcpy(ptr, &uint16_t_buffer, sizeof(uint16_t)); ptr += sizeof(uint16_t); @@ -301,11 +304,11 @@ std::string DNS::encode_domain_name(const std::string &dn) { size_t last_index(0), index; if(!dn.empty()) { while((index = dn.find('.', last_index+1)) != string::npos) { - output.push_back(index - last_index); + output.push_back(static_cast(index - last_index)); output.append(dn.begin() + last_index, dn.begin() + index); last_index = index + 1; //skip dot } - output.push_back(dn.size() - last_index); + output.push_back(static_cast(dn.size() - last_index)); output.append(dn.begin() + last_index, dn.end()); } output.push_back('\0'); diff --git a/src/dot11/dot11_base.cpp b/src/dot11/dot11_base.cpp index 3de49de..e5f11af 100644 --- a/src/dot11/dot11_base.cpp +++ b/src/dot11/dot11_base.cpp @@ -103,7 +103,7 @@ void Dot11::add_tagged_option(OptionTypes opt, uint8_t len, const uint8_t *val) } void Dot11::internal_add_option(const option &opt) { - _options_size += opt.data_size() + sizeof(uint8_t) * 2; + _options_size += static_cast(opt.data_size() + sizeof(uint8_t) * 2); } void Dot11::add_option(const option &opt) { @@ -212,7 +212,7 @@ void Dot11::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *p #endif for(std::list