[FL-2431, FL-2419] SubGhz: bugfixes (#1098)

* [FL-2431] SubGhz: fix Restart with an error (HardFault), while maintaining the RAW signal.
* Stream: fix adding maximum string length to arguments
* [FL-2419] SubGhz: fix flipper hang/Fatal Error when running edited Sub-GHz file.
* SubGhz: remove replace strcpy with strncpy, smaller text buffer and canary
* SubGhz: log key loading before load happen, rollback only rx message handling

Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
Skorpionm 2022-04-07 15:47:47 +04:00 committed by GitHub
parent 321f36d113
commit 02b9cf90d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 41 additions and 26 deletions

View File

@ -297,13 +297,15 @@ bool storage_simply_mkdir(Storage* storage, const char* path);
* @param filename * @param filename
* @param fileextension * @param fileextension
* @param nextfilename return name * @param nextfilename return name
* @param max_len max len name
*/ */
void storage_get_next_filename( void storage_get_next_filename(
Storage* storage, Storage* storage,
const char* dirname, const char* dirname,
const char* filename, const char* filename,
const char* fileextension, const char* fileextension,
string_t nextfilename); string_t nextfilename,
uint8_t max_len);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -556,7 +556,8 @@ void storage_get_next_filename(
const char* dirname, const char* dirname,
const char* filename, const char* filename,
const char* fileextension, const char* fileextension,
string_t nextfilename) { string_t nextfilename,
uint8_t max_len) {
string_t temp_str; string_t temp_str;
uint16_t num = 0; uint16_t num = 0;
@ -566,8 +567,7 @@ void storage_get_next_filename(
num++; num++;
string_printf(temp_str, "%s/%s%d%s", dirname, filename, num, fileextension); string_printf(temp_str, "%s/%s%d%s", dirname, filename, num, fileextension);
} }
if(num && (max_len > strlen(filename))) {
if(num) {
string_printf(nextfilename, "%s%d", filename, num); string_printf(nextfilename, "%s%d", filename, num);
} else { } else {
string_printf(nextfilename, "%s", filename); string_printf(nextfilename, "%s", filename);

View File

@ -49,7 +49,7 @@ bool subghz_scene_delete_on_event(void* context, SceneManagerEvent event) {
SubGhz* subghz = context; SubGhz* subghz = context;
if(event.type == SceneManagerEventTypeCustom) { if(event.type == SceneManagerEventTypeCustom) {
if(event.event == SubGhzCustomEventSceneDelete) { if(event.event == SubGhzCustomEventSceneDelete) {
strcpy(subghz->file_name_tmp, subghz->file_name); strncpy(subghz->file_name_tmp, subghz->file_name, SUBGHZ_MAX_LEN_NAME);
if(subghz_delete_file(subghz)) { if(subghz_delete_file(subghz)) {
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneDeleteSuccess); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneDeleteSuccess);
} else { } else {

View File

@ -56,7 +56,7 @@ bool subghz_scene_delete_raw_on_event(void* context, SceneManagerEvent event) {
SubGhz* subghz = context; SubGhz* subghz = context;
if(event.type == SceneManagerEventTypeCustom) { if(event.type == SceneManagerEventTypeCustom) {
if(event.event == SubGhzCustomEventSceneDeleteRAW) { if(event.event == SubGhzCustomEventSceneDeleteRAW) {
strcpy(subghz->file_name_tmp, subghz->file_name); strncpy(subghz->file_name_tmp, subghz->file_name, SUBGHZ_MAX_LEN_NAME);
if(subghz_delete_file(subghz)) { if(subghz_delete_file(subghz)) {
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneDeleteSuccess); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneDeleteSuccess);
} else { } else {

View File

@ -24,7 +24,7 @@ bool subghz_scene_read_raw_update_filename(SubGhz* subghz) {
} }
path_extract_filename_no_ext(string_get_cstr(temp_str), temp_str); path_extract_filename_no_ext(string_get_cstr(temp_str), temp_str);
strcpy(subghz->file_name, string_get_cstr(temp_str)); strncpy(subghz->file_name, string_get_cstr(temp_str), SUBGHZ_MAX_LEN_NAME);
ret = true; ret = true;
} while(false); } while(false);

View File

@ -22,10 +22,10 @@ void subghz_scene_save_name_on_enter(void* context) {
//highlighting the entire filename by default //highlighting the entire filename by default
dev_name_empty = true; dev_name_empty = true;
} else { } else {
strcpy(subghz->file_name_tmp, subghz->file_name); strncpy(subghz->file_name_tmp, subghz->file_name, SUBGHZ_MAX_LEN_NAME);
if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) != if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) !=
SubGhzCustomEventManagerNoSet) { SubGhzCustomEventManagerNoSet) {
subghz_get_next_name_file(subghz); subghz_get_next_name_file(subghz, SUBGHZ_MAX_LEN_NAME);
if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) == if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) ==
SubGhzCustomEventManagerSetRAW) { SubGhzCustomEventManagerSetRAW) {
dev_name_empty = true; dev_name_empty = true;
@ -39,7 +39,7 @@ void subghz_scene_save_name_on_enter(void* context) {
subghz_scene_save_name_text_input_callback, subghz_scene_save_name_text_input_callback,
subghz, subghz,
subghz->file_name, subghz->file_name,
22, //Max len name SUBGHZ_MAX_LEN_NAME + 1, // buffer size
dev_name_empty); dev_name_empty);
ValidatorIsFile* validator_is_file = ValidatorIsFile* validator_is_file =
@ -52,7 +52,7 @@ void subghz_scene_save_name_on_enter(void* context) {
bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) { bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) {
SubGhz* subghz = context; SubGhz* subghz = context;
if(event.type == SceneManagerEventTypeBack) { if(event.type == SceneManagerEventTypeBack) {
strcpy(subghz->file_name, subghz->file_name_tmp); strncpy(subghz->file_name, subghz->file_name_tmp, SUBGHZ_MAX_LEN_NAME);
scene_manager_previous_scene(subghz->scene_manager); scene_manager_previous_scene(subghz->scene_manager);
return true; return true;
} else if(event.type == SceneManagerEventTypeCustom) { } else if(event.type == SceneManagerEventTypeCustom) {

View File

@ -296,6 +296,10 @@ void subghz_free(SubGhz* subghz) {
furi_record_close("notification"); furi_record_close("notification");
subghz->notifications = NULL; subghz->notifications = NULL;
// About birds
furi_assert(subghz->file_name[SUBGHZ_MAX_LEN_NAME] == 0);
furi_assert(subghz->file_name_tmp[SUBGHZ_MAX_LEN_NAME] == 0);
// The rest // The rest
free(subghz); free(subghz);
} }
@ -315,7 +319,7 @@ int32_t subghz_app(void* p) {
string_init(filename); string_init(filename);
path_extract_filename_no_ext(p, filename); path_extract_filename_no_ext(p, filename);
strcpy(subghz->file_name, string_get_cstr(filename)); strncpy(subghz->file_name, string_get_cstr(filename), SUBGHZ_MAX_LEN_NAME);
string_clear(filename); string_clear(filename);
if((!strcmp(subghz->txrx->decoder_result->protocol->name, "RAW"))) { if((!strcmp(subghz->txrx->decoder_result->protocol->name, "RAW"))) {
//Load Raw TX //Load Raw TX

24
applications/subghz/subghz_i.c Executable file → Normal file
View File

@ -208,7 +208,7 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path) {
bool loaded = false; bool loaded = false;
string_t temp_str; string_t temp_str;
string_init(temp_str); string_init(temp_str);
uint32_t version; uint32_t temp_data32;
do { do {
stream_clean(fff_data_stream); stream_clean(fff_data_stream);
@ -217,25 +217,30 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path) {
break; break;
} }
if(!flipper_format_read_header(fff_data_file, temp_str, &version)) { if(!flipper_format_read_header(fff_data_file, temp_str, &temp_data32)) {
FURI_LOG_E(TAG, "Missing or incorrect header"); FURI_LOG_E(TAG, "Missing or incorrect header");
break; break;
} }
if(((!strcmp(string_get_cstr(temp_str), SUBGHZ_KEY_FILE_TYPE)) || if(((!strcmp(string_get_cstr(temp_str), SUBGHZ_KEY_FILE_TYPE)) ||
(!strcmp(string_get_cstr(temp_str), SUBGHZ_RAW_FILE_TYPE))) && (!strcmp(string_get_cstr(temp_str), SUBGHZ_RAW_FILE_TYPE))) &&
version == SUBGHZ_KEY_FILE_VERSION) { temp_data32 == SUBGHZ_KEY_FILE_VERSION) {
} else { } else {
FURI_LOG_E(TAG, "Type or version mismatch"); FURI_LOG_E(TAG, "Type or version mismatch");
break; break;
} }
if(!flipper_format_read_uint32( if(!flipper_format_read_uint32(fff_data_file, "Frequency", (uint32_t*)&temp_data32, 1)) {
fff_data_file, "Frequency", (uint32_t*)&subghz->txrx->frequency, 1)) {
FURI_LOG_E(TAG, "Missing Frequency"); FURI_LOG_E(TAG, "Missing Frequency");
break; break;
} }
if(!furi_hal_subghz_is_frequency_valid(temp_data32)) {
FURI_LOG_E(TAG, "Frequency not supported");
break;
}
subghz->txrx->frequency = temp_data32;
if(!flipper_format_read_string(fff_data_file, "Preset", temp_str)) { if(!flipper_format_read_string(fff_data_file, "Preset", temp_str)) {
FURI_LOG_E(TAG, "Missing Preset"); FURI_LOG_E(TAG, "Missing Preset");
break; break;
@ -267,6 +272,9 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path) {
if(subghz->txrx->decoder_result) { if(subghz->txrx->decoder_result) {
subghz_protocol_decoder_base_deserialize( subghz_protocol_decoder_base_deserialize(
subghz->txrx->decoder_result, subghz->txrx->fff_data); subghz->txrx->decoder_result, subghz->txrx->fff_data);
} else {
FURI_LOG_E(TAG, "Protocol not found");
break;
} }
loaded = true; loaded = true;
@ -283,7 +291,7 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path) {
return loaded; return loaded;
} }
bool subghz_get_next_name_file(SubGhz* subghz) { bool subghz_get_next_name_file(SubGhz* subghz, uint8_t max_len) {
furi_assert(subghz); furi_assert(subghz);
Storage* storage = furi_record_open("storage"); Storage* storage = furi_record_open("storage");
@ -294,9 +302,9 @@ bool subghz_get_next_name_file(SubGhz* subghz) {
if(strcmp(subghz->file_name, "")) { if(strcmp(subghz->file_name, "")) {
//get the name of the next free file //get the name of the next free file
storage_get_next_filename( storage_get_next_filename(
storage, SUBGHZ_RAW_FOLDER, subghz->file_name, SUBGHZ_APP_EXTENSION, temp_str); storage, SUBGHZ_RAW_FOLDER, subghz->file_name, SUBGHZ_APP_EXTENSION, temp_str, max_len);
strcpy(subghz->file_name, string_get_cstr(temp_str)); strncpy(subghz->file_name, string_get_cstr(temp_str), SUBGHZ_MAX_LEN_NAME);
res = true; res = true;
} }

View File

@ -33,7 +33,7 @@
#include <gui/modules/variable_item_list.h> #include <gui/modules/variable_item_list.h>
#define SUBGHZ_TEXT_STORE_SIZE 40 #define SUBGHZ_MAX_LEN_NAME 21
extern const char* const subghz_frequencies_text[]; extern const char* const subghz_frequencies_text[];
extern const uint32_t subghz_frequencies[]; extern const uint32_t subghz_frequencies[];
@ -115,8 +115,8 @@ struct SubGhz {
TextInput* text_input; TextInput* text_input;
Widget* widget; Widget* widget;
DialogsApp* dialogs; DialogsApp* dialogs;
char file_name[SUBGHZ_TEXT_STORE_SIZE + 1]; char file_name[SUBGHZ_MAX_LEN_NAME + 1];
char file_name_tmp[SUBGHZ_TEXT_STORE_SIZE + 1]; char file_name_tmp[SUBGHZ_MAX_LEN_NAME + 1];
SubGhzNotificationState state_notifications; SubGhzNotificationState state_notifications;
SubGhzViewReceiver* subghz_receiver; SubGhzViewReceiver* subghz_receiver;
@ -156,7 +156,7 @@ void subghz_sleep(SubGhz* subghz);
bool subghz_tx_start(SubGhz* subghz, FlipperFormat* flipper_format); bool subghz_tx_start(SubGhz* subghz, FlipperFormat* flipper_format);
void subghz_tx_stop(SubGhz* subghz); void subghz_tx_stop(SubGhz* subghz);
bool subghz_key_load(SubGhz* subghz, const char* file_path); bool subghz_key_load(SubGhz* subghz, const char* file_path);
bool subghz_get_next_name_file(SubGhz* subghz); bool subghz_get_next_name_file(SubGhz* subghz, uint8_t max_len);
bool subghz_save_protocol_to_file( bool subghz_save_protocol_to_file(
SubGhz* subghz, SubGhz* subghz,
FlipperFormat* flipper_format, FlipperFormat* flipper_format,

View File

@ -187,6 +187,8 @@ bool subghz_keystore_load(SubGhzKeystore* instance, const char* file_name) {
string_t filetype; string_t filetype;
string_init(filetype); string_init(filetype);
FURI_LOG_I(TAG, "Loading keystore %s", file_name);
Storage* storage = furi_record_open("storage"); Storage* storage = furi_record_open("storage");
FlipperFormat* flipper_format = flipper_format_file_alloc(storage); FlipperFormat* flipper_format = flipper_format_file_alloc(storage);
@ -224,7 +226,6 @@ bool subghz_keystore_load(SubGhzKeystore* instance, const char* file_name) {
FURI_LOG_E(TAG, "Unknown encryption"); FURI_LOG_E(TAG, "Unknown encryption");
break; break;
} }
FURI_LOG_I(TAG, "Loading keystore %s", file_name);
} while(0); } while(0);
flipper_format_free(flipper_format); flipper_format_free(flipper_format);

View File

@ -176,7 +176,7 @@ static bool file_stream_delete_and_insert(
string_t scratch_name; string_t scratch_name;
string_t tmp_name; string_t tmp_name;
string_init(tmp_name); string_init(tmp_name);
storage_get_next_filename(_stream->storage, "/any", ".scratch", ".pad", tmp_name); storage_get_next_filename(_stream->storage, "/any", ".scratch", ".pad", tmp_name, 255);
string_init_printf(scratch_name, "/any/%s.pad", string_get_cstr(tmp_name)); string_init_printf(scratch_name, "/any/%s.pad", string_get_cstr(tmp_name));
string_clear(tmp_name); string_clear(tmp_name);