mirror of
https://gitlab.com/Theopse/fbi-i18n-zh.git
synced 2025-05-29 03:09:15 +08:00
Make copy of target item to prevent use-after-free issues.
This commit is contained in:
parent
4eb7586237
commit
adbd41dabf
@ -17,9 +17,9 @@
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
linked_list* items;
|
linked_list* items;
|
||||||
|
|
||||||
|
list_item* targetItem;
|
||||||
file_info* target;
|
file_info* target;
|
||||||
FS_Archive archive;
|
|
||||||
char path[FILE_PATH_MAX];
|
|
||||||
|
|
||||||
linked_list contents;
|
linked_list contents;
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ static void action_delete_draw_top(ui_view* view, void* data, float x1, float y1
|
|||||||
u32 curr = deleteData->deleteInfo.processed;
|
u32 curr = deleteData->deleteInfo.processed;
|
||||||
if(curr < deleteData->deleteInfo.total) {
|
if(curr < deleteData->deleteInfo.total) {
|
||||||
ui_draw_file_info(view, ((list_item*) linked_list_get(&deleteData->contents, linked_list_size(&deleteData->contents) - curr - 1))->data, x1, y1, x2, y2);
|
ui_draw_file_info(view, ((list_item*) linked_list_get(&deleteData->contents, linked_list_size(&deleteData->contents) - curr - 1))->data, x1, y1, x2, y2);
|
||||||
} else if(deleteData->target != NULL) {
|
} else {
|
||||||
ui_draw_file_info(view, deleteData->target, x1, y1, x2, y2);
|
ui_draw_file_info(view, deleteData->target, x1, y1, x2, y2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -46,10 +46,10 @@ static Result action_delete_delete(void* data, u32 index) {
|
|||||||
|
|
||||||
FS_Path* fsPath = util_make_path_utf8(info->path);
|
FS_Path* fsPath = util_make_path_utf8(info->path);
|
||||||
if(fsPath != NULL) {
|
if(fsPath != NULL) {
|
||||||
if(util_is_dir(deleteData->archive, info->path)) {
|
if(util_is_dir(deleteData->target->archive, info->path)) {
|
||||||
res = FSUSER_DeleteDirectory(deleteData->archive, *fsPath);
|
res = FSUSER_DeleteDirectory(deleteData->target->archive, *fsPath);
|
||||||
} else {
|
} else {
|
||||||
res = FSUSER_DeleteFile(deleteData->archive, *fsPath);
|
res = FSUSER_DeleteFile(deleteData->target->archive, *fsPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
util_free_path_utf8(fsPath);
|
util_free_path_utf8(fsPath);
|
||||||
@ -66,10 +66,6 @@ static Result action_delete_delete(void* data, u32 index) {
|
|||||||
file_info* currInfo = (file_info*) item->data;
|
file_info* currInfo = (file_info*) item->data;
|
||||||
|
|
||||||
if(strncmp(currInfo->path, info->path, FILE_PATH_MAX) == 0) {
|
if(strncmp(currInfo->path, info->path, FILE_PATH_MAX) == 0) {
|
||||||
if(currInfo == deleteData->target) {
|
|
||||||
deleteData->target = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
linked_list_iter_remove(&iter);
|
linked_list_iter_remove(&iter);
|
||||||
task_free_file(item);
|
task_free_file(item);
|
||||||
}
|
}
|
||||||
@ -106,6 +102,13 @@ static bool action_delete_error(void* data, u32 index, Result res) {
|
|||||||
static void action_delete_free_data(delete_data* data) {
|
static void action_delete_free_data(delete_data* data) {
|
||||||
task_clear_files(&data->contents);
|
task_clear_files(&data->contents);
|
||||||
linked_list_destroy(&data->contents);
|
linked_list_destroy(&data->contents);
|
||||||
|
|
||||||
|
if(data->targetItem != NULL) {
|
||||||
|
task_free_file(data->targetItem);
|
||||||
|
data->targetItem = NULL;
|
||||||
|
data->target = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,7 +116,7 @@ static void action_delete_update(ui_view* view, void* data, float* progress, cha
|
|||||||
delete_data* deleteData = (delete_data*) data;
|
delete_data* deleteData = (delete_data*) data;
|
||||||
|
|
||||||
if(deleteData->deleteInfo.finished) {
|
if(deleteData->deleteInfo.finished) {
|
||||||
FSUSER_ControlArchive(deleteData->archive, ARCHIVE_ACTION_COMMIT_SAVE_DATA, NULL, 0, NULL, 0);
|
FSUSER_ControlArchive(deleteData->target->archive, ARCHIVE_ACTION_COMMIT_SAVE_DATA, NULL, 0, NULL, 0);
|
||||||
|
|
||||||
ui_pop();
|
ui_pop();
|
||||||
info_destroy(view);
|
info_destroy(view);
|
||||||
@ -143,7 +146,7 @@ static void action_delete_onresponse(ui_view* view, void* data, bool response) {
|
|||||||
if(R_SUCCEEDED(res)) {
|
if(R_SUCCEEDED(res)) {
|
||||||
info_display("Deleting", "Press B to cancel.", true, data, action_delete_update, action_delete_draw_top);
|
info_display("Deleting", "Press B to cancel.", true, data, action_delete_update, action_delete_draw_top);
|
||||||
} else {
|
} else {
|
||||||
error_display_res(deleteData->target, deleteData->target != NULL ? ui_draw_file_info : NULL, res, "Failed to initiate delete operation.");
|
error_display_res(NULL, NULL, res, "Failed to initiate delete operation.");
|
||||||
|
|
||||||
action_delete_free_data(deleteData);
|
action_delete_free_data(deleteData);
|
||||||
}
|
}
|
||||||
@ -202,9 +205,10 @@ static void action_delete_internal(linked_list* items, list_item* selected, cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
data->items = items;
|
data->items = items;
|
||||||
data->target = (file_info*) selected->data;
|
|
||||||
data->archive = data->target->archive;
|
file_info* targetInfo = (file_info*) selected->data;
|
||||||
strncpy(data->path, data->target->path, FILE_PATH_MAX);
|
task_create_file_item(&data->targetItem, targetInfo->archive, targetInfo->path, targetInfo->attributes);
|
||||||
|
data->target = (file_info*) data->targetItem->data;
|
||||||
|
|
||||||
data->deleteInfo.data = data;
|
data->deleteInfo.data = data;
|
||||||
|
|
||||||
@ -233,8 +237,8 @@ static void action_delete_internal(linked_list* items, list_item* selected, cons
|
|||||||
loadingData->message = message;
|
loadingData->message = message;
|
||||||
|
|
||||||
loadingData->popData.items = &data->contents;
|
loadingData->popData.items = &data->contents;
|
||||||
loadingData->popData.archive = data->archive;
|
loadingData->popData.archive = data->target->archive;
|
||||||
strncpy(loadingData->popData.path, data->path, FILE_PATH_MAX);
|
strncpy(loadingData->popData.path, data->target->path, FILE_PATH_MAX);
|
||||||
loadingData->popData.recursive = recursive;
|
loadingData->popData.recursive = recursive;
|
||||||
loadingData->popData.includeBase = includeBase;
|
loadingData->popData.includeBase = includeBase;
|
||||||
loadingData->popData.filter = ciasOnly ? util_filter_cias : ticketsOnly ? util_filter_tickets : NULL;
|
loadingData->popData.filter = ciasOnly ? util_filter_cias : ticketsOnly ? util_filter_tickets : NULL;
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
linked_list* items;
|
linked_list* items;
|
||||||
|
|
||||||
|
list_item* targetItem;
|
||||||
file_info* target;
|
file_info* target;
|
||||||
|
|
||||||
linked_list contents;
|
linked_list contents;
|
||||||
@ -39,7 +41,7 @@ static void action_install_cias_draw_top(ui_view* view, void* data, float x1, fl
|
|||||||
u32 curr = installData->installInfo.processed;
|
u32 curr = installData->installInfo.processed;
|
||||||
if(curr < installData->installInfo.total) {
|
if(curr < installData->installInfo.total) {
|
||||||
ui_draw_file_info(view, ((list_item*) linked_list_get(&installData->contents, curr))->data, x1, y1, x2, y2);
|
ui_draw_file_info(view, ((list_item*) linked_list_get(&installData->contents, curr))->data, x1, y1, x2, y2);
|
||||||
} else if(installData->target != NULL) {
|
} else {
|
||||||
ui_draw_file_info(view, installData->target, x1, y1, x2, y2);
|
ui_draw_file_info(view, installData->target, x1, y1, x2, y2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -212,6 +214,13 @@ bool action_install_cias_error(void* data, u32 index, Result res) {
|
|||||||
static void action_install_cias_free_data(install_cias_data* data) {
|
static void action_install_cias_free_data(install_cias_data* data) {
|
||||||
task_clear_files(&data->contents);
|
task_clear_files(&data->contents);
|
||||||
linked_list_destroy(&data->contents);
|
linked_list_destroy(&data->contents);
|
||||||
|
|
||||||
|
if(data->targetItem != NULL) {
|
||||||
|
task_free_file(data->targetItem);
|
||||||
|
data->targetItem = NULL;
|
||||||
|
data->target = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,7 +319,10 @@ static void action_install_cias_internal(linked_list* items, list_item* selected
|
|||||||
}
|
}
|
||||||
|
|
||||||
data->items = items;
|
data->items = items;
|
||||||
data->target = (file_info*) selected->data;
|
|
||||||
|
file_info* targetInfo = (file_info*) selected->data;
|
||||||
|
task_create_file_item(&data->targetItem, targetInfo->archive, targetInfo->path, targetInfo->attributes);
|
||||||
|
data->target = (file_info*) data->targetItem->data;
|
||||||
|
|
||||||
data->delete = delete;
|
data->delete = delete;
|
||||||
|
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
linked_list* items;
|
linked_list* items;
|
||||||
|
|
||||||
|
list_item* targetItem;
|
||||||
file_info* target;
|
file_info* target;
|
||||||
|
|
||||||
linked_list contents;
|
linked_list contents;
|
||||||
@ -33,7 +35,7 @@ static void action_install_tickets_draw_top(ui_view* view, void* data, float x1,
|
|||||||
u32 curr = installData->installInfo.processed;
|
u32 curr = installData->installInfo.processed;
|
||||||
if(curr < installData->installInfo.total) {
|
if(curr < installData->installInfo.total) {
|
||||||
ui_draw_file_info(view, ((list_item*) linked_list_get(&installData->contents, curr))->data, x1, y1, x2, y2);
|
ui_draw_file_info(view, ((list_item*) linked_list_get(&installData->contents, curr))->data, x1, y1, x2, y2);
|
||||||
} else if(installData->target != NULL) {
|
} else {
|
||||||
ui_draw_file_info(view, installData->target, x1, y1, x2, y2);
|
ui_draw_file_info(view, installData->target, x1, y1, x2, y2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -172,6 +174,13 @@ static bool action_install_tickets_error(void* data, u32 index, Result res) {
|
|||||||
static void action_install_tickets_free_data(install_tickets_data* data) {
|
static void action_install_tickets_free_data(install_tickets_data* data) {
|
||||||
task_clear_files(&data->contents);
|
task_clear_files(&data->contents);
|
||||||
linked_list_destroy(&data->contents);
|
linked_list_destroy(&data->contents);
|
||||||
|
|
||||||
|
if(data->targetItem != NULL) {
|
||||||
|
task_free_file(data->targetItem);
|
||||||
|
data->targetItem = NULL;
|
||||||
|
data->target = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,7 +285,10 @@ static void action_install_tickets_internal(linked_list* items, list_item* selec
|
|||||||
}
|
}
|
||||||
|
|
||||||
data->items = items;
|
data->items = items;
|
||||||
data->target = (file_info*) selected->data;
|
|
||||||
|
file_info* targetInfo = (file_info*) selected->data;
|
||||||
|
task_create_file_item(&data->targetItem, targetInfo->archive, targetInfo->path, targetInfo->attributes);
|
||||||
|
data->target = (file_info*) data->targetItem->data;
|
||||||
|
|
||||||
data->delete = delete;
|
data->delete = delete;
|
||||||
|
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
linked_list* items;
|
linked_list* items;
|
||||||
|
|
||||||
|
list_item* targetItem;
|
||||||
file_info* target;
|
file_info* target;
|
||||||
|
|
||||||
linked_list contents;
|
linked_list contents;
|
||||||
@ -31,7 +33,7 @@ static void action_paste_contents_draw_top(ui_view* view, void* data, float x1,
|
|||||||
u32 curr = pasteData->pasteInfo.processed;
|
u32 curr = pasteData->pasteInfo.processed;
|
||||||
if(curr < pasteData->pasteInfo.total) {
|
if(curr < pasteData->pasteInfo.total) {
|
||||||
ui_draw_file_info(view, ((list_item*) linked_list_get(&pasteData->contents, curr))->data, x1, y1, x2, y2);
|
ui_draw_file_info(view, ((list_item*) linked_list_get(&pasteData->contents, curr))->data, x1, y1, x2, y2);
|
||||||
} else if(pasteData->target != NULL) {
|
} else {
|
||||||
ui_draw_file_info(view, pasteData->target, x1, y1, x2, y2);
|
ui_draw_file_info(view, pasteData->target, x1, y1, x2, y2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -246,6 +248,13 @@ static bool action_paste_contents_error(void* data, u32 index, Result res) {
|
|||||||
static void action_paste_contents_free_data(paste_contents_data* data) {
|
static void action_paste_contents_free_data(paste_contents_data* data) {
|
||||||
task_clear_files(&data->contents);
|
task_clear_files(&data->contents);
|
||||||
linked_list_destroy(&data->contents);
|
linked_list_destroy(&data->contents);
|
||||||
|
|
||||||
|
if(data->targetItem != NULL) {
|
||||||
|
task_free_file(data->targetItem);
|
||||||
|
data->targetItem = NULL;
|
||||||
|
data->target = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,7 +293,7 @@ static void action_paste_contents_onresponse(ui_view* view, void* data, bool res
|
|||||||
if(R_SUCCEEDED(res)) {
|
if(R_SUCCEEDED(res)) {
|
||||||
info_display("Pasting Contents", "Press B to cancel.", true, data, action_paste_contents_update, action_paste_contents_draw_top);
|
info_display("Pasting Contents", "Press B to cancel.", true, data, action_paste_contents_update, action_paste_contents_draw_top);
|
||||||
} else {
|
} else {
|
||||||
error_display_res(pasteData->target, ui_draw_file_info, res, "Failed to initiate paste operation.");
|
error_display_res(NULL, NULL, res, "Failed to initiate paste operation.");
|
||||||
|
|
||||||
action_paste_contents_free_data(pasteData);
|
action_paste_contents_free_data(pasteData);
|
||||||
}
|
}
|
||||||
@ -346,7 +355,10 @@ void action_paste_contents(linked_list* items, list_item* selected) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
data->items = items;
|
data->items = items;
|
||||||
data->target = (file_info*) selected->data;
|
|
||||||
|
file_info* targetInfo = (file_info*) selected->data;
|
||||||
|
task_create_file_item(&data->targetItem, targetInfo->archive, targetInfo->path, targetInfo->attributes);
|
||||||
|
data->target = (file_info*) data->targetItem->data;
|
||||||
|
|
||||||
data->pasteInfo.data = data;
|
data->pasteInfo.data = data;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user