Skip to content

Commit ac4566e

Browse files
rapperskullthrimbor
authored andcommitted
Fix: truncate the file if the ISO ends before its length
1 parent 4488c39 commit ac4566e

File tree

1 file changed

+84
-68
lines changed

1 file changed

+84
-68
lines changed

extract-xiso.c

Lines changed: 84 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1631,57 +1631,54 @@ char *boyer_moore_search( char *in_text, long in_text_len ) {
16311631

16321632

16331633
int extract_file( int in_xiso, dir_node *in_file, modes in_mode , char* path) {
1634-
char c;
16351634
int err = 0;
16361635
bool warn = false;
1637-
uint32_t i, size, totalsize = 0, totalpercent = 0;
1636+
uint32_t i, size, read_size, totalsize = 0, totalpercent = 0;
16381637
int out;
16391638

1640-
if ( s_remove_systemupdate && strstr( path, s_systemupdate ) )
1641-
{
1639+
if ( s_remove_systemupdate && strstr( path, s_systemupdate ) ){
16421640
if ( ! err && lseek( in_xiso, (xoff_t) in_file->start_sector * XISO_SECTOR_SIZE + s_xbox_disc_lseek, SEEK_SET ) == -1 ) seek_err();
1643-
}
1644-
else
1645-
{
1646-
1647-
if ( in_mode == k_extract ) {
1648-
if ( ( out = open( in_file->filename, WRITEFLAGS, 0644 ) ) == -1 ) open_err( in_file->filename );
1649-
} else err = 1;
1641+
}
1642+
else {
1643+
if ( in_mode == k_extract ) {
1644+
if ( ( out = open( in_file->filename, WRITEFLAGS, 0644 ) ) == -1 ) open_err( in_file->filename );
1645+
} else err = 1;
16501646

16511647
if ( ! err && lseek( in_xiso, (xoff_t) in_file->start_sector * XISO_SECTOR_SIZE + s_xbox_disc_lseek, SEEK_SET ) == -1 ) seek_err();
16521648

1653-
if ( ! err ) {
1654-
if ( in_file->file_size == 0 )
1655-
exiso_log( "%s%s%s (0 bytes) [100%%]%s\r", in_mode == k_extract ? "extracting " : "", path, in_file->filename, "" );
1656-
if ( in_mode == k_extract ) {
1657-
for ( i = 0, size = min( in_file->file_size, READWRITE_BUFFER_SIZE );
1658-
i < in_file->file_size && read( in_xiso, s_copy_buffer, size ) == (int) size;
1659-
i += size, size = min( in_file->file_size - i, READWRITE_BUFFER_SIZE ) )
1660-
{
1661-
if ( write( out, s_copy_buffer, size ) != (int) size ) {
1662-
write_err();
1663-
break;
1664-
}
1665-
totalsize += size;
1666-
totalpercent = ( totalsize * 100.0 ) / in_file->file_size;
1667-
exiso_log( "%s%s%s (%u bytes) [%u%%]%s\r", in_mode == k_extract ? "extracting " : "", path, in_file->filename, in_file->file_size , totalpercent, "" );
1649+
if ( ! err ) {
1650+
if (in_file->file_size == 0) {
1651+
exiso_log("%s%s%s (0 bytes) [100%%]%s\r", in_mode == k_extract ? "extracting " : "", path, in_file->filename, "");
16681652
}
1669-
1670-
close( out );
1671-
} else {
1672-
for ( i = 0, size = min( in_file->file_size, READWRITE_BUFFER_SIZE );
1673-
i < in_file->file_size && read( in_xiso, s_copy_buffer, size ) == (int) size;
1674-
i += size, size = min( in_file->file_size - i, READWRITE_BUFFER_SIZE ) )
1675-
{
1676-
totalsize += size;
1677-
totalpercent = ( totalsize * 100.0 ) / in_file->file_size;
1678-
exiso_log( "%s%s%s (%u bytes) [%u%%]%s\r", in_mode == k_extract ? "extracting " : "", path, in_file->filename, in_file->file_size , totalpercent, "" );
1653+
else {
1654+
i = 0;
1655+
size = min(in_file->file_size, READWRITE_BUFFER_SIZE);
1656+
do {
1657+
if ((int)(read_size = read(in_xiso, s_copy_buffer, size)) < 0) {
1658+
read_err();
1659+
break;
1660+
}
1661+
if (in_mode == k_extract && read_size != 0) {
1662+
if (write(out, s_copy_buffer, read_size) != (int)read_size) {
1663+
write_err();
1664+
break;
1665+
}
1666+
}
1667+
totalsize += read_size;
1668+
totalpercent = (totalsize * 100.0) / in_file->file_size;
1669+
exiso_log("%s%s%s (%u bytes) [%u%%]%s\r", in_mode == k_extract ? "extracting " : "", path, in_file->filename, in_file->file_size, totalpercent, "");
1670+
1671+
i += read_size;
1672+
size = min(in_file->file_size - i, READWRITE_BUFFER_SIZE);
1673+
} while (i < in_file->file_size && read_size > 0);
1674+
if (!err && i < in_file->file_size) {
1675+
exiso_log("\nWARNING: File %s is truncated. Reported size: %u bytes, read size: %u bytes!", in_file->filename, in_file->file_size, i);
1676+
}
16791677
}
1678+
if (in_mode == k_extract) close(out);
16801679
}
16811680
}
16821681

1683-
}
1684-
16851682
if ( ! err ) exiso_log( "\n" );
16861683

16871684
return err;
@@ -1752,6 +1749,7 @@ int write_file( dir_node_avl *in_avl, write_tree_context *in_context, int in_dep
17521749
char *buf, *p;
17531750
uint32_t bytes, n, size;
17541751
int err = 0, fd = -1, i;
1752+
size_t len;
17551753

17561754
if ( ! in_avl->subdirectory ) {
17571755
if ( lseek( in_context->xiso, (xoff_t) in_avl->start_sector * XISO_SECTOR_SIZE, SEEK_SET ) == -1 ) seek_err();
@@ -1768,45 +1766,63 @@ int write_file( dir_node_avl *in_avl, write_tree_context *in_context, int in_dep
17681766
if ( ! err ) {
17691767
exiso_log( "adding %s%s (%u bytes) ", in_context->path, in_avl->filename, in_avl->file_size ); flush();
17701768

1771-
if ( s_media_enable && ( i = (int) strlen( in_avl->filename ) ) >= 4 && in_avl->filename[ i - 4 ] == '.' && ( in_avl->filename[ i - 3 ] | 0x20 ) == 'x' && ( in_avl->filename[ i - 2 ] | 0x20 ) == 'b' && ( in_avl->filename[ i - 1 ] | 0x20 ) == 'e' ) {
1772-
for ( bytes = in_avl->file_size, i = 0; ! err && bytes; ) {
1773-
if ( ( n = read( fd, buf + i, min( bytes, size - i ) ) ) == -1 ) read_err();
1774-
1775-
bytes -= n;
1776-
1777-
if ( ! err ) {
1778-
for ( buf[ n += i ] = 0, p = buf; ( p = boyer_moore_search( p, n - ( p - buf ) ) ) != nil; p += XISO_MEDIA_ENABLE_LENGTH ) p[ XISO_MEDIA_ENABLE_BYTE_POS ] = XISO_MEDIA_ENABLE_BYTE;
1779-
1780-
if ( bytes ) {
1781-
if ( write( in_context->xiso, buf, n - ( i = XISO_MEDIA_ENABLE_LENGTH - 1 ) ) != (int) n - i ) write_err();
1782-
1783-
if ( ! err ) memcpy( buf, &buf[ n - ( XISO_MEDIA_ENABLE_LENGTH - 1 ) ], XISO_MEDIA_ENABLE_LENGTH - 1 );
1784-
} else {
1785-
if ( write( in_context->xiso, buf, n + i ) != (int) n + i ) write_err();
1769+
i = 0;
1770+
bytes = in_avl->file_size;
1771+
do {
1772+
if ((int)(n = read(fd, buf + i, min(bytes, size - i))) < 0) {
1773+
read_err();
1774+
break;
1775+
}
1776+
if (n == 0) {
1777+
if (i) {
1778+
if (write(in_context->xiso, buf, i) != i) {
1779+
write_err();
1780+
break;
17861781
}
17871782
}
1783+
break;
17881784
}
1789-
} else {
1790-
for ( bytes = in_avl->file_size; ! err && bytes; bytes -= n ) {
1791-
if ( ( n = read( fd, buf, min( bytes, size ) ) ) == -1 ) read_err();
1792-
1793-
if ( ! err && write( in_context->xiso, buf, n ) != (int) n ) write_err();
1785+
bytes -= n;
1786+
if (s_media_enable && (len = strlen(in_avl->filename)) >= 4 && in_avl->filename[len - 4] == '.' && (in_avl->filename[len - 3] | 0x20) == 'x' && (in_avl->filename[len - 2] | 0x20) == 'b' && (in_avl->filename[len - 1] | 0x20) == 'e') {
1787+
for (buf[n += i] = 0, p = buf; (p = boyer_moore_search(p, n - (p - buf))) != nil; p += XISO_MEDIA_ENABLE_LENGTH) p[XISO_MEDIA_ENABLE_BYTE_POS] = XISO_MEDIA_ENABLE_BYTE;
1788+
if (bytes) {
1789+
i = XISO_MEDIA_ENABLE_LENGTH - 1;
1790+
if (write(in_context->xiso, buf, n - i) != (int)n - i) {
1791+
write_err();
1792+
break;
1793+
}
1794+
memcpy(buf, &buf[n - i], i);
1795+
}
1796+
else {
1797+
if (write(in_context->xiso, buf, n + i) != (int)n + i) {
1798+
write_err();
1799+
break;
1800+
}
1801+
}
17941802
}
1803+
else {
1804+
if (write(in_context->xiso, buf, n + i) != (int)n + i) {
1805+
write_err();
1806+
break;
1807+
}
1808+
}
1809+
} while (bytes);
1810+
i = in_avl->file_size - bytes;
1811+
1812+
if (!err && (bytes = (XISO_SECTOR_SIZE - (in_avl->file_size % XISO_SECTOR_SIZE)) % XISO_SECTOR_SIZE)) {
1813+
memset(buf, XISO_PAD_BYTE, bytes);
1814+
if (write(in_context->xiso, buf, bytes) != (int)bytes) write_err();
17951815
}
1796-
1797-
if ( ! err && ( bytes = ( XISO_SECTOR_SIZE - ( in_avl->file_size % XISO_SECTOR_SIZE ) ) % XISO_SECTOR_SIZE ) ) {
1798-
memset( buf, XISO_PAD_BYTE, bytes );
1799-
if ( write( in_context->xiso, buf, bytes ) != (int) bytes ) write_err();
1816+
exiso_log(err ? "failed\n" : "[OK]\n");
1817+
1818+
if (!err && i != in_avl->file_size) {
1819+
exiso_log("WARNING: File %s is truncated. Reported size: %u bytes, wrote size: %u bytes!\n", in_avl->filename, in_avl->file_size, i);
18001820
}
1801-
1802-
if ( err ) { exiso_log( "failed\n" ); }
1803-
else {
1804-
exiso_log( "[OK]\n" );
18051821

1822+
if (!err) {
18061823
++s_total_files;
18071824
s_total_bytes += in_avl->file_size;
1808-
1809-
if ( in_context->progress ) (*in_context->progress)( s_total_bytes, in_context->final_bytes );
1825+
if (in_context->progress) (*in_context->progress)(s_total_bytes, in_context->final_bytes);
18101826
}
18111827
}
18121828

0 commit comments

Comments
 (0)