Allowed lseekable device files with -cut_out. Proof-of-concept by Ivan Shmakov.

This commit is contained in:
2022-04-26 12:17:22 +02:00
parent 0ef65a7837
commit fc587966d3
6 changed files with 172 additions and 103 deletions

View File

@ -1,7 +1,7 @@
/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
Copyright 2007-2019 Thomas Schmitt, <scdbackup@gmx.net>
Copyright 2007-2022 Thomas Schmitt, <scdbackup@gmx.net>
Provided under GPL version 2 or later.
@ -1225,6 +1225,27 @@ ex:;
}
int Xorriso_lseek_capacity(struct XorrisO *xorriso, char *path,
off_t *capacity, int flag)
{
int fd;
fd= open(path, O_RDONLY);
if(fd < 0) {
sprintf(xorriso->info_text,
"Determination of random-access readable capacity failed: ");
Text_shellsafe(path, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
return -1;
}
*capacity= lseek(fd, 0, SEEK_END);
close(fd);
if(*capacity < 0)
return(-1);
return(1);
}
/* @param flag bit0= -follow: disk_path is not a command parameter
*/
int Xorriso_cut_out(struct XorrisO *xorriso, char *disk_path,
@ -1232,13 +1253,14 @@ int Xorriso_cut_out(struct XorrisO *xorriso, char *disk_path,
{
int ret;
char *eff_source= NULL, *eff_dest= NULL;
off_t src_size;
struct stat stbuf;
Xorriso_alloc_meM(eff_source, char, SfileadrL);
Xorriso_alloc_meM(eff_dest, char, SfileadrL);
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, disk_path, eff_source,
2|4);
2 | 4);
if(ret<=0)
goto ex;
ret= Xorriso_path_is_excluded(xorriso, disk_path, !(flag&1));
@ -1265,22 +1287,44 @@ int Xorriso_cut_out(struct XorrisO *xorriso, char *disk_path,
{ret= 0; goto ex;}
}
}
if(S_ISREG(stbuf.st_mode)) {
if(stbuf.st_size<startbyte) {
Xorriso_msgs_submit(xorriso, 0, eff_source, 0, "ERRFILE", 0);
sprintf(xorriso->info_text,
"-cut_out: Byte offset %.f larger than file size %.f",
(double) startbyte, (double) stbuf.st_size);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "SORRY", 0);
{ret= 0; goto ex;}
src_size= stbuf.st_size;
} else if(!(S_ISDIR(stbuf.st_mode) || S_ISLNK(stbuf.st_mode) ||
S_ISFIFO(stbuf.st_mode) || S_ISSOCK(stbuf.st_mode))) {
ret= Xorriso_lseek_capacity(xorriso, eff_source, &src_size, 0);
if(ret <= 0)
goto unsupported_type;
if(src_size <= 0) {
Xorriso_msgs_submit(xorriso, 0,
"-cut_out: Special file with addressable size range of 0 encountered",
0, "FAILURE", 0);
goto unsupported_type;
}
} else {
unsupported_type:;
Xorriso_msgs_submit(xorriso, 0, eff_source, 0, "ERRFILE", 0);
sprintf(xorriso->info_text, "-cut_out: Unsupported file type (%s) with ",
Ftypetxt(stbuf.st_mode, 0));
if(S_ISDIR(stbuf.st_mode) || S_ISLNK(stbuf.st_mode) ||
S_ISFIFO(stbuf.st_mode) || S_ISSOCK(stbuf.st_mode)) {
sprintf(xorriso->info_text,
"-cut_out: File type (%s) is not suitable for this command: ",
Ftypetxt(stbuf.st_mode, 0));
} else {
sprintf(xorriso->info_text,
"-cut_out: File (%s) does not support random read access: ",
Ftypetxt(stbuf.st_mode, 0));
}
Text_shellsafe(eff_source, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
{ret= 0; goto ex;}
}
if(src_size < startbyte) {
Xorriso_msgs_submit(xorriso, 0, eff_source, 0, "ERRFILE", 0);
sprintf(xorriso->info_text,
"-cut_out: Byte offset %.f larger than addressable file size %.f : ",
(double) startbyte, (double) src_size);
Text_shellsafe(eff_source, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
{ret= 0; goto ex;}
}