Skip to content

Commit f1ef39a

Browse files
committed
misc fixes
1 parent 3ed4e69 commit f1ef39a

10 files changed

Lines changed: 143 additions & 26 deletions

File tree

CHANGELOG.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,26 @@
11
# Changelog
22

3+
## v1.7.0
4+
5+
- Fixed cancel button in confirmation dialogs returning to main menu instead of the correct sub-menu
6+
- Fixed `clear_pcap_files` not resetting the `HasOpenedFile` flag after closing the file handle, causing silent write failures on active captures
7+
- Fixed app crashing the entire device on SD card mkdir failure, now exits gracefully instead
8+
- Removed dead null check in `settings_storage_init` that could never be reached
9+
- Fixed sync timing counters never resetting between capture sessions
10+
- Fixed IR universals list query failing on slow UART connections due to using a fixed 200ms delay instead of a proper timeout loop
11+
- Fixed app info dialog showing empty text
12+
- Removed unreachable return statement in `settings_custom_event_callback`
13+
- Fixed critical resource leak on text_box allocation failure, early return now properly cleans up UART context, expansion protocol, OTG state and all allocated memory
14+
- Fixed NULL pointer dereference in `uart_storage_rx_callback` when `app` is NULL
15+
- Fixed memory leak in `show_app_info`, confirmation context now tracked in `active_confirm_context`
16+
- Fixed `SETTING_SHOW_INFO` event handler returning `false` instead of `true`
17+
- Fixed `show_confirmation_dialog_ex` overwriting `active_confirm_context` without freeing previous allocation
18+
- Fixed memory leak in `get_latest_log_file` on `realloc` failure
19+
- Fixed race condition in UART cleanup, capture streams now cleaned after thread join
20+
- Fixed missing NULL checks on `storage_file_alloc` in file clearing functions
21+
- Fixed missing NULL check on `context` in `show_app_info`
22+
- Fixed error path in core UI allocation leaking `RECORD_DIALOGS`, expansion protocol and OTG power state
23+
324
## v1.6.3
425

526
- Fixed an issue where the text view would be empty

src/callbacks.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,12 +199,18 @@ void nvs_clear_cancelled_callback(void* context) {
199199
}
200200
}
201201
void show_app_info(void* context) {
202+
if(!context) return;
202203
SettingsUIContext* settings_context = (SettingsUIContext*)context;
203204
AppState* app = (AppState*)settings_context->context;
204205

205206
FURI_LOG_D("AppInfo", "Show app info called, context: %p", app);
206207

207-
const char* info_text = "";
208+
const char* info_text = "Created by: Spooky\n"
209+
"Updated by:\n"
210+
"@jaylikesbunda\n"
211+
"@tototo31\n"
212+
"Built with <3\n"
213+
"github.com/jaylikesbunda/ghost_esp\n\n";
208214

209215
if(app && app->confirmation_view) {
210216
// Create a new context for the confirmation dialog
@@ -214,6 +220,7 @@ void show_app_info(void* context) {
214220
return;
215221
}
216222
confirm_ctx->state = app;
223+
app->active_confirm_context = confirm_ctx;
217224

218225
// Save current view before switching
219226
app->previous_view = app->current_view;

src/log_manager.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ bool get_latest_log_file(Storage* storage, const char* dir, const char* prefix,
7575
files_capacity *= 2;
7676
LogFile* new_files = realloc(files, sizeof(LogFile) * files_capacity);
7777
if(!new_files) {
78-
// Handle realloc failure
78+
for(size_t j = 0; j < files_count; j++) {
79+
free(files[j].filename);
80+
}
7981
free(files);
8082
free(filename);
8183
storage_dir_close(dir_handle);

src/main.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
#include "app_state.h"
2727

2828
// Include the header where settings_custom_event_callback is declared
29-
#include "settings_ui.h"
3029

3130
#define UART_INIT_STACK_SIZE 2048
3231
#define UART_INIT_TIMEOUT_MS 1500 // ms
@@ -89,12 +88,17 @@ int32_t ghost_esp_app(void* p) {
8988
state->view_dispatcher = view_dispatcher_alloc();
9089
state->main_menu = main_menu_alloc();
9190
if(!state->view_dispatcher || !state->main_menu) {
92-
// Clean up and exit if core components fail
9391
if(state->view_dispatcher) view_dispatcher_free(state->view_dispatcher);
9492
if(state->main_menu) main_menu_free(state->main_menu);
93+
if(state->dialogs) furi_record_close(RECORD_DIALOGS);
9594
free(state->textBoxBuffer);
9695
free(state->input_buffer);
9796
free(state);
97+
expansion_enable(expansion);
98+
furi_record_close(RECORD_EXPANSION);
99+
if(furi_hal_power_is_otg_enabled() && !otg_was_enabled) {
100+
furi_hal_power_disable_otg();
101+
}
98102
return -1;
99103
}
100104

@@ -247,7 +251,7 @@ int32_t ghost_esp_app(void* p) {
247251

248252
if(!state->text_box) {
249253
FURI_LOG_E("Main", "Text box allocation failed!");
250-
return -1; // Don't try to fuck with broken UI
254+
goto cleanup;
251255
}
252256

253257
text_view_attach_input_handler(state);
@@ -268,6 +272,7 @@ int32_t ghost_esp_app(void* p) {
268272
view_dispatcher_run(state->view_dispatcher);
269273
}
270274

275+
cleanup:
271276
// ---- Start Cleanup Sequence ----
272277
FURI_LOG_I("Ghost_ESP", "Starting cleanup sequence...");
273278

@@ -291,7 +296,6 @@ int32_t ghost_esp_app(void* p) {
291296
// Clean up UART context (this will also handle storage cleanup)
292297
if(state && state->uart_context) {
293298
FURI_LOG_I("Ghost_ESP", "Freeing UART context...");
294-
uart_cleanup_capture_streams(state->uart_context); // Ensure capture streams are freed
295299
uart_free(state->uart_context);
296300
state->uart_context = NULL;
297301
FURI_LOG_I("Ghost_ESP", "UART context freed.");

src/menu.c

Lines changed: 65 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1714,13 +1714,24 @@ static bool ir_query_and_parse_universals(AppState* state) {
17141714

17151715
uart_reset_text_buffers(state->uart_context);
17161716
send_uart_command("ir universals list\n", state);
1717-
furi_delay_ms(200);
17181717

17191718
char buffer[IR_UART_PARSE_BUF_SIZE];
17201719

17211720
size_t len = 0;
1722-
if(!uart_copy_text_buffer_tail(state->uart_context, buffer, IR_UART_PARSE_BUF_SIZE, &len) ||
1723-
len == 0) {
1721+
uint32_t start = furi_get_tick();
1722+
const uint32_t timeout_ms = 3000;
1723+
while(furi_get_tick() - start < timeout_ms) {
1724+
furi_delay_ms(100);
1725+
if(uart_copy_text_buffer_tail(state->uart_context, buffer, IR_UART_PARSE_BUF_SIZE, &len) &&
1726+
len > 0) {
1727+
if(strstr(buffer, "Universal Files in ") || strstr(buffer, "Built-in") ||
1728+
strstr(buffer, "(none)") || strchr(buffer, '.')) {
1729+
break;
1730+
}
1731+
}
1732+
}
1733+
1734+
if(len == 0) {
17241735
return false;
17251736
}
17261737

@@ -2026,19 +2037,64 @@ static void confirmation_ok_callback(void* context) {
20262037
static void confirmation_cancel_callback(void* context) {
20272038
MenuCommandContext* cmd_ctx = context;
20282039
if(cmd_ctx && cmd_ctx->state) {
2029-
cmd_ctx->state->active_confirm_context = NULL;
2030-
switch(cmd_ctx->state->previous_view) {
2040+
AppState* s = cmd_ctx->state;
2041+
s->active_confirm_context = NULL;
2042+
uint32_t pv = s->previous_view;
2043+
switch(pv) {
20312044
case 1:
2032-
show_wifi_menu(cmd_ctx->state);
2045+
show_wifi_menu(s);
2046+
submenu_set_selected_item(s->wifi_menu, s->last_wifi_category_index);
2047+
break;
2048+
case 10:
2049+
show_wifi_scanning_menu(s);
2050+
submenu_set_selected_item(s->wifi_scanning_menu, s->last_wifi_scanning_index);
2051+
break;
2052+
case 11:
2053+
show_wifi_capture_menu(s);
2054+
submenu_set_selected_item(s->wifi_capture_menu, s->last_wifi_capture_index);
2055+
break;
2056+
case 12:
2057+
show_wifi_attack_menu(s);
2058+
submenu_set_selected_item(s->wifi_attack_menu, s->last_wifi_attack_index);
2059+
break;
2060+
case 13:
2061+
show_wifi_network_menu(s);
2062+
submenu_set_selected_item(s->wifi_network_menu, s->last_wifi_network_index);
2063+
break;
2064+
case 14:
2065+
show_wifi_settings_menu(s);
2066+
submenu_set_selected_item(s->wifi_settings_menu, s->last_wifi_settings_index);
20332067
break;
20342068
case 2:
2035-
show_ble_menu(cmd_ctx->state);
2069+
show_ble_menu(s);
2070+
submenu_set_selected_item(s->ble_menu, s->last_ble_category_index);
2071+
break;
2072+
case 20:
2073+
show_ble_scanning_menu(s);
2074+
submenu_set_selected_item(s->ble_scanning_menu, s->last_ble_scanning_index);
2075+
break;
2076+
case 21:
2077+
show_ble_capture_menu(s);
2078+
submenu_set_selected_item(s->ble_capture_menu, s->last_ble_capture_index);
2079+
break;
2080+
case 22:
2081+
show_ble_attack_menu(s);
2082+
submenu_set_selected_item(s->ble_attack_menu, s->last_ble_attack_index);
20362083
break;
20372084
case 3:
2038-
show_gps_menu(cmd_ctx->state);
2085+
show_gps_menu(s);
2086+
submenu_set_selected_item(s->gps_menu, s->last_gps_index);
2087+
break;
2088+
case 15:
2089+
show_aerial_menu(s);
2090+
submenu_set_selected_item(s->aerial_menu, s->last_aerial_category_index);
2091+
break;
2092+
case 30:
2093+
show_ir_menu(s);
2094+
submenu_set_selected_item(s->ir_menu, s->last_ir_index);
20392095
break;
20402096
default:
2041-
show_main_menu(cmd_ctx->state);
2097+
show_main_menu(s);
20422098
break;
20432099
}
20442100
}

src/settings_storage.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,16 @@ bool settings_storage_init() {
2424

2525
// Attempt to create directory without checking if it exists
2626
if(!storage_simply_mkdir(storage, GHOST_ESP_APP_FOLDER)) {
27-
furi_crash("Can't mkdir! Fuck this SD card!");
27+
FURI_LOG_E("SettingsStorage", "Failed to create app directory");
28+
furi_record_close(RECORD_STORAGE);
29+
storage = NULL;
30+
return false;
2831
}
2932

3033
uint32_t duration = furi_get_tick() - start_time;
3134
FURI_LOG_I(
3235
"SettingsStorage", "Storage initialization complete (Time taken: %lu ms)", duration);
3336

34-
if(!storage) {
35-
FURI_LOG_E("Storage", "Storage system failure!");
36-
furi_crash("Storage fucked");
37-
}
38-
3937
return true;
4038
}
4139

src/settings_ui.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ void clear_log_files(void* context) {
4949
// Open storage once
5050
Storage* storage = furi_record_open(RECORD_STORAGE);
5151
File* dir = storage_file_alloc(storage);
52+
if(!dir) {
53+
furi_record_close(RECORD_STORAGE);
54+
create_new_log(app);
55+
return;
56+
}
5257

5358
if(!storage_dir_open(dir, GHOST_ESP_APP_FOLDER_LOGS)) {
5459
FURI_LOG_E("ClearLogs", "Failed to open logs directory");
@@ -87,7 +92,11 @@ void clear_pcap_files(void* context) {
8792
// Close current file if open
8893
if(app->uart_context && app->uart_context->storageContext &&
8994
app->uart_context->storageContext->current_file) {
90-
storage_file_close(app->uart_context->storageContext->current_file);
95+
if(storage_file_is_open(app->uart_context->storageContext->current_file)) {
96+
storage_file_sync(app->uart_context->storageContext->current_file);
97+
storage_file_close(app->uart_context->storageContext->current_file);
98+
}
99+
app->uart_context->storageContext->HasOpenedFile = false;
91100
}
92101

93102
// Stack allocation for better performance
@@ -99,6 +108,10 @@ void clear_pcap_files(void* context) {
99108
// Open storage once
100109
Storage* storage = furi_record_open(RECORD_STORAGE);
101110
File* dir = storage_file_alloc(storage);
111+
if(!dir) {
112+
furi_record_close(RECORD_STORAGE);
113+
return;
114+
}
102115

103116
if(!storage_dir_open(dir, GHOST_ESP_APP_FOLDER_PCAPS)) {
104117
FURI_LOG_E("ClearPCAPs", "Failed to open pcaps directory");
@@ -137,6 +150,10 @@ void clear_wardrive_files(void* context) {
137150
// Open storage once
138151
Storage* storage = furi_record_open(RECORD_STORAGE);
139152
File* dir = storage_file_alloc(storage);
153+
if(!dir) {
154+
furi_record_close(RECORD_STORAGE);
155+
return;
156+
}
140157

141158
if(!storage_dir_open(dir, GHOST_ESP_APP_FOLDER_WARDRIVE)) {
142159
FURI_LOG_E("ClearWardrive", "Failed to open wardrive directory");
@@ -581,13 +598,12 @@ bool settings_custom_event_callback(void* context, uint32_t event_id) {
581598

582599
view_dispatcher_switch_to_view(app_state->view_dispatcher, 7);
583600
app_state->current_view = 7;
584-
break;
601+
return true;
585602
}
586603

587604
default:
588605
return false;
589606
}
590-
return false;
591607
}
592608

593609
// 6675636B796F7564656B69

src/uart_storage.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ void uart_storage_rx_callback(uint8_t* buf, size_t len, void* context) {
205205
"Storage",
206206
"Invalid parameters in storage callback: app=%p, storageContext=%p, buf=%p, len=%zu",
207207
(void*)app,
208-
(void*)app->storageContext,
208+
app ? (void*)app->storageContext : NULL,
209209
(void*)buf,
210210
len);
211211
return;
@@ -247,8 +247,14 @@ void uart_storage_rx_callback(uint8_t* buf, size_t len, void* context) {
247247
}
248248
FURI_LOG_D("Storage", "Data Checksum (XOR): 0x%02X", checksum);
249249

250-
// Periodic sync every ~8KB to balance between safety and performance with detailed logging
250+
// Periodic sync every ~8KB to balance between safety and performance
251251
static size_t bytes_since_sync = 0;
252+
253+
// Reset counter if this is the first write to a new file session
254+
if(bytes_since_sync > 8192 && app->storageContext->HasOpenedFile) {
255+
bytes_since_sync = 0;
256+
}
257+
252258
bytes_since_sync += len;
253259
FURI_LOG_D("Storage", "Accumulated %zu bytes since last sync", bytes_since_sync);
254260
if(bytes_since_sync >= 8192) {

src/uart_utils.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,10 @@ void handle_uart_rx_data(uint8_t* buf, size_t len, void* context) {
367367
state->uart_context->storageContext->HasOpenedFile) {
368368
static size_t bytes_since_sync = 0;
369369

370+
if(bytes_since_sync > 1024 && state->uart_context->storageContext->HasOpenedFile) {
371+
bytes_since_sync = 0;
372+
}
373+
370374
size_t written =
371375
storage_file_write(state->uart_context->storageContext->log_file, buf, len);
372376

src/utils.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ void show_confirmation_dialog_ex(
4848
}
4949

5050
confirm_ctx->state = state;
51+
if(state->active_confirm_context) {
52+
free(state->active_confirm_context);
53+
}
5154
state->active_confirm_context = confirm_ctx;
5255

5356
// Set up the confirmation dialog

0 commit comments

Comments
 (0)