ソースを参照

Fix memory leaks

DocSystem 1 年間 前
コミット
34a1fa47dd

+ 6 - 2
api/calypso/calypso_util.c

@@ -13,7 +13,7 @@ CalypsoElement make_calypso_final_element(
     final_element.final = malloc(sizeof(CalypsoFinalElement));
     final_element.final->size = size;
     final_element.final->final_type = final_type;
-    strncpy(final_element.final->key, key, 64);
+    strncpy(final_element.final->key, key, 36);
     strncpy(final_element.final->label, label, 64);
 
     return final_element;
@@ -29,7 +29,7 @@ CalypsoElement make_calypso_bitmap_element(const char* key, int size, CalypsoEle
     for(int i = 0; i < size; i++) {
         bitmap_element.bitmap->elements[i] = elements[i];
     }
-    strncpy(bitmap_element.bitmap->key, key, 64);
+    strncpy(bitmap_element.bitmap->key, key, 36);
 
     return bitmap_element;
 }
@@ -92,11 +92,13 @@ bool is_calypso_subnode_present(
         CalypsoElement* element = &bitmap->elements[positions[i]];
         if(element->type == CALYPSO_ELEMENT_TYPE_FINAL) {
             if(strcmp(element->final->key, key) == 0) {
+                free(positions);
                 return true;
             }
             offset += element->final->size;
         } else {
             if(strcmp(element->bitmap->key, key) == 0) {
+                free(positions);
                 return true;
             }
             int sub_binary_string_size = element->bitmap->size;
@@ -104,11 +106,13 @@ bool is_calypso_subnode_present(
             strncpy(bit_slice, binary_string, sub_binary_string_size);
             bit_slice[sub_binary_string_size] = '\0';
             if(is_calypso_subnode_present(binary_string + offset, key, element->bitmap)) {
+                free(positions);
                 return true;
             }
             offset += element->bitmap->size;
         }
     }
+    free(positions);
     return false;
 }
 

+ 2 - 2
api/calypso/calypso_util.h

@@ -39,14 +39,14 @@ typedef struct {
 } CalypsoElement;
 
 struct CalypsoFinalElement_t {
-    char key[64];
+    char key[36];
     int size;
     char label[64];
     CalypsoFinalType final_type;
 };
 
 struct CalypsoBitmapElement_t {
-    char key[64];
+    char key[36];
     int size;
     CalypsoElement* elements;
 };

+ 4 - 0
metroflip_i.h

@@ -43,6 +43,8 @@ extern const Icon I_RFIDDolphinReceive_97x61;
 
 #include "scenes/metroflip_scene.h"
 
+#include "scenes/navigo_structs.h"
+
 typedef struct {
     Gui* gui;
     SceneManager* scene_manager;
@@ -71,6 +73,8 @@ typedef struct {
     char currency[4];
     char card_type[32];
 
+    // Navigo specific context
+    NavigoContext* navigo_context;
 } Metroflip;
 
 enum MetroflipCustomEvent {

+ 32 - 17
scenes/metroflip_scene_navigo.c

@@ -458,7 +458,9 @@ void show_environment_info(NavigoCardEnv* environment, FuriString* parsed_data)
     furi_string_cat_printf(parsed_data, "\n");
 }
 
-void update_page_info(NavigoContext* ctx, FuriString* parsed_data) {
+void update_page_info(void* context, FuriString* parsed_data) {
+    Metroflip* app = context;
+    NavigoContext* ctx = app->navigo_context;
     if(ctx->page_id == 0) {
         furi_string_cat_printf(
             parsed_data, "\e#%s :\n", get_navigo_type(ctx->card->holder.card_status));
@@ -484,7 +486,10 @@ void update_page_info(NavigoContext* ctx, FuriString* parsed_data) {
     }
 }
 
-void update_widget_elements(Widget* widget, NavigoContext* ctx, void* context) {
+void update_widget_elements(void* context) {
+    Metroflip* app = context;
+    NavigoContext* ctx = app->navigo_context;
+    Widget* widget = app->widget;
     if(ctx->page_id < 5) {
         widget_add_button_element(
             widget, GuiButtonTypeRight, "Next", metroflip_next_button_widget_callback, context);
@@ -499,8 +504,8 @@ void update_widget_elements(Widget* widget, NavigoContext* ctx, void* context) {
 }
 
 void metroflip_back_button_widget_callback(GuiButtonType result, InputType type, void* context) {
-    NavigoContext* ctx = context;
-    Metroflip* app = ctx->app;
+    Metroflip* app = context;
+    NavigoContext* ctx = app->navigo_context;
     UNUSED(result);
 
     Widget* widget = app->widget;
@@ -521,7 +526,7 @@ void metroflip_back_button_widget_callback(GuiButtonType result, InputType type,
 
         // Ensure no nested mutexes
         furi_mutex_acquire(ctx->mutex, FuriWaitForever);
-        update_page_info(ctx, parsed_data);
+        update_page_info(app, parsed_data);
         furi_mutex_release(ctx->mutex);
 
         widget_add_text_scroll_element(widget, 0, 0, 128, 64, furi_string_get_cstr(parsed_data));
@@ -529,7 +534,7 @@ void metroflip_back_button_widget_callback(GuiButtonType result, InputType type,
 
         // Ensure no nested mutexes
         furi_mutex_acquire(ctx->mutex, FuriWaitForever);
-        update_widget_elements(widget, ctx, context);
+        update_widget_elements(app);
         furi_mutex_release(ctx->mutex);
 
         furi_string_free(parsed_data);
@@ -537,8 +542,8 @@ void metroflip_back_button_widget_callback(GuiButtonType result, InputType type,
 }
 
 void metroflip_next_button_widget_callback(GuiButtonType result, InputType type, void* context) {
-    NavigoContext* ctx = context;
-    Metroflip* app = ctx->app;
+    Metroflip* app = context;
+    NavigoContext* ctx = app->navigo_context;
     UNUSED(result);
 
     Widget* widget = app->widget;
@@ -557,20 +562,21 @@ void metroflip_next_button_widget_callback(GuiButtonType result, InputType type,
             ctx->page_id = 0;
             scene_manager_search_and_switch_to_previous_scene(
                 app->scene_manager, MetroflipSceneStart);
+            return;
         }
 
         FuriString* parsed_data = furi_string_alloc();
 
         // Ensure no nested mutexes
         furi_mutex_acquire(ctx->mutex, FuriWaitForever);
-        update_page_info(ctx, parsed_data);
+        update_page_info(app, parsed_data);
         furi_mutex_release(ctx->mutex);
 
         widget_add_text_scroll_element(widget, 0, 0, 128, 64, furi_string_get_cstr(parsed_data));
 
         // Ensure no nested mutexes
         furi_mutex_acquire(ctx->mutex, FuriWaitForever);
-        update_widget_elements(widget, ctx, context);
+        update_widget_elements(app);
         furi_mutex_release(ctx->mutex);
 
         furi_string_free(parsed_data);
@@ -612,12 +618,9 @@ static NfcCommand metroflip_scene_navigo_poller_callback(NfcGenericEvent event,
             size_t response_length = 0;
 
             do {
+                // Initialize the card data
                 NavigoCardData* card = malloc(sizeof(NavigoCardData));
 
-                // Initialize the card
-                card->contracts = malloc(2 * sizeof(NavigoCardContract));
-                card->events = malloc(3 * sizeof(NavigoCardEvent));
-
                 // Select app for contracts
                 error =
                     select_new_app(0x20, tx_buffer, rx_buffer, iso14443_4b_poller, app, &stage);
@@ -1175,6 +1178,10 @@ static NfcCommand metroflip_scene_navigo_poller_callback(NfcGenericEvent event,
                     card->events[i - 1].date.minute = ((decimal_value * 60) % 3600) / 60;
                     card->events[i - 1].date.second = ((decimal_value * 60) % 3600) % 60;
                 }
+
+                // Free the calypso structure
+                free_calypso_structure(NavigoEventStructure);
+
                 UNUSED(TRANSITION_LIST);
                 UNUSED(TRANSPORT_LIST);
                 UNUSED(SERVICE_PROVIDERS);
@@ -1183,14 +1190,14 @@ static NfcCommand metroflip_scene_navigo_poller_callback(NfcGenericEvent event,
                     widget, 0, 0, 128, 64, furi_string_get_cstr(parsed_data));
 
                 NavigoContext* context = malloc(sizeof(NavigoContext));
-                context->app = app;
                 context->card = card;
                 context->page_id = 0;
                 context->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
+                app->navigo_context = context;
 
                 // Ensure no nested mutexes
                 furi_mutex_acquire(context->mutex, FuriWaitForever);
-                update_page_info(context, parsed_data);
+                update_page_info(app, parsed_data);
                 furi_mutex_release(context->mutex);
 
                 widget_add_text_scroll_element(
@@ -1198,7 +1205,7 @@ static NfcCommand metroflip_scene_navigo_poller_callback(NfcGenericEvent event,
 
                 // Ensure no nested mutexes
                 furi_mutex_acquire(context->mutex, FuriWaitForever);
-                update_widget_elements(widget, context, context);
+                update_widget_elements(app);
                 furi_mutex_release(context->mutex);
 
                 furi_string_free(parsed_data);
@@ -1275,4 +1282,12 @@ void metroflip_scene_navigo_on_exit(void* context) {
 
     // Clear view
     popup_reset(app->popup);
+
+    if(app->navigo_context) {
+        NavigoContext* ctx = app->navigo_context;
+        free(ctx->card);
+        furi_mutex_free(ctx->mutex);
+        free(ctx);
+        app->navigo_context = NULL;
+    }
 }

+ 2 - 72
scenes/navigo.h

@@ -1,4 +1,5 @@
-#include "../metroflip_i.h"
+#include <gui/gui.h>
+#include <gui/modules/widget_elements/widget_element.h>
 #include "../api/calypso/calypso_util.h"
 #include "../api/calypso/cards/navigo.h"
 #include <datetime.h>
@@ -13,77 +14,6 @@
 void metroflip_back_button_widget_callback(GuiButtonType result, InputType type, void* context);
 void metroflip_next_button_widget_callback(GuiButtonType result, InputType type, void* context);
 
-typedef struct {
-    int transport_type;
-    int transition;
-    int service_provider;
-    int station_group_id;
-    int station_id;
-    int location_gate;
-    bool location_gate_available;
-    int device;
-    int door;
-    int side;
-    bool device_available;
-    int route_number;
-    bool route_number_available;
-    int mission;
-    bool mission_available;
-    int vehicle_id;
-    bool vehicle_id_available;
-    int used_contract;
-    bool used_contract_available;
-    DateTime date;
-} NavigoCardEvent;
-
-typedef struct {
-    int app_version;
-    int country_num;
-    int network_num;
-    DateTime end_dt;
-} NavigoCardEnv;
-
-typedef struct {
-    int card_status;
-    int commercial_id;
-} NavigoCardHolder;
-
-typedef struct {
-    int tariff;
-    int serial_number;
-    bool serial_number_available;
-    int pay_method;
-    bool pay_method_available;
-    double price_amount;
-    bool price_amount_available;
-    DateTime start_date;
-    DateTime end_date;
-    bool end_date_available;
-    int zones[5];
-    bool zones_available;
-    DateTime sale_date;
-    int sale_agent;
-    int sale_device;
-    int status;
-    int authenticator;
-} NavigoCardContract;
-
-typedef struct {
-    NavigoCardEnv environment;
-    NavigoCardHolder holder;
-    NavigoCardContract* contracts;
-    NavigoCardEvent* events;
-    int ticket_count;
-} NavigoCardData;
-
-typedef struct {
-    Metroflip* app;
-    NavigoCardData* card;
-    int page_id;
-    // mutex
-    FuriMutex* mutex;
-} NavigoContext;
-
 // Service Providers
 static const char* SERVICE_PROVIDERS[] = {
     [2] = "SNCF",

+ 73 - 0
scenes/navigo_structs.h

@@ -0,0 +1,73 @@
+#include <datetime.h>
+#include <stdbool.h>
+#include <furi.h>
+
+typedef struct {
+    int transport_type;
+    int transition;
+    int service_provider;
+    int station_group_id;
+    int station_id;
+    int location_gate;
+    bool location_gate_available;
+    int device;
+    int door;
+    int side;
+    bool device_available;
+    int route_number;
+    bool route_number_available;
+    int mission;
+    bool mission_available;
+    int vehicle_id;
+    bool vehicle_id_available;
+    int used_contract;
+    bool used_contract_available;
+    DateTime date;
+} NavigoCardEvent;
+
+typedef struct {
+    int app_version;
+    int country_num;
+    int network_num;
+    DateTime end_dt;
+} NavigoCardEnv;
+
+typedef struct {
+    int card_status;
+    int commercial_id;
+} NavigoCardHolder;
+
+typedef struct {
+    int tariff;
+    int serial_number;
+    bool serial_number_available;
+    int pay_method;
+    bool pay_method_available;
+    double price_amount;
+    bool price_amount_available;
+    DateTime start_date;
+    DateTime end_date;
+    bool end_date_available;
+    int zones[5];
+    bool zones_available;
+    DateTime sale_date;
+    int sale_agent;
+    int sale_device;
+    int status;
+    int authenticator;
+} NavigoCardContract;
+
+typedef struct {
+    NavigoCardEnv environment;
+    NavigoCardHolder holder;
+    NavigoCardContract contracts[2];
+    NavigoCardEvent events[3];
+    int ticket_count;
+} NavigoCardData;
+
+typedef struct {
+    NavigoCardData* card;
+    int page_id;
+    // mutex
+    FuriMutex* mutex;
+} NavigoContext;