[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:
		
							parent
							
								
									321f36d113
								
							
						
					
					
						commit
						02b9cf90d5
					
				| @ -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 | ||||||
| } | } | ||||||
|  | |||||||
| @ -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); | ||||||
|  | |||||||
| @ -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 { | ||||||
|  | |||||||
| @ -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 { | ||||||
|  | |||||||
| @ -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); | ||||||
|  | |||||||
| @ -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) { | ||||||
|  | |||||||
| @ -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
									
								
							
							
						
						
									
										24
									
								
								applications/subghz/subghz_i.c
									
									
									
									
									
										
										
										Executable file → Normal 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; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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, | ||||||
|  | |||||||
| @ -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); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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); | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Skorpionm
						Skorpionm