diff --git a/lib/cdda_interface/toc.c b/lib/cdda_interface/toc.c index 2e32be8..05470f0 100644 --- a/lib/cdda_interface/toc.c +++ b/lib/cdda_interface/toc.c @@ -61,7 +61,7 @@ cdda_track_firstsector(cdrom_drive_t *d, track_t i_track) } } -/*! Get first lsn of the first audio track. -1 is returned on error. */ +/*! Get first lsn of the first audio track. -ERROR_CODE is returned on error. */ lsn_t cdda_disc_firstsector(cdrom_drive_t *d) { @@ -87,7 +87,7 @@ cdda_disc_firstsector(cdrom_drive_t *d) } /*! Get last lsn of the track. The lsn is generally one less than the - start of the next track. -1 is returned on error. */ + start of the next track. -ERROR_CODE is returned on error. */ lsn_t cdda_track_lastsector(cdrom_drive_t *d, track_t i_track) { @@ -129,7 +129,7 @@ cdda_track_lastsector(cdrom_drive_t *d, track_t i_track) } /*! Get last lsn of the last audio track. The last lssn generally one - less than the start of the next track after the audio track. -1 is + less than the start of the next track after the audio track. -ERROR_CODE is returned on error. */ lsn_t cdda_disc_lastsector(cdrom_drive_t *d) @@ -149,7 +149,7 @@ cdda_disc_lastsector(cdrom_drive_t *d) return -403; } -/*! Return the number of tracks on the or 300 if error. */ +/*! Return the number of tracks on the CD or CDIO_INVALID_TRACK (255) if error. */ track_t cdda_tracks(cdrom_drive_t *d) { diff --git a/src/cd-paranoia.c b/src/cd-paranoia.c index d89af2b..e0bf955 100644 --- a/src/cd-paranoia.c +++ b/src/cd-paranoia.c @@ -1226,11 +1226,19 @@ main(int argc,char *argv[]) } { - int track1 = cdda_sector_gettrack(d, i_first_lsn); + /* Check for errors on lsn before getting track */ + if(i_first_lsn < 0){ + report("Error on begin of span: %li. Aborting.\n\n", i_first_lsn); + exit(1); + } + if(i_last_lsn < 0 ){ + report("Error on end of span: %li. Aborting.\n\n", i_last_lsn); + exit(1); + } + int track1 = cdda_sector_gettrack(d, i_first_lsn); int track2 = cdda_sector_gettrack(d, i_last_lsn); - long off1 = i_first_lsn - cdda_track_firstsector(d, track1); - long off2 = i_last_lsn - cdda_track_firstsector(d, track2); + int i; for( i=track1; i<=track2; i++ ) { @@ -1240,6 +1248,9 @@ main(int argc,char *argv[]) } } + long off1 = i_first_lsn - cdda_track_firstsector(d, track1); + long off2 = i_last_lsn - cdda_track_firstsector(d, track2); + report("Ripping from sector %7ld (track %2d [%d:%02d.%02d])\n" "\t to sector %7ld (track %2d [%d:%02d.%02d])\n", i_first_lsn, @@ -1341,30 +1352,36 @@ main(int argc,char *argv[]) exit(1); } + int res; if(batch) { - if (strlen(argv[optind+1]) - 10 > PATH_MAX) { - report("Output filename too long"); - exit(1); - } - snprintf(outfile_name, PATH_MAX, + res=snprintf(outfile_name, PATH_MAX, " %strack%02d.%s", dirname, batch_track, basename); } else - snprintf(outfile_name, PATH_MAX, "%s%s", dirname, basename); + res=snprintf(outfile_name, PATH_MAX, "%s%s", dirname, basename); + + if(res < 0){ + report("Error on setting filename"); + exit(1); + } + if(res >= PATH_MAX){ + report("Output filename too long"); + exit(1); + } if(basename[0]=='\0'){ switch (output_type) { case 0: /* raw */ - strncat(outfile_name, "cdda.raw", sizeof("cdda.raw")); + strncat(outfile_name, "cdda.raw", PATH_MAX - strlen(outfile_name) - 1); break; case 1: - strncat(outfile_name, "cdda.wav", sizeof("cdda.wav")); + strncat(outfile_name, "cdda.wav", PATH_MAX - strlen(outfile_name) - 1); break; case 2: - strncat(outfile_name, "cdda.aifc", sizeof("cdda.aifc")); + strncat(outfile_name, "cdda.aifc", PATH_MAX - strlen(outfile_name) - 1); break; case 3: - strncat(outfile_name, "cdda.aiff", sizeof("cdda.aiff")); + strncat(outfile_name, "cdda.aiff", PATH_MAX - strlen(outfile_name) - 1); break; } } @@ -1390,16 +1407,16 @@ main(int argc,char *argv[]) switch(output_type){ case 0: /* raw */ - strncat(outfile_name, "cdda.raw", sizeof("cdda.raw")); + strncat(outfile_name, "cdda.raw", PATH_MAX - strlen(outfile_name) - 1); break; case 1: - strncat(outfile_name, "cdda.wav", sizeof("cdda.wav")); + strncat(outfile_name, "cdda.wav", PATH_MAX - strlen(outfile_name) - 1); break; case 2: - strncat(outfile_name, "cdda.aifc", sizeof("cdda.aifc")); + strncat(outfile_name, "cdda.aifc", PATH_MAX - strlen(outfile_name) - 1); break; case 3: - strncat(outfile_name, "cdda.aiff", sizeof("cdda.aiff")); + strncat(outfile_name, "cdda.aiff", PATH_MAX - strlen(outfile_name) - 1); break; } diff --git a/test/cdda_interface/toc.c.in b/test/cdda_interface/toc.c.in index 41a9671..59f650c 100644 --- a/test/cdda_interface/toc.c.in +++ b/test/cdda_interface/toc.c.in @@ -37,6 +37,9 @@ #ifdef HAVE_STDLIB_H #include #endif +#ifdef HAVE_STRING_H +#include +#endif #include #include @@ -58,7 +61,8 @@ log_handler (cdio_log_level_t level, const char message[]) } } -static int testit(cdrom_drive_t *d) { +static int +cdda(cdrom_drive_t *d) { track_t t = 0; lsn_t lsn = 0; @@ -92,24 +96,58 @@ static int testit(cdrom_drive_t *d) { return 3; } - lsn = cdda_track_lastsector(d, 0); - if ( lsn != -402 ) { - printf("Should have gotten error code -402, got %d.\n", lsn); - return 3; - } - /* Check track sector reporting. */ lsn = cdda_track_firstsector(d, 1); if ( lsn != 0 ) { printf("Should have gotten 0 as the first sector, got %d.\n", lsn); - return 2; + return 4; } lsn = cdda_track_lastsector(d, 1); if ( lsn != 301 ) { printf("Should have gotten 301 as the last sector, got %d.\n", lsn); - return 2; + return 4; + } + + /* Check CDIO_CDROM_LEADOUT_TRACK/tracks+1. + */ + lsn = cdda_track_firstsector(d, CDIO_CDROM_LEADOUT_TRACK); + if ( lsn != 302 ) { + printf("First: Should have gotten 302 as first sector on leadout, got %d.\n", lsn); + return 5; + } + + lsn = cdda_track_firstsector(d, 2); + if ( lsn != 302 ) { + printf("First: Should have gotten 302 as first sector on leadout, got %d.\n", lsn); + return 5; + } + + lsn = cdda_track_lastsector(d, CDIO_CDROM_LEADOUT_TRACK); + if ( lsn != -401 ) { + printf("Last: Should have gotten error code -401, got %d.\n", lsn); + return 5; + } + + lsn = cdda_track_lastsector(d, 2); + if ( lsn != -401 ) { + printf("Last: Should have gotten error code -401, got %d.\n", lsn); + return 5; + } + + /* Check track ranges. + */ + lsn = cdda_track_firstsector(d, 3); + if ( lsn != -401 ) { + printf("Should have gotten error code -401, got %d.\n", lsn); + return 6; + } + + lsn = cdda_track_lastsector(d, -1); + if ( lsn != -401 ) { + printf("Should have gotten error code -401, got %d.\n", lsn); + return 6; } /* Check sector track reporting. @@ -117,51 +155,226 @@ static int testit(cdrom_drive_t *d) { t = cdda_sector_gettrack(d, 100); if ( 1 != t ) { printf("Should have gotten 1 as the track, got %d.\n", t); - return 2; + return 7; } t = cdda_sector_gettrack(d, 1000); if ( CDIO_INVALID_TRACK != t ) { printf("Should have gotten CDIO_INVALID_TRACK as the track, got %d.\n", t); + return 7; + } + + return 0; +} + +static int +cd_extra(cdrom_drive_t *d) { + track_t t = 0; + lsn_t lsn = 0; + + /* Check number of tracks (data track also counted). + */ + t = cdda_tracks(d); + if (t != 2) { + printf("Should have found two tracks, got %d\n", t); + return 1; + } + + /* Check disc sector reporting. + */ + lsn = cdda_disc_lastsector(d); + if ( lsn != 149 ) { + printf("Should have gotten 149 as the last sector, got %d.\n", lsn); + return 2; + } + + /* Check track sector reporting. + */ + lsn = cdda_track_lastsector(d, 1); + if ( lsn != 149 ) { + printf("Should have gotten 149 as the last sector, got %d.\n", lsn); + return 4; + } + + /* Check CDIO_CDROM_LEADOUT_TRACK/tracks+1. + */ + lsn = cdda_track_firstsector(d, 3); + if ( lsn != 302 ) { + printf("First: Should have gotten 302 as first sector on leadout, got %d.\n", lsn); + return 5; + } + + lsn = cdda_track_lastsector(d, 3); + if ( lsn != -401 ) { + printf("Last: Should have gotten error code -401, got %d.\n", lsn); + return 5; + } + + /* Check track ranges. + */ + lsn = cdda_track_firstsector(d, 4); + if ( lsn != -401 ) { + printf("Should have gotten error code -401, got %d.\n", lsn); + return 6; + } + + /* Check non audio tracks. + */ + lsn = cdda_track_firstsector(d, 2); + if ( lsn != 150 ) { + printf("Should have gotten 150 as first sector, got %d.\n", lsn); + return 8; + } + + lsn = cdda_track_lastsector(d, 2); + if ( lsn != 301 ) { + printf("Should have gotten 301 as last sector, got %d.\n", lsn); + return 8; + } + + return 0; +} + +static int +hidden_track(cdrom_drive_t *d) { + track_t t = 0; + lsn_t lsn = 0; + + /* Check number of tracks (hidden track ignored). + */ + t = cdda_tracks(d); + if (t != 1) { + printf("Should have found one track, got %d\n", t); + return 1; + } + + /* Check pregap sector reporting. + */ + lsn = cdda_track_firstsector(d, 0); + if ( lsn != 0 ) { + printf("Should have gotten 0 as the first sector on hidden track, got %d.\n", lsn); + return 2; + } + + /* Check track sector reporting. + */ + lsn = cdda_track_firstsector(d, 1); + if ( lsn != 150 ) { + printf("Should have gotten 150 as the first sector, got %d.\n", lsn); + return 3; + } + + lsn = cdda_track_lastsector(d, 1); + if ( lsn != 301 ) { + printf("Should have gotten 301 as the last sector, got %d.\n", lsn); return 3; } return 0; } -int -main(int argc, const char *argv[]) -{ +static int +mixed_mode_cd(cdrom_drive_t *d) { + track_t t = 0; + lsn_t lsn = 0; + + /* Check number of tracks (data track also counted). + */ + t = cdda_tracks(d); + if (t != 2) { + printf("Should have found two tracks, got %d\n", t); + return 1; + } + + /* Check disc sector reporting. + */ + lsn = cdda_disc_firstsector(d); + if ( lsn != 150 ) { + printf("Should have gotten 150 as the first sector, got %d.\n", lsn); + return 1; + } + + lsn = cdda_disc_lastsector(d); + if ( lsn != 301 ) { + printf("Should have gotten 301 as the last sector, got %d.\n", lsn); + return 1; + } + + /* Check non audio tracks. + */ + lsn = cdda_track_firstsector(d, 1); + if ( lsn != 0 ) { + printf("Should have gotten 0 as the first sector, got %d.\n", lsn); + return 8; + } + + lsn = cdda_track_lastsector(d, 1); + if ( lsn != 149 ) { + printf("Should have gotten 149 as the last sector, got %d.\n", lsn); + return 8; + } + + return 0; +} + +static int +perform_test(const char *dir, const char *file, int (*func)(cdrom_drive_t *)){ cdrom_drive_t *d = NULL; /* Place to store handle given by cd-paranoia. */ CdIo_t *p_cdio; int rc; - cdio_log_set_handler (log_handler); + char *drv = (char*) malloc(strlen(dir) + strlen(file) + 4); + strcpy(drv, dir); + strcat(drv, file); if (cdio_have_driver(DRIVER_BINCUE)) { - p_cdio = cdio_open("@native_abs_top_srcdir@/test/data/cdda.cue", DRIVER_UNKNOWN); + p_cdio = cdio_open(strcat(drv, ".cue"), DRIVER_UNKNOWN); } else if (cdio_have_driver(DRIVER_CDRDAO)) { - p_cdio = cdio_open("@native_abs_top_srcdir@/test/data/cdda.toc", DRIVER_UNKNOWN); + p_cdio = cdio_open(strcat(drv, ".toc"), DRIVER_UNKNOWN); } else { - printf("-- You don't have enough drivers for this test\n"); + printf("-- You don't have enough drivers for the test (%s).\n", file); + free(drv); return 77; } d=cdio_cddap_identify_cdio(p_cdio, CDDA_MESSAGE_PRINTIT, NULL); if ( !d ) { - printf("Should have identified as an audio CD disc.\n"); + printf("Should have identified as an audio CD disc (%s).\n", file); + free(drv); return 1; } if ( 0 != cdio_cddap_open(d) ) { - printf("Unable to open disc.\n"); + printf("Unable to open disc (%s).\n", file); + free(drv); return 2; } - rc = testit(d); + rc = func(d); cdio_cddap_close_no_free_cdio(d); cdio_destroy(p_cdio); + free(drv); return rc; } + +int +main(int argc, const char *argv[]) +{ + int i=0; + int rc; + const char *files[] = { "cdda", "cd-extra", "hidden-track", "mixed-mode-cd", NULL }; + int (*funcs[])(cdrom_drive_t *) = { cdda, cd_extra, hidden_track, mixed_mode_cd }; + + cdio_log_set_handler (log_handler); + + while(files[i] != NULL){ + rc = perform_test("@native_abs_top_srcdir@/test/data/", files[i], funcs[i]); + if(rc) + return rc; + i++; + } + + return 0; +} diff --git a/test/check_paranoia.sh.in b/test/check_paranoia.sh.in index 76d15c5..9b0d5de 100644 --- a/test/check_paranoia.sh.in +++ b/test/check_paranoia.sh.in @@ -11,6 +11,9 @@ fi cue_file=$abs_top_srcdir/test/data/cdda.cue cue_file2=$abs_top_srcdir/test/data/cdda2.cue +cue_cd_extra=$abs_top_srcdir/test/data/cd-extra.cue +cue_hidden_track=$abs_top_srcdir/test/data/hidden-track.cue +cue_mixed_mode_cd=$abs_top_srcdir/test/data/mixed-mode-cd.cue if test "@CMP@" != no ; then cd_paranoia=$abs_top_builddir/src/cd-paranoia@EXEEXT@ @@ -90,6 +93,79 @@ if test "@CMP@" != no ; then fi ### FIXME: medium jitter is known to fail. Investigate. ### FIXME: large jitter is known to fail. Investigate. + + # CD extra + + # Audio track shoud pass + $cd_paranoia -d $cue_cd_extra -v -r -- "1" + if test $? -ne 0 ; then + exit 7 + fi + + # Track 0 should fail since no pregap + $cd_paranoia -d $cue_cd_extra -v -r -- "0" + if test $? -eq 0 ; then + exit 8 + fi + + # Data track should fail + $cd_paranoia -d $cue_cd_extra -v -r -- "2" + if test $? -eq 0 ; then + exit 9 + fi + + # Track out of range should fail + $cd_paranoia -d $cue_cd_extra -v -r -- "3" + if test $? -eq 0 ; then + exit 10 + fi + + # Span shoud fail due to data track + $cd_paranoia -d $cue_cd_extra -v -r -- "1-2" + if test $? -eq 0 ; then + exit 11 + fi + + # Span shoud fail due to range + $cd_paranoia -d $cue_cd_extra -v -r -- "1-3" + if test $? -eq 0 ; then + exit 11 + fi + + # CD with hidden track + + # Audio track shoud pass + $cd_paranoia -d $cue_hidden_track -v -r -- "1" + if test $? -ne 0 ; then + exit 7 + fi + + # Track 0 should pass + $cd_paranoia -d $cue_hidden_track -v -r -- "0" + if test $? -ne 0 ; then + exit 8 + fi + + # Span shoud pass + $cd_paranoia -d $cue_hidden_track -v -r -- "0-1" + if test $? -ne 0 ; then + exit 11 + fi + + # Mixed mode CD + + # Audio track shoud pass + $cd_paranoia -d $cue_mixed_mode_cd -v -r -- "2" + if test $? -ne 0 ; then + exit 7 + fi + + # Data track should fail + $cd_paranoia -d $cue_mixed_mode_cd -v -r -- "1" + if test $? -eq 0 ; then + exit 9 + fi + exit 0 else if test "@CMP@" != no ; then diff --git a/test/data/cd-extra.bin b/test/data/cd-extra.bin new file mode 100644 index 0000000..b1ba1f5 Binary files /dev/null and b/test/data/cd-extra.bin differ diff --git a/test/data/cd-extra.cue b/test/data/cd-extra.cue new file mode 100644 index 0000000..913666d --- /dev/null +++ b/test/data/cd-extra.cue @@ -0,0 +1,10 @@ +TITLE "Join us now we have the software" +CATALOG 0000010271955 +PERFORMER "Richard Stallman" +FILE "cd-extra.bin" BINARY + TRACK 01 AUDIO + FLAGS DCP + INDEX 01 00:00:00 + TRACK 02 MODE1/2352 + FLAGS DCP + INDEX 01 00:02:00 diff --git a/test/data/hidden-track.bin b/test/data/hidden-track.bin new file mode 100644 index 0000000..b1ba1f5 Binary files /dev/null and b/test/data/hidden-track.bin differ diff --git a/test/data/hidden-track.cue b/test/data/hidden-track.cue new file mode 100644 index 0000000..0a1c489 --- /dev/null +++ b/test/data/hidden-track.cue @@ -0,0 +1,8 @@ +TITLE "Join us now we have the software" +CATALOG 0000010271955 +PERFORMER "Richard Stallman" +FILE "hidden-track.bin" BINARY + TRACK 01 AUDIO + FLAGS DCP + INDEX 00 00:00:00 + INDEX 01 00:02:00 diff --git a/test/data/mixed-mode-cd.bin b/test/data/mixed-mode-cd.bin new file mode 100644 index 0000000..b1ba1f5 Binary files /dev/null and b/test/data/mixed-mode-cd.bin differ diff --git a/test/data/mixed-mode-cd.cue b/test/data/mixed-mode-cd.cue new file mode 100644 index 0000000..89ffeb1 --- /dev/null +++ b/test/data/mixed-mode-cd.cue @@ -0,0 +1,10 @@ +TITLE "Join us now we have the software" +CATALOG 0000010271955 +PERFORMER "Richard Stallman" +FILE "mixed-mode-cd.bin" BINARY + TRACK 01 MODE1/2352 + FLAGS DCP + INDEX 01 00:00:00 + TRACK 02 AUDIO + FLAGS DCP + INDEX 01 00:02:00