From 0dfc79bd4ede75fdf458608ead7111e7a2ec8e4e Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Sun, 2 Mar 2008 17:28:38 +0000 Subject: [PATCH] Made -update_r and -find -exec update safe against IsoDirIter pitfalls --- xorriso/xorriso_timestamp.h | 2 +- xorriso/xorrisoburn.c | 129 ++++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+), 1 deletion(-) diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index 55ba3274..a083e48d 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2008.03.01.151219" +#define Xorriso_timestamP "2008.03.02.172751" diff --git a/xorriso/xorrisoburn.c b/xorriso/xorrisoburn.c index 243c7910..53a7c222 100644 --- a/xorriso/xorrisoburn.c +++ b/xorriso/xorrisoburn.c @@ -2646,6 +2646,13 @@ dir_not_removed:; whereas iso_dir_iter_remove() removes the next node to come rather than the most recently returned node. */ + if(boss_iter!=NULL) { + sprintf(xorriso->info_text, + "Xorriso_rmi() was requested to delete iterated node %s", + Text_shellsafe(path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); + } + ret= iso_node_remove(victim_node); #endif /* Libisofs_iso_dir_iter_remove_repaireD */ @@ -3810,6 +3817,95 @@ int Xorriso_findi_action(struct XorrisO *xorriso, struct FindjoB *job, } +/* The caller shall make no assumptions about the meaning of iter, node_array, + node_count, node_idx ! They are just opaque handles for which the caller + provides the memory of proper type. + @param flag bit0= initialize iteration + bit1= action needs full freedom of object manipulation + bit31= end iteration (mandatory !) +*/ +int Xorriso_findi_iter(struct XorrisO *xorriso, IsoDir *dir_node, + IsoDirIter **iter, + IsoNode ***node_array, int *node_count, int *node_idx, + IsoNode **iterated_node, int flag) +{ + int ret, i; + IsoNode *node; + + if(flag&1) { + *node_array= NULL; + *node_count= -1; + *node_idx= 0; + *iter= NULL; + ret= iso_dir_get_children(dir_node, iter); + if(ret<0) { +cannot_iter:; + Xorriso_cannot_create_iter(xorriso, ret, 0); + return(-1); + } + if(flag&2) { + /* copy list of nodes and prepare soft iterator */ + *node_count= 0; + while(iso_dir_iter_next(*iter, &node) == 1) + (*node_count)++; + iso_dir_iter_free(*iter); + *iter= NULL; + + /* >>> check with temp mem limit */; + + (*node_array)= (IsoNode **) calloc((*node_count)+1, sizeof(IsoNode *)); + if(*node_array == NULL) { + sprintf(xorriso->info_text, + "Could not allocate inode list of %.lf bytes", + ((double) (*node_count)+1) * (double) sizeof(IsoNode *)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + *node_count= -1; + return(-1); + } + ret= iso_dir_get_children(dir_node, iter); + if(ret<0) + goto cannot_iter; + while(iso_dir_iter_next(*iter, &node) == 1 && *node_idx < *node_count) { + (*node_array)[*node_idx]= node; + iso_node_ref(node); + (*node_idx)++; + } + iso_dir_iter_free(*iter); + *iter= NULL; + *node_count= *node_idx; + *node_idx= 0; + } + } + if(flag&(1<<31)) { + if(*node_count>=0) { + for(i= 0; i<*node_count; i++) + iso_node_unref((*node_array)[i]); + free(*node_array); + *node_array= NULL; + *node_count= -1; + *node_idx= 0; + } else { + if(*iter!=NULL) + iso_dir_iter_free(*iter); + *iter= NULL; + } + } + if(flag&(1|(1<<31))) + return(1); + if(*node_count>=0) { + /* return next node_array element */ + if(*node_idx>=*node_count) + return(0); + *iterated_node= (*node_array)[*node_idx]; + (*node_idx)++; + } else { + ret= iso_dir_iter_next(*iter, iterated_node); + return(ret == 1); + } + return(1); +} + + int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job, void *boss_iter, void *dir_node_generic, char *dir_path, @@ -3827,6 +3923,13 @@ int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job, #else /* Xorriso_fat_local_meM */ char *path= NULL, *abs_path= NULL; +#define Xorriso_findi_new_iteR yes + +#ifdef Xorriso_findi_new_iteR + IsoNode **node_array= NULL; + int node_count, node_idx; +#endif + path= malloc(SfileadrL); abs_path= malloc(SfileadrL); if(path==NULL || abs_path==NULL) { @@ -3874,12 +3977,32 @@ int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job, if(!LIBISO_ISDIR((IsoNode *) dir_node)) {ret= 2; goto ex;} +#ifdef Xorriso_findi_new_iteR + + ret= Xorriso_findi_iter(xorriso, dir_node, + &iter, &node_array, &node_count, &node_idx, + &node, 1|((action==17)<<1)); + if(ret<=0) + goto ex; + while(1) { + ret= Xorriso_findi_iter(xorriso, dir_node, &iter, &node_array, &node_count, + &node_idx, &node, 0); + if(ret<0) + goto ex; + if(ret==0 || xorriso->request_to_abort) + break; + +#else + ret= iso_dir_get_children(dir_node, &iter); if(ret<0) { Xorriso_cannot_create_iter(xorriso, ret, 0); {ret= -1; goto ex;} } while(iso_dir_iter_next(iter, &node) == 1 && !xorriso->request_to_abort) { + +#endif /* ! Xorriso_findi_new_iteR */ + name= (char *) iso_node_get_name(node); ret= Xorriso_make_abs_adr(xorriso, dir_path, name, path, 4); if(ret<=0) @@ -3924,8 +4047,14 @@ ex:; #endif /* ! Xorriso_fat_local_meM */ Xorriso_process_msg_queues(xorriso,0); + +#ifdef Xorriso_findi_new_iteR + Xorriso_findi_iter(xorriso, dir_node, &iter, &node_array, &node_count, + &node_idx, &node, (1<<31)); +#else if(iter!=NULL) iso_dir_iter_free(iter); +#endif return(ret); }