diff --git a/lib/cdda_interface/interface.c b/lib/cdda_interface/interface.c index 8fa5fb83..5b150315 100644 --- a/lib/cdda_interface/interface.c +++ b/lib/cdda_interface/interface.c @@ -1,5 +1,5 @@ /* - $Id: interface.c,v 1.14 2005/01/18 16:05:29 rocky Exp $ + $Id: interface.c,v 1.15 2005/01/23 14:05:19 rocky Exp $ Copyright (C) 2005 Rocky Bernstein Copyright (C) 1998 Monty xiphmont@mit.edu @@ -118,20 +118,27 @@ cdda_speed_set(cdrom_drive_t *d, int speed) long cdda_read(cdrom_drive_t *d, void *buffer, lsn_t beginsector, long sectors) { - if(d->opened){ - if(sectors>0){ - sectors=d->read_audio(d,buffer,beginsector,sectors); + if (d->opened) { + if (sectors>0) { + sectors=d->read_audio(d, buffer, beginsector, sectors); - if(sectors > 0){ + if (sectors > 0){ /* byteswap? */ if(d->bigendianp==-1) /* not determined yet */ - d->bigendianp=data_bigendianp(d); - + d->bigendianp = data_bigendianp(d); + if(d->bigendianp!=bigendianp()){ int i; uint16_t *p=(uint16_t *)buffer; long els=sectors*CDIO_CD_FRAMESIZE_RAW/2; + /* Note: Something perhaps in the original cdparanioa code might + cause the code to access outside of the allocated range of + buffer. This comment is just to serve as a marker for + the loop where the data got clobbered. I don't think this + code however is wrong. See the comment in i_read_c_block + of paranioa.c + */ for(i=0;i Copyright (C) 1998 Monty xiphmont@mit.edu @@ -1202,7 +1202,7 @@ i_read_c_block(cdrom_paranoia_t *p,long beginword,long endword, readat+=driftcomp; if (p->enable&(PARANOIA_MODE_OVERLAP|PARANOIA_MODE_VERIFY)) { - flags=calloc(totaltoread*CD_FRAMEWORDS,1); + flags=calloc(totaltoread*CD_FRAMEWORDS, 1); new=new_c_block(p); recover_cache(p); } else { @@ -1211,7 +1211,19 @@ i_read_c_block(cdrom_paranoia_t *p,long beginword,long endword, new=new_c_block(p); } - buffer=calloc(1, totaltoread*CDIO_CD_FRAMESIZE_RAW); + /* FIXME: We allocate one extra frame more than what we should be + using. In cdda_read() when the CD-ROM endian-ness is different + from the machine endian-ness and we need to swap bytes, we seem + to be accessing outside of buffer in some (but not all) + cases. This is probably due to this routine calling cdda_read + with parameter that would have it access outside the allocated + range. Since I don't know how to fix, we'll do the harmless over + allocation. + + On a sparc (Big Endian) Solaris with a little-endian CD-ROM. The + symptom would be that the calloc *after* the one below would fail. + */ + buffer=calloc((totaltoread+1)*CDIO_CD_FRAMESIZE_RAW, 1); sofar=0; firstread=-1; @@ -1234,16 +1246,20 @@ i_read_c_block(cdrom_paranoia_t *p,long beginword,long endword, if (secread>0){ - if (firstread<0) firstread=adjread; - if ((thisread=cdda_read(p->d,buffer+sofar*CD_FRAMEWORDS,adjread, - secread))d, buffer+sofar*CD_FRAMEWORDS, adjread, secread); + + if ( thisread < secread) { if (thisread<0) thisread=0; /* Uhhh... right. Make something up. But don't make us seek backward! */ - if(callback)(*callback)((adjread+thisread)*CD_FRAMEWORDS,PARANOIA_CB_READERR); + if(callback) + (*callback)((adjread+thisread)*CD_FRAMEWORDS, PARANOIA_CB_READERR); memset(buffer+(sofar+thisread)*CD_FRAMEWORDS,0, CDIO_CD_FRAMESIZE_RAW*(secread-thisread)); if(flags)memset(flags+(sofar+thisread)*CD_FRAMEWORDS,2,