access violations and divides by 0 when usint ov_time_tell() with a not seekable stream
Hello, take a look at the ov_time_tell function in vorbisfile.c
double ov_time_tell(OggVorbis_File *vf){
/* translate time to PCM position and call ov_pcm_seek */
int link=-1;
ogg_int64_t pcm_total=0;
double time_total=0.f;
if(vf->ready_state<OPENED)return(OV_EINVAL);
if(vf->seekable){
pcm_total=ov_pcm_total(vf,-1);
time_total=ov_time_total(vf,-1);
/* which bitstream section does this time offset occur in? */
for(link=vf->links-1;link>=0;link--){
pcm_total-=vf->pcmlengths[link*2+1];
time_total-=ov_time_total(vf,link);
if(vf->pcm_offset>=pcm_total)break;
}
}
return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi
[link].rate);
}
As you may easily notice, when the vf is *not* seekable, link = -1, and
therefore in the return, it tries to access vf->vi[-1].rate (access violation),
with the side effect of being that 0, so it also performs a divide by 0
operation and since the result value is a double, it returns a NAN -INF. So it
is clearly a bug, therefore I propose the following change:
double ov_time_tell(OggVorbis_File *vf){
/* translate time to PCM position and call ov_pcm_seek */
int link=-1;
ogg_int64_t pcm_total=0;
double time_total=0.f;
if(vf->ready_state<OPENED)return(OV_EINVAL);
if(vf->seekable){
pcm_total=ov_pcm_total(vf,-1);
time_total=ov_time_total(vf,-1);
/* which bitstream section does this time offset occur in? */
for(link=vf->links-1;link>=0;link--){
pcm_total-=vf->pcmlengths[link*2+1];
time_total-=ov_time_total(vf,link);
if(vf->pcm_offset>=pcm_total)break;
}
return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi
[link].rate);
}
else
return((double)vf->pcm_offset/vf->vi->rate);
}
which basicaly moves the return in the old function inside so it is only called
if the vf is seekable and adds a new return for non seekable files which
returns the current sample / current section rate, which is, that is, the
current second. Probably it doesn't work properly if the current section is
using a different rate than an old (possible) one, but it is always nicer than
an access violation and a divide by 0 and also a more accurate result than NAN -
INF :)
Thanks