From b56f26ec59aed035a8c9c06a5d3ca466b68f9f2c Mon Sep 17 00:00:00 2001 From: Alistair John Strachan Date: Wed, 29 Dec 2010 20:23:40 +0000 Subject: [PATCH] Fixed label list corruption bug. --- arch/nds/extmem.c | 4 ++-- docs/changelog.txt | 3 +++ src/counter.c | 4 ++-- src/robot.c | 30 +++++------------------------- 4 files changed, 12 insertions(+), 29 deletions(-) diff --git a/arch/nds/extmem.c b/arch/nds/extmem.c index 7e88a3c2..9dfca10c 100644 --- a/arch/nds/extmem.c +++ b/arch/nds/extmem.c @@ -43,7 +43,7 @@ static void store_robot_to_extram(struct robot *robot) if(robot->used) { clear_label_cache(robot->label_list, robot->num_labels); - robot->label_list = cache_robot_labels(robot, &(robot->num_labels)); + robot->label_list = cache_robot_labels(robot, &robot->num_labels); } } @@ -62,7 +62,7 @@ static void retrieve_robot_from_extram(struct robot *robot) if(robot->used) { clear_label_cache(robot->label_list, robot->num_labels); - robot->label_list = cache_robot_labels(robot, &(robot->num_labels)); + robot->label_list = cache_robot_labels(robot, &robot->num_labels); } } diff --git a/docs/changelog.txt b/docs/changelog.txt index 4006b62c..d9720056 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -69,6 +69,9 @@ USERS properly on all platforms. + Fixed a bug where a file would be re-opened for read/write, even if the file was missing or an I/O error occurred before saving. ++ Fixed a bug where MZX could occasionally crash due to label list + corruption when copying robots from heap locations greater than + 2^32 bytes apart (only affected 64bit builds). DEVELOPERS diff --git a/src/counter.c b/src/counter.c index 7b2a1dd4..3f2bee6d 100644 --- a/src/counter.c +++ b/src/counter.c @@ -2500,7 +2500,7 @@ int set_counter_special(struct world *mzx_world, char *char_value, cur_robot->stack_pointer = 0; cur_robot->cur_prog_line = 1; cur_robot->label_list = - cache_robot_labels(cur_robot, &(cur_robot->num_labels)); + cache_robot_labels(cur_robot, &cur_robot->num_labels); // Restart this robot if either it was just a LOAD_ROBOT // OR LOAD_ROBOTn was used where n is &robot_id&. @@ -2537,7 +2537,7 @@ int set_counter_special(struct world *mzx_world, char *char_value, cur_robot->cur_prog_line = 1; cur_robot->stack_pointer = 0; cur_robot->label_list = - cache_robot_labels(cur_robot, &(cur_robot->num_labels)); + cache_robot_labels(cur_robot, &cur_robot->num_labels); // Restart this robot if either it was just a LOAD_BC // OR LOAD_BCn was used where n is &robot_id&. diff --git a/src/robot.c b/src/robot.c index b6ef2243..91465349 100644 --- a/src/robot.c +++ b/src/robot.c @@ -274,7 +274,7 @@ void load_robot(struct robot *cur_robot, FILE *fp, int savegame, int version) // TODO: This has to be made part of what's saved one day. cur_robot->label_list = - cache_robot_labels(cur_robot, &(cur_robot->num_labels)); + cache_robot_labels(cur_robot, &cur_robot->num_labels); #endif /* CONFIG_DEBYTECODE */ } else @@ -346,7 +346,7 @@ void load_robot(struct robot *cur_robot, FILE *fp, int savegame, int version) if(cur_robot->used) { cur_robot->label_list = - cache_robot_labels(cur_robot, &(cur_robot->num_labels)); + cache_robot_labels(cur_robot, &cur_robot->num_labels); } #endif /* !CONFIG_DEBYTECODE */ } @@ -2806,12 +2806,9 @@ __editor_maybe_static void duplicate_robot_direct(struct robot *cur_robot, struct robot *copy_robot, int x, int y) { - struct label *src_label, *dest_label; char *dest_program_location, *src_program_location; - int program_offset; int program_length; int num_labels; - int i; #ifdef CONFIG_DEBYTECODE prepare_robot_bytecode(cur_robot); @@ -2829,25 +2826,8 @@ void duplicate_robot_direct(struct robot *cur_robot, memcpy(dest_program_location, src_program_location, program_length); - if(num_labels) - copy_robot->label_list = ccalloc(num_labels, sizeof(struct label *)); - else - copy_robot->label_list = NULL; - - program_offset = (int)(dest_program_location - src_program_location); - - // Copy each individual label pointer over - for(i = 0; i < num_labels; i++) - { - copy_robot->label_list[i] = cmalloc(sizeof(struct label)); - - src_label = cur_robot->label_list[i]; - dest_label = copy_robot->label_list[i]; - - memcpy(dest_label, src_label, sizeof(struct label)); - // The name pointer actually has to be readjusted to match the new program - dest_label->name += program_offset; - } + copy_robot->label_list = + cache_robot_labels(cur_robot, &cur_robot->num_labels); #ifdef CONFIG_DEBYTECODE copy_robot->program_source = NULL; @@ -3138,7 +3118,7 @@ void prepare_robot_bytecode(struct robot *cur_robot) // robot's actually used. But eventually this should be combined with // assemble_program. cur_robot->label_list = - cache_robot_labels(cur_robot, &(cur_robot->num_labels)); + cache_robot_labels(cur_robot, &cur_robot->num_labels); // Can free source code now. free(cur_robot->program_source);