Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
Vorbis
Vorbis
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 21
    • Issues 21
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
  • Merge Requests 0
    • Merge Requests 0
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Operations
    • Operations
    • Incidents
    • Environments
  • Packages & Registries
    • Packages & Registries
    • Container Registry
  • Analytics
    • Analytics
    • CI/CD
    • Repository
    • Value Stream
  • Wiki
    • Wiki
  • Members
    • Members
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Xiph.Org
  • VorbisVorbis
  • Issues
  • #232

Closed
Open
Created Aug 26, 2002 by xaviergonz@xaviergonz

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
Assignee
Assign to
None
Milestone
None
Assign milestone
Time tracking
None
Due date
None