diff --git a/NEWS b/NEWS index 552dc2c4..cd539f20 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,8 @@ - FreeBSD 6 tolerated - improve Win32 driver - mode detection fixes +- all read routines check and adjust so we don't try to access beyond the + end of the disc - C++ fixes - Update doc @@ -169,4 +171,4 @@ 0.1 Routines split off from VCDImager. -$Id: NEWS,v 1.60 2005/01/18 03:46:40 rocky Exp $ +$Id: NEWS,v 1.61 2005/01/21 10:11:23 rocky Exp $ diff --git a/lib/driver/_cdio_stream.c b/lib/driver/_cdio_stream.c index 452cc13a..84bcd901 100644 --- a/lib/driver/_cdio_stream.c +++ b/lib/driver/_cdio_stream.c @@ -1,5 +1,5 @@ /* - $Id: _cdio_stream.c,v 1.2 2005/01/20 01:00:52 rocky Exp $ + $Id: _cdio_stream.c,v 1.3 2005/01/21 10:11:24 rocky Exp $ Copyright (C) 2000, 2004, 2005 Herbert Valerio Riedel @@ -34,7 +34,7 @@ #include #include "_cdio_stream.h" -static const char _rcsid[] = "$Id: _cdio_stream.c,v 1.2 2005/01/20 01:00:52 rocky Exp $"; +static const char _rcsid[] = "$Id: _cdio_stream.c,v 1.3 2005/01/21 10:11:24 rocky Exp $"; /* * DataSource implementations @@ -54,7 +54,7 @@ struct _CdioDataSource { static bool _cdio_stream_open_if_necessary(CdioDataSource_t *p_obj) { - cdio_assert (p_obj != NULL); + if (!p_obj) return false; if (!p_obj->is_open) { if (p_obj->op.open(p_obj->user_data)) { @@ -89,7 +89,7 @@ _cdio_stream_open_if_necessary(CdioDataSource_t *p_obj) long cdio_stream_seek(CdioDataSource_t* p_obj, long int offset, int whence) { - cdio_assert (p_obj != NULL); + if (!p_obj) return -1; if (!_cdio_stream_open_if_necessary(p_obj)) /* errno is set by _cdio_stream_open_if necessary. */ @@ -141,8 +141,7 @@ cdio_stream_read(CdioDataSource_t* p_obj, void *ptr, long size, long nmemb) { long read_bytes; - cdio_assert (p_obj != NULL); - + if (!p_obj) return 0; if (!_cdio_stream_open_if_necessary(p_obj)) return 0; read_bytes = p_obj->op.read(p_obj->user_data, ptr, size*nmemb); @@ -158,8 +157,7 @@ cdio_stream_read(CdioDataSource_t* p_obj, void *ptr, long size, long nmemb) long int cdio_stream_stat(CdioDataSource_t *p_obj) { - cdio_assert (p_obj != NULL); - + if (!p_obj) return -1; if (!_cdio_stream_open_if_necessary(p_obj)) return -1; return p_obj->op.stat(p_obj->user_data); @@ -168,7 +166,7 @@ cdio_stream_stat(CdioDataSource_t *p_obj) void cdio_stream_close(CdioDataSource_t *p_obj) { - cdio_assert (p_obj != NULL); + if (!p_obj) return; if (p_obj->is_open) { cdio_debug ("closed source..."); @@ -181,7 +179,7 @@ cdio_stream_close(CdioDataSource_t *p_obj) void cdio_stream_destroy(CdioDataSource_t *p_obj) { - cdio_assert (p_obj != NULL); + if (!p_obj) return; cdio_stream_close(p_obj); diff --git a/lib/driver/image.h b/lib/driver/image.h index 292c59e1..25651fa4 100644 --- a/lib/driver/image.h +++ b/lib/driver/image.h @@ -1,5 +1,5 @@ /* - $Id: image.h,v 1.4 2005/01/20 01:00:52 rocky Exp $ + $Id: image.h,v 1.5 2005/01/21 10:11:24 rocky Exp $ Copyright (C) 2004, 2005 Rocky Bernstein @@ -57,6 +57,12 @@ typedef struct { char *isrc; /**< IRSC Code (5.22.4) exactly 12 bytes */ char *filename; CdioDataSource_t *data_source; + off_t offset; /**< byte offset into data_start of track + beginning. In cdrdao for example, one + filename may cover many tracks and + each track would then have a different + offset. + */ track_format_t track_format; bool track_green; cdtext_t cdtext; /**< CD-TEXT */ @@ -64,7 +70,8 @@ typedef struct { trackmode_t mode; uint16_t datasize; /**< How much is in the portion we return back? */ - long int datastart; /**< Offset from begining that data starts */ + long int datastart; /**< Offset from begining of fraem + that data starts */ uint16_t endsize; /**< How much stuff at the end to skip over. This stuff may have error correction (EDC, or ECC).*/ diff --git a/lib/driver/image/cdrdao.c b/lib/driver/image/cdrdao.c index ff409e46..2f17d932 100644 --- a/lib/driver/image/cdrdao.c +++ b/lib/driver/image/cdrdao.c @@ -1,5 +1,5 @@ /* - $Id: cdrdao.c,v 1.7 2005/01/18 00:57:20 rocky Exp $ + $Id: cdrdao.c,v 1.8 2005/01/21 10:11:24 rocky Exp $ Copyright (C) 2004, 2005 Rocky Bernstein toc reading routine adapted from cuetools @@ -25,7 +25,7 @@ (*.cue). */ -static const char _rcsid[] = "$Id: cdrdao.c,v 1.7 2005/01/18 00:57:20 rocky Exp $"; +static const char _rcsid[] = "$Id: cdrdao.c,v 1.8 2005/01/21 10:11:24 rocky Exp $"; #include "image.h" #include "cdio_assert.h" @@ -70,6 +70,25 @@ static uint32_t _stat_size_cdrdao (void *p_user_data); static bool parse_tocfile (_img_private_t *cd, const char *p_toc_name); +static bool +check_track_is_blocksize_multiple(const char *psz_fname, + track_t i_track, long i_size, + long i_blocksize) +{ + if (i_size % i_blocksize) { + cdio_info ("image %s track %d size (%ld) not a multiple" + " of the blocksize (%ld)", psz_fname, i_track, i_size, + i_blocksize); + if (i_size % M2RAW_SECTOR_SIZE == 0) + cdio_info ("this may be a 2336-type disc image"); + else if (i_size % CDIO_CD_FRAMESIZE_RAW == 0) + cdio_info ("this may be a 2352-type disc image"); + return false; + } + return true; +} + + /*! Initialize image structures. */ @@ -213,27 +232,26 @@ _read_cdrdao (void *user_data, void *data, size_t size) Return the size of the CD in logical block address (LBA) units. */ static uint32_t -_stat_size_cdrdao (void *user_data) +_stat_size_cdrdao (void *p_user_data) { - _img_private_t *env = user_data; - long size; + _img_private_t *p_env = p_user_data; + track_t i_leadout = p_env->gen.i_tracks; + long i_blocksize = p_env->tocent[i_leadout-1].blocksize; + long i_size = cdio_stream_stat(p_env->tocent[i_leadout-1].data_source) + - p_env->tocent[i_leadout-1].offset; - size = cdio_stream_stat (env->tocent[0].data_source); + if (check_track_is_blocksize_multiple(p_env->tocent[i_leadout-1].filename, + i_leadout-1, i_size, i_blocksize)) { + i_size /= i_blocksize; + } else { + /* Round up */ + i_size = (i_size / i_blocksize) + 1; + } + + i_size += p_env->tocent[i_leadout-1].start_lba; + i_size -= CDIO_PREGAP_SECTORS; - if (size % CDIO_CD_FRAMESIZE_RAW) - { - cdio_warn ("image %s size (%ld) not multiple of blocksize (%d)", - env->tocent[0].filename, size, CDIO_CD_FRAMESIZE_RAW); - if (size % M2RAW_SECTOR_SIZE == 0) - cdio_warn ("this may be a 2336-type disc image"); - else if (size % CDIO_CD_FRAMESIZE_RAW == 0) - cdio_warn ("this may be a 2352-type disc image"); - /* exit (EXIT_FAILURE); */ - } - - size /= CDIO_CD_FRAMESIZE_RAW; - - return size; + return i_size; } #define MAXLINE 512 @@ -685,12 +703,13 @@ parse_tocfile (_img_private_t *cd, const char *psz_cue_name) } } - if (NULL != (psz_field = strtok (NULL, " \t\n\r"))) { + psz_field = strtok (NULL, " \t\n\r"); + if (psz_field) { /* Handle optional #byte-offset */ if ( psz_field[0] == '#') { - long int datastart; + long int offset; psz_field++; - datastart = strtol(psz_field, (char **)NULL, 10); + offset = strtol(psz_field, (char **)NULL, 10); if ( 0 != errno ) { cdio_log (log_level, "%s line %d: can't convert `%s' to byte offset", @@ -698,13 +717,13 @@ parse_tocfile (_img_private_t *cd, const char *psz_cue_name) goto err_exit; } else { if (NULL != cd) { - cd->tocent[i].datastart = datastart; + cd->tocent[i].offset = offset; } } psz_field = strtok (NULL, " \t\n\r"); } } - if (NULL != psz_field) { + if (psz_field) { /* Handle start-msf */ lba_t lba = cdio_mmssff_to_lba (psz_field); if (CDIO_INVALID_LBA == lba) { @@ -712,12 +731,32 @@ parse_tocfile (_img_private_t *cd, const char *psz_cue_name) psz_cue_name, i_line, psz_field); goto err_exit; } - if (NULL != cd) { + if (cd) { cd->tocent[i].start_lba = lba; cdio_lba_to_msf(cd->tocent[i].start_lba, &(cd->tocent[i].start_msf)); } + } else { + /* No start-msf. */ + if (cd) { + if (i) { + long i_blocksize = cd->tocent[i-1].blocksize; + long i_size = + cdio_stream_stat(cd->tocent[i-1].data_source); + + check_track_is_blocksize_multiple(cd->tocent[i-1].filename, + i-1, i_size, i_blocksize); + /* Append size of previous datafile. */ + cd->tocent[i].start_lba = cd->tocent[i-1].start_lba + + (i_size / i_blocksize); + } + cd->tocent[i].offset = 0; + cd->tocent[i].start_lba += CDIO_PREGAP_SECTORS; + cdio_lba_to_msf(cd->tocent[i].start_lba, + &(cd->tocent[i].start_msf)); + } } + } else { goto not_in_global_section; } @@ -1107,7 +1146,7 @@ _get_track_green_cdrdao(void *user_data, track_t i_track) Return the starting LSN track number i_track in obj. Track numbers start at 1. The "leadout" track is specified either by - using i_track LEADOUT_TRACK or the total tracks+1. + using i_track CDIO_CDROM_LEADOUT_TRACK or the total tracks+1. False is returned if there is no track entry. */ static lba_t diff --git a/test/vcd_demo_toc.right b/test/vcd_demo_toc.right index 59814dd2..16a0f7cd 100644 --- a/test/vcd_demo_toc.right +++ b/test/vcd_demo_toc.right @@ -8,7 +8,7 @@ CD-ROM Track List (1 - 3) 1: 00:02:00 000000 XA true yes 2: 00:17:57 001182 XA true yes 3: 00:24:71 001721 XA true yes -170: 00:30:10 002110 leadout (4 MB raw, 4 MB formatted) +170: 00:53:06 003831 leadout (8 MB raw, 8 MB formatted) Media Catalog Number (MCN): not available __________________________________ CD Analysis Report