-rw-r--r-- | configure.ac | 57 | ||||
-rw-r--r-- | doc/libcdio.texi | 2 | ||||
-rw-r--r-- | include/cdio/iso9660.h | 22 | ||||
-rw-r--r-- | include/cdio/rock.h | 20 | ||||
-rw-r--r-- | lib/iso9660/iso9660.c | 2 | ||||
-rw-r--r-- | lib/iso9660/iso9660_fs.c | 88 | ||||
-rw-r--r-- | lib/iso9660/rock.c | 98 | ||||
-rw-r--r-- | src/cd-info.c | 4 | ||||
-rw-r--r-- | src/cddb.c | 2 | ||||
-rwxr-xr-x | test/check_multiextent.sh | 38 | ||||
-rw-r--r-- | test/data/multi_extent_8k.iso | bin | 524288 -> 122880 bytes | |||
-rw-r--r-- | test/data/multi_extent_8k_joliet.iso | bin | 0 -> 122880 bytes | |||
-rw-r--r-- | test/multiextent.right | 6 | ||||
-rw-r--r-- | test/multiextent_joliet.right | 7 |
diff --git a/configure.ac b/configure.ac index f94ee83c..0399a718 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -dnl Copyright (C) 2003-2008, 2010, 2011-2014, 2018, 2019 +dnl Copyright (C) 2003-2008, 2010, 2011-2014, 2018, 2019, 2023 dnl Rocky Bernstein <rocky@gnu.org> dnl dnl This program is free software: you can redistribute it and/or modify @@ -14,12 +14,12 @@ dnl dnl You should have received a copy of the GNU General Public License dnl along with this program. If not, see <http://www.gnu.org/licenses/>. -define(RELEASE_NUM, 2.1.0) +define(RELEASE_NUM, 2.1.1.dev0) define(CDIO_VERSION_STR, 1ドル) -AC_PREREQ(2.61) +AC_PREREQ([2.71]) -AC_INIT([libcdio], [CDIO_VERSION_STR(RELEASE_NUM)], [https://savannah.gnu.org/bugs/?group=libcdio]) +AC_INIT([libcdio],[CDIO_VERSION_STR(RELEASE_NUM)],[https://savannah.gnu.org/bugs/?group=libcdio]) AC_CONFIG_SRCDIR(src/cd-info.c) AM_INIT_AUTOMAKE([foreign subdir-objects]) @@ -45,43 +45,43 @@ AM_MAINTAINER_MODE AM_SANITY_CHECK AC_ARG_WITH(cd-drive, - AC_HELP_STRING([--without-cd-drive], [don't build program cd-drive (default with)]), + AS_HELP_STRING([--without-cd-drive],[don't build program cd-drive (default with)]), enable_cd_drive="${withval}", enable_cd_drive=yes) AC_ARG_WITH(cd-info, - AC_HELP_STRING([--without-cd-info], [don't build program cd-info (default with)]), + AS_HELP_STRING([--without-cd-info],[don't build program cd-info (default with)]), enable_cd_info="${withval}", enable_cd_info=yes) AC_ARG_WITH(cdda-player, - AC_HELP_STRING([--without-cdda-player], [don't build program cdda-player (default with)]), + AS_HELP_STRING([--without-cdda-player],[don't build program cdda-player (default with)]), enable_cdda_player="${withval}", enable_cdda_player=yes) AC_ARG_WITH(cd-read, - AC_HELP_STRING([--without-cd-read], [don't build program cd-read (default with)]), + AS_HELP_STRING([--without-cd-read],[don't build program cd-read (default with)]), enable_cd_read="${withval}", enable_cd_read=yes) AC_ARG_WITH(iso-info, - AC_HELP_STRING([--without-iso-info], [don't build program iso-info (default with)]), + AS_HELP_STRING([--without-iso-info],[don't build program iso-info (default with)]), enable_iso_info="${withval}", enable_iso_info=yes) AC_ARG_WITH(iso-read, - AC_HELP_STRING([--without-iso-read], [don't build program iso-read (default with)]), + AS_HELP_STRING([--without-iso-read],[don't build program iso-read (default with)]), enable_iso_read="${withval}", enable_iso_read=yes) AC_ARG_WITH(versioned-libs, - AC_HELP_STRING([--without-versioned-libs], [build versioned library symbols (default enabled if you have GNU ld)]), + AS_HELP_STRING([--without-versioned-libs],[build versioned library symbols (default enabled if you have GNU ld)]), enable_versioned_libs="${withval}", enable_versioned_libs=yes) AC_ARG_ENABLE([cxx], - AC_HELP_STRING([--disable-cxx], [Disable C++ bindings (default enabled)])) + AS_HELP_STRING([--disable-cxx],[Disable C++ bindings (default enabled)])) AM_CONDITIONAL([ENABLE_CXX_BINDINGS], [test "x$enable_cxx" != "xno"]) AC_ARG_ENABLE(cpp-progs, - AC_HELP_STRING([--enable-cpp-progs], [make C++ example programs (default enabled)])) + AS_HELP_STRING([--enable-cpp-progs],[make C++ example programs (default enabled)])) AM_CONDITIONAL(ENABLE_CPP, test "x$enable_cpp_progs" = "xyes") AC_ARG_ENABLE(example-progs, - AC_HELP_STRING([--disable-example-progs], [Don't build libcdio sample programs])) + AS_HELP_STRING([--disable-example-progs],[Don't build libcdio sample programs])) AM_CONDITIONAL(BUILD_EXAMPLES, test "x$enable_example_progs" != "xno") @@ -133,7 +133,7 @@ else SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $OPT" AC_MSG_CHECKING([whether $CC understands $OPT]) - AC_TRY_COMPILE([], [], has_option=yes, has_option=no,) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[has_option=yes],[has_option=no]) CFLAGS="$SAVE_CFLAGS" AC_MSG_RESULT($has_option) if test "x$has_option" = "xyes"; then @@ -193,7 +193,9 @@ AC_DEFINE(LIBCDIO_CONFIG_H, 1, dnl headers -AC_HEADER_STDC +AC_CHECK_INCLUDES_DEFAULT +AC_PROG_EGREP + AC_CHECK_HEADERS(stdbool.h, [], [AC_MSG_ERROR(["Couldn't find or include stdbool.h"])]) AC_CHECK_HEADERS(alloca.h errno.h fcntl.h glob.h limits.h pwd.h) AC_CHECK_HEADERS(stdarg.h stdbool.h stdio.h sys/cdio.h sys/param.h \ @@ -215,10 +217,10 @@ AC_C_INLINE ## ISOC99_PRAGMA AC_MSG_CHECKING([whether $CC supports ISOC99 _Pragma()]) -AC_TRY_COMPILE([],[_Pragma("pack(1)")], [ +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[_Pragma("pack(1)")]])],[ ISOC99_PRAGMA=yes AC_DEFINE(HAVE_ISOC99_PRAGMA, [], [Supports ISO _Pragma() macro]) -],ISOC99_PRAGMA=no) +],[ISOC99_PRAGMA=no]) AC_MSG_RESULT($ISOC99_PRAGMA) ## Check for Windows header files @@ -262,10 +264,10 @@ dnl empty_array_size AC_MSG_CHECKING([how to create empty arrays]) empty_array_size="xxxx" -AC_TRY_COMPILE([],[struct { int foo; int bar[]; } doo;], empty_array_size="") +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[struct { int foo; int bar[]; } doo;]])],[empty_array_size=""],[]) if test "x$empty_array_size" = "xxxx"; then - AC_TRY_COMPILE([],[struct { int foo; int bar[0]; } doo;], empty_array_size="0") + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[struct { int foo; int bar[0]; } doo;]])],[empty_array_size="0"],[]) fi if test "x$empty_array_size" = "xxxx"; then @@ -416,12 +418,11 @@ case $host_os in AC_CHECK_HEADERS(linux/version.h linux/major.h) AC_CHECK_HEADERS(linux/cdrom.h, [have_linux_cdrom_h="yes"]) if test "x$have_linux_cdrom_h" = "xyes"; then - AC_TRY_COMPILE(,[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ #include <linux/cdrom.h> struct cdrom_generic_command test; -int has_timeout=sizeof(test.timeout);], - [AC_DEFINE([HAVE_LINUX_CDROM_TIMEOUT], [1], - [Define 1 if timeout is in cdrom_generic_command struct])]) +int has_timeout=sizeof(test.timeout);]])],[AC_DEFINE([HAVE_LINUX_CDROM_TIMEOUT], [1], + [Define 1 if timeout is in cdrom_generic_command struct])],[]) AC_DEFINE([HAVE_LINUX_CDROM], [1], [Define 1 if you have Linux-type CD-ROM support]) cd_drivers="${cd_drivers}, GNU/Linux" @@ -608,7 +609,7 @@ fi AC_SUBST(HAVE_JOLIET) AC_ARG_ENABLE(rock, - AC_HELP_STRING([--enable-rock], [include Rock-Ridge extension support (default enabled)]), + AS_HELP_STRING([--enable-rock],[include Rock-Ridge extension support (default enabled)]), enable_rock=$enableval, enable_rock=yes) if test "x${enable_rock}" != "xno"; then AC_DEFINE(HAVE_ROCK, [1], @@ -620,7 +621,7 @@ AC_SUBST(MINGW32) AM_CONDITIONAL(ENABLE_ROCK, test "x$enable_rock" = "xyes") AC_ARG_ENABLE(cddb, - AC_HELP_STRING([--enable-cddb], [include CDDB lookups in cd_info (default enabled)]), + AS_HELP_STRING([--enable-cddb],[include CDDB lookups in cd_info (default enabled)]), enable_cddb=$enableval, enable_cddb=check) if test "x$enable_cddb" != "xno"; then PKG_CHECK_MODULES(CDDB, libcddb >= 1.0.1, [ @@ -636,7 +637,7 @@ fi AC_SUBST(CDDB_LIBS) AC_ARG_ENABLE(compatibility, - AC_HELP_STRING([--disable-compatibility], [disable the use of obsoleted APIs (default enabled)]), + AS_HELP_STRING([--disable-compatibility],[disable the use of obsoleted APIs (default enabled)]), enable_compatibility=$enableval, enable_compatibility=yes) if test "x${enable_compatibility}" != "xyes"; then AC_DEFINE(DO_NOT_WANT_COMPATIBILITY, [], @@ -673,7 +674,7 @@ AM_CONDITIONAL(BUILD_CDDA_PLAYER, test "x$enable_cdda_player" = "xyes") AC_SUBST(CDDA_PLAYER_LIBS) AC_ARG_ENABLE(vcd_info, - AC_HELP_STRING([--enable-vcd-info], [include Video CD Info from libvcd]), + AS_HELP_STRING([--enable-vcd-info],[include Video CD Info from libvcd]), enable_vcd_info=${enableval}, enable_vcd_info=no) if test "x$enable_vcd_info" = "xyes"; then diff --git a/doc/libcdio.texi b/doc/libcdio.texi index 991bbd2d..008402a7 100644 --- a/doc/libcdio.texi +++ b/doc/libcdio.texi @@ -458,7 +458,7 @@ CDs. There are currently two popular CDDB services on the Internet. The original database has been renamed Gracenote and is a profit making -entity. FreeDB (@url{http://freedb.org} is an open source CD +entity. GnuDB (@url{https://gnudb.org} is an open source CD information resource that is free for developers and the public to use. diff --git a/include/cdio/iso9660.h b/include/cdio/iso9660.h index 04308909..f5eb09e2 100644 --- a/include/cdio/iso9660.h +++ b/include/cdio/iso9660.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2003-2008, 2012-2013, 2017 + Copyright (C) 2003-2008, 2012-2013, 2017, 2023 Rocky Bernstein <rocky@gnu.org> Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org> @@ -27,7 +27,7 @@ * filesystem library; applications include this. * * See also the ISO-9660 specification. The freely available European - * equivalant standard is called ECMA-119. + * equivalent standard is called ECMA-119. */ @@ -78,7 +78,7 @@ typedef char dchar_t; /*! See section 7.4.1 */ program; things are done this way so that in a debugger one can to refer to the enumeration value names such as in a debugger expression and get something. With the more common a \#define - mechanism, the name/value assocation is lost at run time. + mechanism, the name/value association is lost at run time. */ extern enum iso_enum1_s { ISO_PVD_SECTOR = 16, /**< Sector of Primary Volume Descriptor. */ @@ -395,7 +395,7 @@ typedef struct iso9660_pvd_s iso9660_pvd_t; /*! \brief ISO-9660 Supplementary Volume Descriptor. - This is used for Joliet Extentions and is almost the same as the + This is used for Joliet Extensions and is almost the same as the the primary descriptor but two unused fields, "unused1" and "unused3 become "flags and "escape_sequences" respectively. */ @@ -550,7 +550,7 @@ struct iso9660_stat_s { /* big endian!! */ /* Multi-extent aware size, in bytes. It is guaranteed that the bytes are stored as gapless string in a - continguous sequence of blocks. I.e. they can be read sequentially + contiguous sequence of blocks. I.e. they can be read sequentially starting at iso9660_stat_s.lsn. Data files which do not fulfil this promise cause a warning message and are not represented by this type of struct. @@ -638,7 +638,7 @@ typedef struct _iso9660_s iso9660_t; contained in a file format that libiso9660 doesn't know natively (or knows imperfectly.) - Some tolerence allowed for positioning the ISO 9660 image. We scan + Some tolerance allowed for positioning the ISO 9660 image. We scan for STANDARD_ID and use that to set the eventual offset to adjust by (as long as that is <= i_fuzz). @@ -650,7 +650,7 @@ typedef struct _iso9660_s iso9660_t; uint16_t i_fuzz); /*! - Open an ISO 9660 image for reading with some tolerence for positioning + Open an ISO 9660 image for reading with some tolerance for positioning of the ISO9660 image. We scan for ISO_STANDARD_ID and use that to set the eventual offset to adjust by (as long as that is <= i_fuzz). @@ -766,7 +766,7 @@ typedef struct _iso9660_s iso9660_t; tm will reported in GMT. */ bool iso9660_get_dtime (const iso9660_dtime_t *idr_date, bool b_localtime, - /*out*/ struct tm *tm); + /*out*/ struct tm *p_tm); /*! @@ -857,7 +857,7 @@ typedef struct _iso9660_s iso9660_t; /*! Take psz_path and a version number and turn that into a ISO-9660 - pathname. (That's just the pathname followd by ";" and the version + pathname. (That's just the pathname followed by ";" and the version number. For example, mydir/file.ext -> MYDIR/FILE.EXT;1 for version 1. The resulting ISO-9660 pathname is returned. */ @@ -1202,7 +1202,7 @@ lsn_t iso9660_get_dir_extent(const iso9660_dir_t *p_idr); @param p_iso the ISO-9660 file image to get data from - @param u_file_limit the maximimum number of (non-rock-ridge) files + @param u_file_limit the maximum number of (non-rock-ridge) files to consider before giving up and returning "dunno". "dunno" can also be returned if there was some error encountered @@ -1278,7 +1278,7 @@ lsn_t iso9660_get_dir_extent(const iso9660_dir_t *p_idr); void iso9660_set_evd (void *pd); /*! - Return true if ISO 9660 image has extended attrributes (XA). + Return true if ISO 9660 image has extended attributes (XA). */ bool iso9660_ifs_is_xa (const iso9660_t * p_iso); diff --git a/include/cdio/rock.h b/include/cdio/rock.h index 33774c7a..ff26835b 100644 --- a/include/cdio/rock.h +++ b/include/cdio/rock.h @@ -98,24 +98,24 @@ PRAGMA_BEGIN_PACKED /*! system-use-sharing protocol */ typedef struct iso_su_sp_s{ - unsigned char magic[2]; + uint8_t magic[2]; uint8_t skip; } GNUC_PACKED iso_su_sp_t; /*! system-use extension record */ typedef struct iso_su_er_s { iso711_t len_id; /**< Identifier length. Value 10?. */ - unsigned char len_des; - unsigned char len_src; + uint8_t len_des; + uint8_t len_src; iso711_t ext_ver; /**< Extension version. Value 1? */ - char data[EMPTY_ARRAY_SIZE]; + char data[EMPTY_ARRAY_SIZE]; } GNUC_PACKED iso_su_er_t; typedef struct iso_su_ce_s { - char extent[8]; - char offset[8]; - char 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 { @@ -165,7 +165,7 @@ typedef struct iso_rock_sl_part_s { /*! Symbolic link. See Rock Ridge Section 4.1.3 */ typedef struct iso_rock_sl_s { - unsigned char flags; + uint8_t flags; iso_rock_sl_part_t link; } GNUC_PACKED iso_rock_sl_t ; @@ -184,7 +184,7 @@ typedef enum { typedef struct iso_rock_nm_s { - unsigned char flags; + uint8_t flags; char name[EMPTY_ARRAY_SIZE]; } GNUC_PACKED iso_rock_nm_t ; diff --git a/lib/iso9660/iso9660.c b/lib/iso9660/iso9660.c index ae4edda3..06e7554e 100644 --- a/lib/iso9660/iso9660.c +++ b/lib/iso9660/iso9660.c @@ -721,7 +721,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/lib/iso9660/iso9660_fs.c b/lib/iso9660/iso9660_fs.c index be693c7e..f18a2a16 100644 --- a/lib/iso9660/iso9660_fs.c +++ b/lib/iso9660/iso9660_fs.c @@ -793,6 +793,49 @@ _iso9660_is_rock_ridge_enabled(void* p_image) return true; } +/*! + Convert a directory record name to a 0-terminated string. + One of parameters alloc_result and cpy_result should be non-NULL to take + the result. +*/ +static bool +_iso9660_recname_to_cstring(const char *src, size_t src_len, + cdio_utf8_t **alloc_result, + cdio_utf8_t *cpy_result, uint8_t u_joliet_level) +{ +#ifdef HAVE_JOLIET + if (u_joliet_level) { + int i_inlen = src_len; + cdio_utf8_t *p_psz_out = NULL; + + if (cdio_charset_to_utf8(src, i_inlen, &p_psz_out, "UCS-2BE")) { + if (cpy_result != NULL) + strcpy(cpy_result, p_psz_out); + if (alloc_result != NULL) + *alloc_result = p_psz_out; + else + free(p_psz_out); + } else { + return false; + } + } else +#endif /*HAVE_JOLIET*/ + { + if (alloc_result != NULL) { + *alloc_result = calloc(1, src_len + 1); + if (*alloc_result == NULL) + return false; + strncpy(*alloc_result, src, src_len); + (*alloc_result)[src_len] = 0; + } + if (cpy_result != NULL) { + strncpy(cpy_result, src, src_len); + cpy_result[src_len] = 0; + } + } + return true; +} + static iso9660_stat_t * _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir, iso9660_stat_t *last_p_stat, @@ -866,8 +909,17 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir, if ((p_iso9660_dir->file_flags & ISO_MULTIEXTENT) == 0) { /* Check if this is the last part of a multiextent file */ if (!first_extent) { - if (strlen(p_stat->filename) != i_fname || - strncmp(p_stat->filename, &p_iso9660_dir->filename.str[1], i_fname) != 0) { + cdio_utf8_t *p_psz_out = NULL; + int bad_multi; + int i_inlen = i_fname; + + if (!_iso9660_recname_to_cstring(&p_iso9660_dir->filename.str[1], + i_inlen, &p_psz_out, NULL, + u_joliet_level)) + goto fail; + bad_multi = (strcmp(p_stat->filename, p_psz_out) != 0); + free(p_psz_out); + if (bad_multi) { cdio_warn("Non consecutive multiextent file parts for '%s'", p_stat->filename); goto fail; @@ -893,30 +945,26 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir, } strncpy(p_stat->filename, rr_fname, i_rr_fname+1); } else { - if ('0円' == p_iso9660_dir->filename.str[1] && 1 == i_fname) + if ('0円' == p_iso9660_dir->filename.str[1] && 1 == i_fname) { strncpy (p_stat->filename, ".", strlen(".")+1); - else if ('1円' == p_iso9660_dir->filename.str[1] && 1 == i_fname) + } else if ('1円' == p_iso9660_dir->filename.str[1] && 1 == i_fname) { strncpy (p_stat->filename, "..", strlen("..")+1); -#ifdef HAVE_JOLIET - else if (u_joliet_level) { + } else { int i_inlen = i_fname; - cdio_utf8_t *p_psz_out = NULL; - if (cdio_charset_to_utf8(&p_iso9660_dir->filename.str[1], i_inlen, - &p_psz_out, "UCS-2BE")) { - strncpy(p_stat->filename, p_psz_out, i_fname); - free(p_psz_out); - } else { - goto fail; - } - } -#endif /*HAVE_JOLIET*/ - else { - strncpy (p_stat->filename, &p_iso9660_dir->filename.str[1], i_fname); + + if (!_iso9660_recname_to_cstring(&p_iso9660_dir->filename.str[1], + i_inlen, NULL, p_stat->filename, + u_joliet_level)) + goto fail; } } } else { - /* Use the plain ISO-9660 name when dealing with a multiextent file part */ - strncpy(p_stat->filename, &p_iso9660_dir->filename.str[1], i_fname); + int i_inlen = i_fname; + + if (!_iso9660_recname_to_cstring(&p_iso9660_dir->filename.str[1], + i_inlen, NULL, p_stat->filename, + u_joliet_level)) + goto fail; } iso9660_get_dtime(&(p_iso9660_dir->recording_time), true, &(p_stat->tm)); diff --git a/lib/iso9660/rock.c b/lib/iso9660/rock.c index ff420dca..fd03be24 100644 --- a/lib/iso9660/rock.c +++ b/lib/iso9660/rock.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2020 Pete Batard <pete@akeo.ie> + Copyright (C) 2020, 2023 Pete Batard <pete@akeo.ie> Copyright (C) 2005, 2008, 2010-2011, 2014, 2017, 2022 Rocky Bernstein <rocky@gnu.org> @@ -20,7 +20,8 @@ */ /* Rock Ridge Extensions to iso9660 */ - + + #ifdef HAVE_CONFIG_H # include "config.h" #endif @@ -94,34 +95,36 @@ realloc_symlink(/*in/out*/ iso9660_stat_t *p_stat, uint8_t i_grow) /* This is a way of ensuring that we have something in the system use fields that is compatible with Rock Ridge */ -#define CHECK_SP(FAIL) \ - if(rr->u.SP.magic[0] != 0xbe) FAIL; \ - if(rr->u.SP.magic[1] != 0xef) FAIL; \ +#define CHECK_SP(FAIL) \ + if (rr->u.SP.magic[0] != 0xbe) FAIL; \ + if (rr->u.SP.magic[1] != 0xef) FAIL; \ p_stat->rr.s_rock_offset = rr->u.SP.skip; /* We define a series of macros because each function must do exactly the same thing in certain places. We use the macros to ensure that everything is done correctly */ #define CONTINUE_DECLS \ - int cont_extent = 0, cont_offset = 0, cont_size = 0; \ - void *buffer = NULL - -#define CHECK_CE \ - { cont_extent = from_733(*rr->u.CE.extent); \ - cont_offset = from_733(*rr->u.CE.offset); \ - cont_size = from_733(*rr->u.CE.size); \ - (void)cont_extent; (void)cont_offset, (void)cont_size; } + uint32_t cont_extent = 0, cont_offset = 0, cont_size = 0; \ + 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); \ + if (cont_offset >= ISO_BLOCKSIZE) FAIL; \ + 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++; \ + if (LEN & 1) LEN++; \ CHR = ((unsigned char *) DE) + LEN; \ LEN = *((unsigned char *) DE) - LEN; \ if (0xff != p_stat->rr.s_rock_offset) \ { \ - LEN -= p_stat->rr.s_rock_offset; \ - CHR += p_stat->rr.s_rock_offset; \ + LEN -= p_stat->rr.s_rock_offset; \ + CHR += p_stat->rr.s_rock_offset; \ if (LEN<0) LEN=0; \ } \ } @@ -130,22 +133,22 @@ realloc_symlink(/*in/out*/ iso9660_stat_t *p_stat, uint8_t i_grow) the specified field of a iso_rock_statbuf_t. non-paramater variables are p_stat, rr, and cnt. */ -#define add_time(FLAG, TIME_FIELD) \ - if (rr->u.TF.flags & FLAG) { \ - p_stat->rr.TIME_FIELD.b_used = true; \ - p_stat->rr.TIME_FIELD.b_longdate = \ - (0 != (rr->u.TF.flags & ISO_ROCK_TF_LONG_FORM)); \ - if (p_stat->rr.TIME_FIELD.b_longdate) { \ - memcpy(&(p_stat->rr.TIME_FIELD.t.ltime), \ - &(rr->u.TF.time_bytes[cnt]), \ - sizeof(iso9660_ltime_t)); \ - cnt += sizeof(iso9660_ltime_t); \ - } else { \ - memcpy(&(p_stat->rr.TIME_FIELD.t.dtime), \ - &(rr->u.TF.time_bytes[cnt]), \ - sizeof(iso9660_dtime_t)); \ - cnt += sizeof(iso9660_dtime_t); \ - } \ +#define add_time(FLAG, TIME_FIELD) \ + if (rr->u.TF.flags & FLAG) { \ + p_stat->rr.TIME_FIELD.b_used = true; \ + p_stat->rr.TIME_FIELD.b_longdate = \ + (0 != (rr->u.TF.flags & ISO_ROCK_TF_LONG_FORM)); \ + if (p_stat->rr.TIME_FIELD.b_longdate) { \ + memcpy(&(p_stat->rr.TIME_FIELD.t.ltime), \ + &(rr->u.TF.time_bytes[cnt]), \ + sizeof(iso9660_ltime_t)); \ + cnt += sizeof(iso9660_ltime_t); \ + } else { \ + memcpy(&(p_stat->rr.TIME_FIELD.t.dtime), \ + &(rr->u.TF.time_bytes[cnt]), \ + sizeof(iso9660_dtime_t)); \ + cnt += sizeof(iso9660_dtime_t); \ + } \ } /* Indicates if we should process deep directory entries */ @@ -179,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; @@ -202,7 +205,7 @@ get_rock_ridge_filename(iso9660_dir_t * p_iso9660_dir, switch(sig) { case SIG('S','P'): - CHECK_SP(goto out); + CHECK_SP({cdio_warn("Invalid Rock Ridge SP field"); goto out;}); p_stat->rr.u_su_fields |= ISO_ROCK_SUF_SP; break; case SIG('C','E'): @@ -213,8 +216,12 @@ get_rock_ridge_filename(iso9660_dir_t * p_iso9660_dir, if ('1円' == p_iso9660_dir->filename.str[1] && 1 == i_fname) break; } - CHECK_CE; + CHECK_CE({cdio_warn("Invalid Rock Ridge CE field"); goto out;}); p_stat->rr.u_su_fields |= ISO_ROCK_SUF_CE; + /* 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: "); @@ -368,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/cd-info.c b/src/cd-info.c index 21d5606a..fa3d6eb5 100644 --- a/src/cd-info.c +++ b/src/cd-info.c @@ -2,7 +2,7 @@ Copyright (C) 2003-2005, 2007-2008, 2011-2012, 2014, 2017 Rocky Bernstein <rocky@gnu.org> Copyright (C) 1996, 1997, 1998 Gerd Knorr <kraxel@bytesex.org> - and Heiko Ei�feldt <heiko@hexco.de> + and Heiko Eißfeldt <heiko@hexco.de> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -199,7 +199,7 @@ parse_options (int argc, char *argv[]) " -H, --cddb-http Lookup CDDB via HTTP proxy (default no\n" " proxy)\n" " --cddb-server=STRING CDDB server to contact for information\n" - " (default: freedb.freedb.org)\n" + " (default: gnudb.gnudb.org)\n" " --cddb-cache=STRING Location of CDDB cache directory\n" " (default ~/.cddbclient)\n" " --cddb-email=STRING Email address to give CDDB server\n" diff --git a/src/cddb.c b/src/cddb.c index fd23b791..5bc781d0 100644 --- a/src/cddb.c +++ b/src/cddb.c @@ -90,7 +90,7 @@ init_cddb(CdIo_t *p_cdio, cddb_conn_t **pp_conn, cddb_disc_t **pp_cddb_disc, cddb_set_email_address(*pp_conn, cddb_opts.email); if (NULL == cddb_opts.server) - cddb_set_server_name(*pp_conn, "freedb.freedb.org"); + cddb_set_server_name(*pp_conn, "gnudb.gnudb.org"); else cddb_set_server_name(*pp_conn, cddb_opts.server); diff --git a/test/check_multiextent.sh b/test/check_multiextent.sh index cdb93c47..ac2705a1 100755 --- a/test/check_multiextent.sh +++ b/test/check_multiextent.sh @@ -36,19 +36,29 @@ fi BASE=`basename 0ドル .sh` -fname=multiextent - -# File listing -iso_image="${srcdir}/data/multi_extent_8k.iso" -opts="--no-header --quiet -l ${iso_image}" -test_iso_info "$opts" ${fname}.dump ${srcdir}/${fname}.right -RC=$? -check_result $RC 'Multiextent listing test' "$ISO_INFO $opts" - -# File dump and comparison -opts="--ignore --image ${iso_image} --extract multi_extent_file" -test_iso_read "$opts" ${fname} ${srcdir}/data/multi_extent_file -RC=$? -check_result $RC 'Multiextent read test' "$ISO_READ $opts" +for i in multi_extent_8k.iso multi_extent_8k_joliet.iso +do + if test "$i" = multi_extent_8k.iso + then + fname=multiextent + aspect="ISO 9660 + Rock Ridge" + else + fname=multiextent_joliet + aspect="Joliet" + fi + + # File listing + iso_image="${srcdir}/data/${i}" + opts="--no-header --quiet -l ${iso_image}" + test_iso_info "$opts" ${fname}.dump ${srcdir}/${fname}.right + RC=$? + check_result $RC "$aspect"' multiextent listing test' "$ISO_INFO $opts" + + # File dump and comparison + opts="--ignore --image ${iso_image} --extract multi_extent_file" + test_iso_read "$opts" ${fname} ${srcdir}/data/multi_extent_file + RC=$? + check_result $RC "$aspect"' multiextent read test' "$ISO_READ $opts" +done exit $RC diff --git a/test/data/multi_extent_8k.iso b/test/data/multi_extent_8k.iso Binary files differindex b002412d..33fc6e38 100644 --- a/test/data/multi_extent_8k.iso +++ b/test/data/multi_extent_8k.iso diff --git a/test/data/multi_extent_8k_joliet.iso b/test/data/multi_extent_8k_joliet.iso Binary files differnew file mode 100644 index 00000000..c8876a70 --- /dev/null +++ b/test/data/multi_extent_8k_joliet.iso diff --git a/test/multiextent.right b/test/multiextent.right index 816cd438..97cab855 100644 --- a/test/multiextent.right +++ b/test/multiextent.right @@ -1,7 +1,7 @@ __________________________________ ISO-9660 Information /: - drwxr-xr-x 1 0 0 [LSN 50] 2048 Jun 27 2018 08:21:56 . - drwxr-xr-x 1 0 0 [LSN 50] 2048 Jun 27 2018 08:21:56 .. - -rw-r--r-- 1 1000 1000 [LSN 55] 54305 Jun 10 2018 17:52:58 multi_extent_file + drwxr-xr-x 1 0 0 [LSN 18] 2048 Mar 27 2023 14:09:08 . + drwxr-xr-x 1 0 0 [LSN 18] 2048 Mar 27 2023 14:09:08 .. + -rw-r--r-- 1 1007 1001 [LSN 33] 54305 Jun 17 2020 19:29:52 multi_extent_file diff --git a/test/multiextent_joliet.right b/test/multiextent_joliet.right new file mode 100644 index 00000000..31ac8dcc --- /dev/null +++ b/test/multiextent_joliet.right @@ -0,0 +1,7 @@ +__________________________________ +ISO-9660 Information +/: + d [LSN 22] 2048 Mar 27 2023 14:08:05 . + d [LSN 22] 2048 Mar 27 2023 14:08:05 .. + - [LSN 33] 54305 Jun 17 2020 19:29:52 multi_extent_file + |