AprilAndFriends / theoraplayer

A multi-threaded C++ library that plays video files supporting multiple codecs across platforms. Easy to use, fast, responsive, abstract interface and minimal dependencies, you'll soon be wondering how you lived without it! ;) Audio and Video interfaces are completely abstracted so the library can be used anywhere, regardless of what you use to display video frames and play audio samples (eg. OpenGL / OpenAL, Direct3D / DirectSound?, SDL / SDL_mixer, X11 / alsa ...) The library can pre-cache video frames and decoded audio samples for maximum efficiency and smooth playback, even on single-cpu systems. Currently, the library supports Theora on Windows, Mac, iOS, Linux, Android, WinRT and Windows Phone. H.264 is supported on Mac and iOS.
BSD 3-Clause "New" or "Revised" License
84 stars 43 forks source link

Access violation at TheoraVideoClip_Theora::load #4

Open d1ke opened 9 years ago

d1ke commented 9 years ago

Hello, I have access violation at ogg_page_serialno called from code below. It happens because case when ret == -1 not handled. Sometimes mInfo.OggPage stays unitialized after calling ogg_sync_buffer. And if mInfo.OggPage.header points to protected memory - we get crash.

void TheoraVideoClip_Theora::load(TheoraDataSource* source)
{
    ...
    char *buffer = ogg_sync_buffer(&mInfo.OggSyncState, 4096 * i);
    int bytes_read = mStream->read(buffer, 4096 * i);
    ogg_sync_wrote(&mInfo.OggSyncState, bytes_read);
    ogg_sync_pageseek(&mInfo.OggSyncState, &mInfo.OggPage);

    for (;;)
    {
        int ret = ogg_sync_pageout(&mInfo.OggSyncState, &mInfo.OggPage);
        if (ret == 0)
        {
            break;
        }
        // if page is not a theora page, skip it
        if (ogg_page_serialno(&mInfo.OggPage) != mInfo.TheoraStreamState.serialno) // <--- HERE!
        {
            continue;
        }
        ...
    }
    ...
}

I have 100% reproducibility using GFlags (gflags /p /enable C:\myapp.exe /full) and this video: http://s000.tinyupload.com/?file_id=66466629115262039545

Adding check ret == -1 fixes this bug for me.

if (ret == -1 || ogg_page_serialno(&mInfo.OggPage) != mInfo.TheoraStreamState.serialno) 
kspes commented 9 years ago

Good catch! Commited your fix, thanks :)