From e524e81e997bac0e580ebe46d403ed44e9ef7b5f Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Thu, 23 Mar 2023 14:47:53 +0000 Subject: [PATCH] [iso] improve Rock Ridge CE handling --- .vs/libcdio-iso9660.vcxproj | 1 + .vs/libcdio-iso9660.vcxproj.filters | 3 ++ src/libcdio/cdio/rock.h | 8 ++--- src/libcdio/iso9660/iso9660.c | 2 +- src/libcdio/iso9660/rock.c | 47 ++++++++++++++++++----------- src/rufus.rc | 10 +++--- 6 files changed, 44 insertions(+), 27 deletions(-) diff --git a/.vs/libcdio-iso9660.vcxproj b/.vs/libcdio-iso9660.vcxproj index 23ac97e6..beadf8e6 100644 --- a/.vs/libcdio-iso9660.vcxproj +++ b/.vs/libcdio-iso9660.vcxproj @@ -41,6 +41,7 @@ + diff --git a/.vs/libcdio-iso9660.vcxproj.filters b/.vs/libcdio-iso9660.vcxproj.filters index e3b3c656..d62e4879 100644 --- a/.vs/libcdio-iso9660.vcxproj.filters +++ b/.vs/libcdio-iso9660.vcxproj.filters @@ -53,6 +53,9 @@ Header Files + + Header Files + diff --git a/src/libcdio/cdio/rock.h b/src/libcdio/cdio/rock.h index 548228bf..ff26835b 100644 --- a/src/libcdio/cdio/rock.h +++ b/src/libcdio/cdio/rock.h @@ -112,10 +112,10 @@ typedef struct iso_su_er_s { } GNUC_PACKED iso_su_er_t; typedef struct iso_su_ce_s { - uint8_t extent[8]; - uint8_t offset[8]; - uint8_t size[8]; -} iso_su_ce_t; + iso733_t extent; + iso733_t offset; + iso733_t size; +} GNUC_PACKED iso_su_ce_t; /*! POSIX file attributes, PX. See Rock Ridge Section 4.1.2 */ typedef struct iso_rock_px_s { diff --git a/src/libcdio/iso9660/iso9660.c b/src/libcdio/iso9660/iso9660.c index 066c4f1a..501d28c9 100644 --- a/src/libcdio/iso9660/iso9660.c +++ b/src/libcdio/iso9660/iso9660.c @@ -729,7 +729,7 @@ iso9660_dir_add_entry_su(void *dir, unsigned int offset = 0; uint32_t dsize = from_733(idr->size); int length, su_offset; - struct tm temp_tm; + struct tm temp_tm = { 0 }; cdio_assert (sizeof(iso9660_dir_t) == 33); if (!dsize && !idr->length) diff --git a/src/libcdio/iso9660/rock.c b/src/libcdio/iso9660/rock.c index d2c01165..fd03be24 100644 --- a/src/libcdio/iso9660/rock.c +++ b/src/libcdio/iso9660/rock.c @@ -20,7 +20,8 @@ */ /* Rock Ridge Extensions to iso9660 */ - + + #ifdef HAVE_CONFIG_H # include "config.h" #endif @@ -104,17 +105,17 @@ realloc_symlink(/*in/out*/ iso9660_stat_t *p_stat, uint8_t i_grow) #define CONTINUE_DECLS \ uint32_t cont_extent = 0, cont_offset = 0, cont_size = 0; \ - uint8_t *buffer = NULL + uint8_t *buffer = NULL, ce_count = 0 #define CHECK_CE(FAIL) \ - { cont_extent = from_733(*rr->u.CE.extent); \ - cont_offset = from_733(*rr->u.CE.offset); \ + { cont_extent = from_733(rr->u.CE.extent); \ + cont_offset = from_733(rr->u.CE.offset); \ if (cont_offset >= ISO_BLOCKSIZE) FAIL; \ - cont_size = from_733(*rr->u.CE.size); \ + cont_size = from_733(rr->u.CE.size); \ if (cont_size >= ISO_BLOCKSIZE) FAIL; \ } -#define SETUP_ROCK_RIDGE(DE,CHR,LEN) \ +#define SETUP_ROCK_RIDGE(DE, CHR, LEN) \ { \ LEN= sizeof(iso9660_dir_t) + DE->filename.len; \ if (LEN & 1) LEN++; \ @@ -181,7 +182,7 @@ get_rock_ridge_filename(iso9660_dir_t * p_iso9660_dir, *psz_name = 0; SETUP_ROCK_RIDGE(p_iso9660_dir, chr, len); - /*repeat:*/ +repeat: { iso_extension_record_t * rr; int sig; @@ -217,15 +218,10 @@ get_rock_ridge_filename(iso9660_dir_t * p_iso9660_dir, } CHECK_CE({cdio_warn("Invalid Rock Ridge CE field"); goto out;}); p_stat->rr.u_su_fields |= ISO_ROCK_SUF_CE; - /* We may already be processing a continuation block so free it */ - free(buffer); - buffer = calloc(1, ISO_BLOCKSIZE); - if (!buffer) - goto out; - if (iso9660_iso_seek_read(p_image, buffer, cont_extent, 1) != ISO_BLOCKSIZE) - goto out; - chr = &buffer[cont_offset]; - len = cont_size; + /* Though no mastering utility in its right mind would produce anything + like this, the specs make it theoretically possible to have more RR + extensions after a CE, so we delay the CE block processing for later. + */ break; case SIG('E','R'): cdio_debug("ISO 9660 Extensions: "); @@ -379,9 +375,26 @@ get_rock_ridge_filename(iso9660_dir_t * p_iso9660_dir, } } } - free(buffer); + /* Process delayed CE blocks */ + if (cont_size != 0) { + free(buffer); + buffer = calloc(1, ISO_BLOCKSIZE); + if (!buffer) + goto out; + if (iso9660_iso_seek_read(p_image, buffer, cont_extent, 1) != ISO_BLOCKSIZE) + goto out; + chr = &buffer[cont_offset]; + len = cont_size; + cont_size = 0; + /* Someone abusing the specs may also be creating looping CEs */ + if (ce_count++ < 64) + goto repeat; + else + cdio_warn("More than 64 consecutive Rock Ridge CEs detected"); + } if (p_stat->rr.u_su_fields & ISO_ROCK_SUF_FORMAL) p_stat->rr.b3_rock = yep; + free(buffer); return i_namelen; /* If 0, this file did not have a NM field */ out: free(buffer); diff --git a/src/rufus.rc b/src/rufus.rc index 48c8dfcf..95c63996 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDD_DIALOG DIALOGEX 12, 12, 232, 326 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_ACCEPTFILES -CAPTION "Rufus 3.22.2005" +CAPTION "Rufus 3.22.2006" FONT 9, "Segoe UI Symbol", 400, 0, 0x0 BEGIN LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP @@ -392,8 +392,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,22,2005,0 - PRODUCTVERSION 3,22,2005,0 + FILEVERSION 3,22,2006,0 + PRODUCTVERSION 3,22,2006,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -411,13 +411,13 @@ BEGIN VALUE "Comments", "https://rufus.ie" VALUE "CompanyName", "Akeo Consulting" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "3.22.2005" + VALUE "FileVersion", "3.22.2006" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "© 2011-2023 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" VALUE "OriginalFilename", "rufus-3.22.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "3.22.2005" + VALUE "ProductVersion", "3.22.2006" END END BLOCK "VarFileInfo"