diff --git a/xorriso/xorriso.c b/xorriso/xorriso.c index 56d756ff..3ab7ad66 100644 --- a/xorriso/xorriso.c +++ b/xorriso/xorriso.c @@ -7308,7 +7308,8 @@ int Xorriso_option_alter_date(struct XorrisO *xorriso, {ret= -1; goto ex;} } Findjob_set_action_ad(job, t_type, t, 0); - ret= Xorriso_findi(xorriso, job, NULL, NULL, optv[i], &dir_stbuf, 0, 0); + ret= Xorriso_findi(xorriso, job, NULL, (off_t) 0, + NULL, optv[i], &dir_stbuf, 0, 0); Findjob_destroy(&job, 0); } else ret= Xorriso_set_time(xorriso, optv[i], t, t_type); @@ -7673,7 +7674,8 @@ int Xorriso_option_chgrpi(struct XorrisO *xorriso, char *gid, {ret= -1; goto ex;} } Findjob_set_action_chgrp(job, gid_number, 0); - ret= Xorriso_findi(xorriso, job, NULL, NULL, optv[i], &dir_stbuf, 0, 0); + ret= Xorriso_findi(xorriso, job, NULL, (off_t) 0, + NULL, optv[i], &dir_stbuf, 0, 0); Findjob_destroy(&job, 0); } else ret= Xorriso_set_gid(xorriso, optv[i], gid_number, 0); @@ -7726,7 +7728,8 @@ int Xorriso_option_chmodi(struct XorrisO *xorriso, char *mode, {ret= -1; goto ex;} } Findjob_set_action_chmod(job, mode_and, mode_or, 0); - ret= Xorriso_findi(xorriso, job, NULL, NULL, optv[i], &dir_stbuf, 0, 0); + ret= Xorriso_findi(xorriso, job, NULL, (off_t) 0, + NULL, optv[i], &dir_stbuf, 0, 0); Findjob_destroy(&job, 0); } else { ret= Xorriso_set_st_mode(xorriso, optv[i], mode_and, mode_or, 0); @@ -7779,7 +7782,8 @@ int Xorriso_option_chowni(struct XorrisO *xorriso, char *uid, {ret= -1; goto ex;} } Findjob_set_action_chown(job, uid_number, 0); - ret= Xorriso_findi(xorriso, job, NULL, NULL, optv[i], &dir_stbuf, 0, 0); + ret= Xorriso_findi(xorriso, job, NULL, (off_t) 0, + NULL, optv[i], &dir_stbuf, 0, 0); Findjob_destroy(&job, 0); } else ret= Xorriso_set_uid(xorriso, optv[i], uid_number, 0); @@ -8556,7 +8560,7 @@ sorry_ex:; ret= Xorriso_findx(xorriso, first_job, "", start_path, &dir_stbuf, 0, NULL, 0); else - ret= Xorriso_findi(xorriso, first_job, NULL, NULL, + ret= Xorriso_findi(xorriso, first_job, NULL, (off_t) 0, NULL, start_path, &dir_stbuf, 0, 0); ex:; if(mem_lut!=xorriso->last_update_time && mem_lut!=0.0 && !(flag&2)) diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index a083e48d..52f0209c 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2008.03.02.172751" +#define Xorriso_timestamP "2008.03.02.201455" diff --git a/xorriso/xorrisoburn.c b/xorriso/xorrisoburn.c index 53a7c222..8e24c6ef 100644 --- a/xorriso/xorrisoburn.c +++ b/xorriso/xorrisoburn.c @@ -2487,6 +2487,21 @@ int Xorriso_rmi(struct XorrisO *xorriso, void *boss_iter, } #endif /* ! Xorriso_fat_local_meM */ +#ifndef Libisofs_iso_dir_iter_sufficienT + /* Ticket 127: A80301 - A80302 + I do not not deem IsoDirIter safe for node list manipulations. + The parameter boss_iter once was intended to allow such but + has now been downgraded to a mere check for eventual programming bugs. + */ + if(boss_iter!=NULL) { + sprintf(xorriso->info_text, + "Program error: Xorriso_rmi() was requested to delete iterated node %s", + Text_shellsafe(path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + ret= -1; goto ex; + } +#endif /* Libisofs_iso_dir_iter_sufficienT */ + ret= Xorriso_get_volume(xorriso, &volume, 0); if(ret<=0) goto ex; @@ -2631,7 +2646,8 @@ dir_not_removed:; } } -#ifdef Libisofs_iso_dir_iter_remove_repaireD +#ifdef Libisofs_iso_dir_iter_sufficienT + if(boss_iter!=NULL) { ret= iso_dir_iter_remove((IsoDirIter *) boss_iter); if(ret<0) @@ -2639,23 +2655,11 @@ dir_not_removed:; } else ret= iso_node_remove(victim_node); -#else /* ! Libisofs_iso_dir_iter_remove_repaireD */ - - /* Ticket 127: A80301 - This violates libisofs API prescriptions but works by lucky incident - 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); - } +#else /* ! Libisofs_iso_dir_iter_sufficienT */ ret= iso_node_remove(victim_node); -#endif /* Libisofs_iso_dir_iter_remove_repaireD */ +#endif /* Libisofs_iso_dir_iter_sufficienT */ Xorriso_process_msg_queues(xorriso,0); if(ret<0) { @@ -3758,7 +3762,7 @@ int Xorriso_set_time(struct XorrisO *xorriso, char *in_path, time_t t, int Xorriso_findi_action(struct XorrisO *xorriso, struct FindjoB *job, - IsoDirIter *boss_iter, + IsoDirIter *boss_iter, off_t boss_mem, char *abs_path, char *show_path, IsoNode *node, int depth, int flag) { @@ -3798,7 +3802,7 @@ int Xorriso_findi_action(struct XorrisO *xorriso, struct FindjoB *job, ret= Xorriso_ls_filev(xorriso, "", 1, &abs_path, (off_t) 0, 1|2|8); } else if(action>=9 && action<=13) { /* actions which have own findjobs */ Findjob_set_start_path(subjob, abs_path, 0); - ret= Xorriso_findi(xorriso, subjob, boss_iter, NULL, + ret= Xorriso_findi(xorriso, subjob, boss_iter, boss_mem, NULL, abs_path, &dir_stbuf, depth, 0); } else if(action==14 || action==17) { /* compare , update */ Findjob_get_start_path(job, &iso_prefix, 0); @@ -3824,13 +3828,15 @@ int Xorriso_findi_action(struct XorrisO *xorriso, struct FindjoB *job, bit1= action needs full freedom of object manipulation bit31= end iteration (mandatory !) */ -int Xorriso_findi_iter(struct XorrisO *xorriso, IsoDir *dir_node, - IsoDirIter **iter, +int Xorriso_findi_iter(struct XorrisO *xorriso, IsoDir *dir_node, off_t *mem, + IsoDirIter **iter, IsoNode ***node_array, int *node_count, int *node_idx, IsoNode **iterated_node, int flag) { int ret, i; IsoNode *node; + off_t new_mem= 0; + char mem_text[80], limit_text[80]; if(flag&1) { *node_array= NULL; @@ -3851,17 +3857,27 @@ cannot_iter:; iso_dir_iter_free(*iter); *iter= NULL; - /* >>> check with temp mem limit */; - + new_mem= ((*node_count)+1) * sizeof(IsoNode *); + if(new_mem > xorriso->temp_mem_limit) { + Sfile_scale((double) new_mem, mem_text, 5,1e4, 0); + Sfile_scale((double) xorriso->temp_mem_limit, limit_text, 5,1e4, 0); + sprintf(xorriso->info_text, + "Stacked directory snapshots exceed -temp_mem_limit (%s > %s)", + mem_text, limit_text); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + *node_count= -1; + return(-1); + } (*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", + "Could not allocate inode list of %.f bytes", ((double) (*node_count)+1) * (double) sizeof(IsoNode *)); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); *node_count= -1; return(-1); } + *mem= new_mem; ret= iso_dir_get_children(dir_node, iter); if(ret<0) goto cannot_iter; @@ -3876,8 +3892,9 @@ cannot_iter:; *node_idx= 0; } } + if(flag&(1<<31)) { - if(*node_count>=0) { + if(*node_count>=0 && *node_array!=NULL) { for(i= 0; i<*node_count; i++) iso_node_unref((*node_array)[i]); free(*node_array); @@ -3890,6 +3907,7 @@ cannot_iter:; *iter= NULL; } } + if(flag&(1|(1<<31))) return(1); if(*node_count>=0) { @@ -3907,13 +3925,13 @@ cannot_iter:; int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job, - void *boss_iter, + void *boss_iter, off_t boss_mem, void *dir_node_generic, char *dir_path, struct stat *dir_stbuf, int depth, int flag) { int ret, action= 0; IsoDirIter *iter= NULL; - IsoDir *dir_node; + IsoDir *dir_node= NULL; IsoNode *node, *iso_node; IsoImage *volume; struct stat stbuf; @@ -3922,6 +3940,7 @@ int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job, char path[SfileadrL], abs_path[SfileadrL]; #else /* Xorriso_fat_local_meM */ char *path= NULL, *abs_path= NULL; + off_t mem; #define Xorriso_findi_new_iteR yes @@ -3968,7 +3987,8 @@ int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job, if(ret<0) goto ex; if(ret>0) { - ret= Xorriso_findi_action(xorriso, job, (IsoDirIter *) boss_iter, + ret= Xorriso_findi_action(xorriso, job, + (IsoDirIter *) boss_iter, boss_mem, path, dir_path, (IsoNode *) dir_node, depth, 0); if(ret<=0) goto ex; @@ -3979,14 +3999,15 @@ int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job, #ifdef Xorriso_findi_new_iteR - ret= Xorriso_findi_iter(xorriso, dir_node, + mem= boss_mem; + ret= Xorriso_findi_iter(xorriso, dir_node, &mem, &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); + ret= Xorriso_findi_iter(xorriso, dir_node, &mem, &iter, + &node_array, &node_count, &node_idx, &node, 0); if(ret<0) goto ex; if(ret==0 || xorriso->request_to_abort) @@ -4020,7 +4041,7 @@ int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job, ret= Xorriso_make_abs_adr(xorriso, xorriso->wdi, path, abs_path, 1|2|4); if(ret<=0) goto ex; - ret= Xorriso_findi_action(xorriso, job, iter, + ret= Xorriso_findi_action(xorriso, job, iter, mem, abs_path, path, node, depth, 0); if(ret<=0) { if(Xorriso_eval_problem_status(xorriso, ret, 1|2)<0) @@ -4029,8 +4050,8 @@ int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job, } if(S_ISDIR(stbuf.st_mode)) { - ret= Xorriso_findi(xorriso, job, (void *) iter, (void *) node, path, - &stbuf, depth+1, flag); + ret= Xorriso_findi(xorriso, job, (void *) iter, mem, + (void *) node, path, &stbuf, depth+1, flag); if(ret<0) goto ex; } @@ -4049,7 +4070,7 @@ ex:; Xorriso_process_msg_queues(xorriso,0); #ifdef Xorriso_findi_new_iteR - Xorriso_findi_iter(xorriso, dir_node, &iter, &node_array, &node_count, + Xorriso_findi_iter(xorriso, dir_node, &mem, &iter, &node_array, &node_count, &node_idx, &node, (1<<31)); #else if(iter!=NULL) diff --git a/xorriso/xorrisoburn.h b/xorriso/xorrisoburn.h index 21588e4f..e56bd5c4 100644 --- a/xorriso/xorrisoburn.h +++ b/xorriso/xorrisoburn.h @@ -140,7 +140,7 @@ int Xorriso_set_time(struct XorrisO *xorriso, char *in_path, time_t t, int flag); int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job, - void *boss_iter, + void *boss_iter, off_t boss_mem, void *dir_node_generic, char *dir_path, struct stat *dir_stbuf, int depth, int flag);