diff --git a/firmware/application/apps/ble_tx_app.cpp b/firmware/application/apps/ble_tx_app.cpp index f7a2cb9fc..07b5ff13c 100644 --- a/firmware/application/apps/ble_tx_app.cpp +++ b/firmware/application/apps/ble_tx_app.cpp @@ -199,6 +199,7 @@ void BLETxView::send_packet() { generateRandomMacAddress(randomMac); char advertisementData[63] = {0}; + packets[current_packet].advertisementData[62] = '\0'; strcpy(advertisementData, packets[current_packet].advertisementData); // TODO: Make this a checkbox. diff --git a/firmware/application/apps/ui_standalone_view.cpp b/firmware/application/apps/ui_standalone_view.cpp index 33ab46486..540a18396 100644 --- a/firmware/application/apps/ui_standalone_view.cpp +++ b/firmware/application/apps/ui_standalone_view.cpp @@ -34,7 +34,7 @@ namespace ui { void create_thread(int32_t (*fn)(void*), void* arg, size_t stack_size, int priority) { - // TODO: collect memory on terminate, once this is used + // TODO: collect memory on terminate, once this is used. This is a HUGE TODO! need to call chThdWait on all of them! chThdCreateFromHeap(NULL, stack_size, priority, fn, arg); } diff --git a/firmware/application/external/sd_wipe/ui_sd_wipe.cpp b/firmware/application/external/sd_wipe/ui_sd_wipe.cpp index a482e784a..00bf9a8be 100644 --- a/firmware/application/external/sd_wipe/ui_sd_wipe.cpp +++ b/firmware/application/external/sd_wipe/ui_sd_wipe.cpp @@ -36,8 +36,11 @@ WipeSDView::WipeSDView(NavigationView& nav) } WipeSDView::~WipeSDView() { - if (thread) + if (thread) { chThdTerminate(thread); + chThdWait(thread); + thread = nullptr; + } } void WipeSDView::focus() { diff --git a/firmware/application/file.cpp b/firmware/application/file.cpp index df0f22849..08bf0f36f 100644 --- a/firmware/application/file.cpp +++ b/firmware/application/file.cpp @@ -161,7 +161,7 @@ Optional File::sync() { File::Result File::read_file(const std::filesystem::path& filename) { constexpr size_t buffer_size = 0x80; - char* buffer[buffer_size]; + char buffer[buffer_size]; File f; auto error = f.open(filename); @@ -205,6 +205,7 @@ static std::filesystem::path find_last_ordinal_match( const std::filesystem::path& pattern, pattern_range range) { auto last_match = std::filesystem::path(); + if (range.start == std::string::npos || range.end == std::string::npos || range.start > range.end) return last_match; auto can_increment = [range](const auto& path) { for (auto i = range.start; i <= range.end; ++i) if (!isdigit(path.native()[i])) @@ -230,7 +231,7 @@ static std::filesystem::path increment_filename_ordinal( const std::filesystem::path& path, pattern_range range) { auto name = path.filename().native(); - + if (range.start == std::string::npos || range.end == std::string::npos || range.start > range.end) return {name}; for (auto i = range.end; i >= range.start; --i) { auto& c = name[i]; diff --git a/firmware/application/file_reader.hpp b/firmware/application/file_reader.hpp index bcd9f1517..03de8caa6 100644 --- a/firmware/application/file_reader.hpp +++ b/firmware/application/file_reader.hpp @@ -117,7 +117,7 @@ class BufferLineReader { std::strncpy(&it.line_data_[offset], buf, len); offset += len; - if (len < buf_size) + if (len < buf_size || buf[len - 1] == '\n') break; } diff --git a/firmware/application/gradient.cpp b/firmware/application/gradient.cpp index 2ca27e6bb..f8564526a 100644 --- a/firmware/application/gradient.cpp +++ b/firmware/application/gradient.cpp @@ -84,8 +84,7 @@ void Gradient::step(int16_t index, int16_t r, int16_t g, int16_t b) { int16_t new_r = prev_r * y + r * x; int16_t new_g = prev_g * y + g * x; int16_t new_b = prev_b * y + b * x; - - lut[i] = ui::Color(new_r, new_g, new_b); + if (i <= 255) lut[i] = ui::Color(new_r, new_g, new_b); } prev_index = index; diff --git a/firmware/application/io_wave.hpp b/firmware/application/io_wave.hpp index 6d32454f8..2cbfa4109 100644 --- a/firmware/application/io_wave.hpp +++ b/firmware/application/io_wave.hpp @@ -81,7 +81,8 @@ struct header_t { struct tags_t { constexpr tags_t( const std::string& title_str) { - strcpy(title, title_str.c_str()); + strncpy(title, title_str.c_str(), sizeof(title) - 1); + title[sizeof(title) - 1] = '\0'; cksize = sizeof(tags_t) - 8; } diff --git a/firmware/application/main.cpp b/firmware/application/main.cpp index 76911cb8f..ef2eb9435 100644 --- a/firmware/application/main.cpp +++ b/firmware/application/main.cpp @@ -91,7 +91,7 @@ Continuous (Fox-oring) // TODO: ADS-B draw trajectory + GPS coordinates + scale, and playback // TODO: RDS multiple groups (sequence) // TODO: Use ModalMessageView confirmation for TX ? -// TODO: Use msgpack for settings, lists... on sd card +// TODO: Use msgpack for settings, lists... on sd card. and make it safe, since now it has a lot of oob potentials // Multimon-style stuff: // TODO: DMR detector diff --git a/firmware/application/recent_entries.hpp b/firmware/application/recent_entries.hpp index 8c5e35d31..6880f479a 100644 --- a/firmware/application/recent_entries.hpp +++ b/firmware/application/recent_entries.hpp @@ -108,9 +108,10 @@ void resetFilteredEntries(ContainerType& entries, KeySelector keySelector) { auto it = entries.begin(); while (it != entries.end()) { if (keySelector(*it)) { - entries.erase(it); // Add a new entry to filteredEntries + it = entries.erase(it); // Add a new entry to filteredEntries + } else { + ++it; // Move to the next element, outside of the if block } - ++it; // Move to the next element, outside of the if block } } diff --git a/firmware/application/string_format.cpp b/firmware/application/string_format.cpp index 764b7f7e9..faf5e62dc 100644 --- a/firmware/application/string_format.cpp +++ b/firmware/application/string_format.cpp @@ -100,7 +100,8 @@ std::string to_string_dec_uint(uint64_t n) { std::string to_string_bin( const uint32_t n, - const uint8_t l) { + uint8_t l) { + if (l >= 33) l = 32; char p[33]; for (uint8_t c = 0; c < l; c++) { if (n & (1 << (l - 1 - c))) diff --git a/firmware/application/string_format.hpp b/firmware/application/string_format.hpp index cfebd70f3..bf803ced3 100644 --- a/firmware/application/string_format.hpp +++ b/firmware/application/string_format.hpp @@ -50,7 +50,7 @@ char* to_string_dec_uint(uint64_t n, StringFormatBuffer& buffer, size_t& length) std::string to_string_dec_int(int64_t n); std::string to_string_dec_uint(uint64_t n); -std::string to_string_bin(const uint32_t n, const uint8_t l = 0); +std::string to_string_bin(const uint32_t n, uint8_t l = 0); std::string to_string_dec_uint(const uint32_t n, const int32_t l, const char fill = ' '); std::string to_string_dec_int(const int32_t n, const int32_t l, const char fill = 0); std::string to_string_decimal(float decimal, int8_t precision); diff --git a/firmware/application/theme.hpp b/firmware/application/theme.hpp index a03b7d887..1f7f8c96e 100644 --- a/firmware/application/theme.hpp +++ b/firmware/application/theme.hpp @@ -32,40 +32,40 @@ namespace ui { class ThemeTemplate { public: - ~ThemeTemplate(); - Style* bg_lightest; - Style* bg_lightest_small; - Style* bg_light; - Style* bg_medium; - Style* bg_dark; - Style* bg_darker; + virtual ~ThemeTemplate(); + Style* bg_lightest = nullptr; + Style* bg_lightest_small = nullptr; + Style* bg_light = nullptr; + Style* bg_medium = nullptr; + Style* bg_dark = nullptr; + Style* bg_darker = nullptr; - Style* bg_darkest; - Style* bg_darkest_small; + Style* bg_darkest = nullptr; + Style* bg_darkest_small = nullptr; - Style* bg_important_small; + Style* bg_important_small = nullptr; - Style* error_dark; - Style* warning_dark; - Style* ok_dark; + Style* error_dark = nullptr; + Style* warning_dark = nullptr; + Style* ok_dark = nullptr; - Style* fg_dark; - Style* fg_medium; - Style* fg_light; + Style* fg_dark = nullptr; + Style* fg_medium = nullptr; + Style* fg_light = nullptr; - Style* fg_red; - Style* fg_green; - Style* fg_yellow; - Style* fg_orange; - Style* fg_blue; - Style* fg_cyan; - Style* fg_darkcyan; - Style* fg_magenta; + Style* fg_red = nullptr; + Style* fg_green = nullptr; + Style* fg_yellow = nullptr; + Style* fg_orange = nullptr; + Style* fg_blue = nullptr; + Style* fg_cyan = nullptr; + Style* fg_darkcyan = nullptr; + Style* fg_magenta = nullptr; - Style* option_active; + Style* option_active = nullptr; - Color* status_active; // green, the status bar icons when active - Color* bg_table_header; + Color* status_active = nullptr; // green, the status bar icons when active + Color* bg_table_header = nullptr; }; class ThemeDefault : public ThemeTemplate { diff --git a/firmware/application/ui/ui_bmpview.cpp b/firmware/application/ui/ui_bmpview.cpp index 9a8a23803..9556a9f15 100644 --- a/firmware/application/ui/ui_bmpview.cpp +++ b/firmware/application/ui/ui_bmpview.cpp @@ -92,7 +92,7 @@ void BMPViewer::get_line(ui::Color* line, uint32_t bx, uint32_t by, uint32_t cnt for (uint32_t x = 0; x < cnt; x++) { uint32_t targetx = (zoom < 0) ? bx + x * -1 * zoom : bx + x / zoom; // on zoom out could probably avg the pixels, or apply some smoothing, but this is way faster. if (last_targetx == targetx) { - line[x] = line[x - 1]; + if (x > 0) line[x] = line[x - 1]; continue; } last_targetx = targetx; @@ -123,7 +123,7 @@ void BMPViewer::paint(Painter& painter) { last_by = by; portapack::display.draw_pixels({rect.left(), rect.top() + y, d_width, 1}, line, d_width); } - delete line; + delete[] line; } int8_t BMPViewer::get_zoom() { diff --git a/firmware/application/usb_serial_shell.cpp b/firmware/application/usb_serial_shell.cpp index f528636f5..9c1483f89 100644 --- a/firmware/application/usb_serial_shell.cpp +++ b/firmware/application/usb_serial_shell.cpp @@ -1141,7 +1141,7 @@ static void cmd_gotenv(BaseSequentialStream* chp, int argc, char* argv[]) { uint16_t light = 0; if (argc > 1) humi = atof(argv[1]); if (argc > 2) pressure = atof(argv[2]); - if (argc > 3) light = strtol(argv[0], NULL, 10); + if (argc > 3) light = strtol(argv[3], NULL, 10); EnvironmentDataMessage msg{temp, humi, pressure}; EventDispatcher::send_message(msg); // compatibility: diff --git a/firmware/application/usb_serial_shell_filesystem.cpp b/firmware/application/usb_serial_shell_filesystem.cpp index 1ba036ec6..8f39f7a83 100644 --- a/firmware/application/usb_serial_shell_filesystem.cpp +++ b/firmware/application/usb_serial_shell_filesystem.cpp @@ -148,7 +148,11 @@ void cmd_sd_open(BaseSequentialStream* chp, int argc, char* argv[]) { auto path = path_from_string8((char*)full_fn_from_args(argc, argv).c_str()); shell_file = new File(); auto error = shell_file->open(path, false, true); - if (report_on_error(chp, error)) return; + if (report_on_error(chp, error)) { + delete shell_file; + shell_file = nullptr; + return; + } chprintf(chp, "ok\r\n"); } diff --git a/firmware/baseband/fprotos/subcarprotos.hpp b/firmware/baseband/fprotos/subcarprotos.hpp index 31272ec0a..96952e264 100644 --- a/firmware/baseband/fprotos/subcarprotos.hpp +++ b/firmware/baseband/fprotos/subcarprotos.hpp @@ -28,8 +28,8 @@ So include here the .hpp, and add a new element to the protos vector in the cons class SubCarProtos : public FProtoListGeneral { public: - SubCarProtos(const SubCarProtos&) { SubCarProtos(); }; // won't use, but makes compiler happy - SubCarProtos& operator=(const SubCarProtos&) { return *this; } // won't use, but makes compiler happy + SubCarProtos(const SubCarProtos&) = delete; + SubCarProtos& operator=(const SubCarProtos&) = delete; SubCarProtos() { // add protos protos[FPC_SUZUKI] = new FProtoSubCarSuzuki(); diff --git a/firmware/baseband/fprotos/subghzdprotos.hpp b/firmware/baseband/fprotos/subghzdprotos.hpp index cdc83b87f..6efea5d88 100644 --- a/firmware/baseband/fprotos/subghzdprotos.hpp +++ b/firmware/baseband/fprotos/subghzdprotos.hpp @@ -62,8 +62,8 @@ So include here the .hpp, and add a new element to the protos vector in the cons class SubGhzDProtos : public FProtoListGeneral { public: - SubGhzDProtos(const SubGhzDProtos&) { SubGhzDProtos(); }; // won't use, but makes compiler happy - SubGhzDProtos& operator=(const SubGhzDProtos&) { return *this; } // won't use, but makes compiler happy + SubGhzDProtos(const SubGhzDProtos&) = delete; + SubGhzDProtos& operator=(const SubGhzDProtos&) = delete; SubGhzDProtos() { // add protos protos[FPS_PRINCETON] = new FProtoSubGhzDPrinceton(); diff --git a/firmware/baseband/fprotos/weatherprotos.hpp b/firmware/baseband/fprotos/weatherprotos.hpp index 98dec833e..5f5c70ac4 100644 --- a/firmware/baseband/fprotos/weatherprotos.hpp +++ b/firmware/baseband/fprotos/weatherprotos.hpp @@ -41,8 +41,8 @@ So include here the .hpp, and add a new element to the protos vector in the cons class WeatherProtos : public FProtoListGeneral { public: - WeatherProtos(const WeatherProtos&) { WeatherProtos(); }; // won't use, but makes compiler happy - WeatherProtos& operator=(const WeatherProtos&) { return *this; } // won't use, but makes compiler happy + WeatherProtos(const WeatherProtos&) = delete; + WeatherProtos& operator=(const WeatherProtos&) = delete; WeatherProtos() { // add protos protos[FPW_NexusTH] = new FProtoWeatherNexusTH(); diff --git a/firmware/baseband/proc_ble_tx.cpp b/firmware/baseband/proc_ble_tx.cpp index c789bbfa1..612d0ffb7 100644 --- a/firmware/baseband/proc_ble_tx.cpp +++ b/firmware/baseband/proc_ble_tx.cpp @@ -195,7 +195,7 @@ void BTLETxProcessor::scramble(char* bit_in, int num_bit, int channel_number, ch void BTLETxProcessor::disp_bit_in_hex(char* bit, int num_bit) { int i, a; - for (i = 0; i < num_bit; i = i + 8) { + for (i = 0; i + 7 < num_bit; i = i + 8) { a = bit[i] + bit[i + 1] * 2 + bit[i + 2] * 4 + bit[i + 3] * 8 + bit[i + 4] * 16 + bit[i + 5] * 32 + bit[i + 6] * 64 + bit[i + 7] * 128; data_message.is_data = true; diff --git a/firmware/baseband/proc_mictx.cpp b/firmware/baseband/proc_mictx.cpp index 4be4a81cb..8e17b34fa 100644 --- a/firmware/baseband/proc_mictx.cpp +++ b/firmware/baseband/proc_mictx.cpp @@ -101,6 +101,10 @@ void MicTXProcessor::on_message(const Message* const msg) { switch (msg->id) { case Message::ID::AudioTXConfig: + if (modulator) { + delete modulator; + modulator = NULL; + } if (fm_enabled) { dsp::modulate::FM* fm = new dsp::modulate::FM(); diff --git a/firmware/common/i2cdevmanager.cpp b/firmware/common/i2cdevmanager.cpp index c1bef6a8e..f7de439cc 100644 --- a/firmware/common/i2cdevmanager.cpp +++ b/firmware/common/i2cdevmanager.cpp @@ -205,7 +205,7 @@ uint16_t I2cDev::read16_1(uint8_t reg) { } uint32_t I2cDev::read24_1(uint8_t reg) { uint8_t buffer[3]; - i2c_read(®, 1, buffer, 2); + i2c_read(®, 1, buffer, 3); return uint32_t(buffer[0]) << 16 | uint32_t(buffer[1]) << 8 | uint32_t(buffer[2]); } diff --git a/firmware/common/morse.cpp b/firmware/common/morse.cpp index b91a3a183..ff1f809b3 100644 --- a/firmware/common/morse.cpp +++ b/firmware/common/morse.cpp @@ -41,7 +41,7 @@ size_t morse_encode(std::string& message, const uint32_t time_unit_ms, const uin i = 0; for (char& ch : message) { - if (i > 256) return 0; // Message too long + if (i >= 256) return 0; // Message too long if ((ch >= 'a') && (ch <= 'z')) // Make uppercase ch -= 32; diff --git a/firmware/common/ui_widget.cpp b/firmware/common/ui_widget.cpp index ab97924b2..8a6b8ef99 100644 --- a/firmware/common/ui_widget.cpp +++ b/firmware/common/ui_widget.cpp @@ -272,9 +272,8 @@ void View::add_child(Widget* const widget) { } void View::add_children(const std::initializer_list children) { - children_.insert(std::end(children_), children); for (auto child : children) { - child->set_parent(this); + add_child(child); } } @@ -622,8 +621,8 @@ ProgressBar::ProgressBar( void ProgressBar::set_max(const uint32_t max) { if (max == _max) return; - if (_value > _max) - _value = _max; + if (_value > max) + _value = max; _max = max; set_dirty(); @@ -651,9 +650,11 @@ void ProgressBar::paint(Painter& painter) { const auto sr = screen_rect(); const auto s = style(); - - v_scaled = (sr.size().width() * (uint64_t)_value) / _max; - + if (_max == 0) { + v_scaled = 0; + } else { + v_scaled = (sr.size().width() * (uint64_t)_value) / _max; + } painter.fill_rectangle({sr.location(), {v_scaled, sr.size().height()}}, style().foreground); painter.fill_rectangle({{sr.location().x() + v_scaled, sr.location().y()}, {sr.size().width() - v_scaled, sr.size().height()}}, s.background); @@ -1267,7 +1268,7 @@ bool ButtonWithEncoder::on_encoder(const EncoderEvent delta) { if (delta != 0) { encoder_delta += delta; delta_change = true; - on_change(); + if (on_change) on_change(); } else delta_change = 0; return true; @@ -1904,6 +1905,7 @@ void OptionsField::on_focus() { } bool OptionsField::on_encoder(const EncoderEvent delta) { + if (options_.empty()) return false; int32_t new_value = selected_index() + delta; if (new_value < 0) new_value = options_.size() - 1; diff --git a/firmware/common/utility.cpp b/firmware/common/utility.cpp index c4af7f400..d73584ef3 100644 --- a/firmware/common/utility.cpp +++ b/firmware/common/utility.cpp @@ -22,6 +22,7 @@ #include "utility.hpp" #include +#include #if 0 uint32_t gcd(const uint32_t u, const uint32_t v) { @@ -257,8 +258,23 @@ std::string join(char c, std::initializer_list strings) { } uint32_t simple_checksum(uint32_t buffer_address, uint32_t length) { + if (buffer_address == 0 || length == 0) { + return 0; + } uint32_t checksum = 0; - for (uint32_t i = 0; i < length; i += 4) - checksum += *(uint32_t*)(buffer_address + i); + const uint8_t* ptr = (const uint8_t*)(uintptr_t)buffer_address; + uint32_t i = 0; + for (; i + 3 < length; i += 4) { + uint32_t chunk; + // memcpy prevents unaligned access hard-faults on embedded processors + memcpy(&chunk, ptr + i, 4); + checksum += chunk; + } + // Leftover bytes (won't happen hopefully) + if (i < length) { + uint32_t remainder = 0; + memcpy(&remainder, ptr + i, length - i); + checksum += remainder; + } return checksum; } \ No newline at end of file