[libvorbis] 01/01: Fix segmentation fault on two subsequent seeks to 0.

Martin Steghöfer martin.steghoefer-guest at moszumanska.debian.org
Sun Sep 20 23:18:45 UTC 2015


This is an automated email from the git hooks/post-receive script.

martin.steghoefer-guest pushed a commit to branch master
in repository libvorbis.

commit 50dc26a637e2438e15614cdb71390f5051f82986
Author: Martin Steghöfer <martin at steghoefer.eu>
Date:   Mon Sep 21 00:19:07 2015 +0200

    Fix segmentation fault on two subsequent seeks to 0.
    
    Closes: #782831
---
 ...ation-fault-on-two-subsequent-seeks-to-0-.patch |  27 +++
 ...ation-fault-on-two-subsequent-seeks-to-0-.patch | 202 +++++++++++++++++++++
 ...ation-fault-on-two-subsequent-seeks-to-0-.patch |  59 ++++++
 debian/patches/series                              |   3 +
 4 files changed, 291 insertions(+)

diff --git a/debian/patches/0007-Fix-segmentation-fault-on-two-subsequent-seeks-to-0-.patch b/debian/patches/0007-Fix-segmentation-fault-on-two-subsequent-seeks-to-0-.patch
new file mode 100644
index 0000000..5a496e9
--- /dev/null
+++ b/debian/patches/0007-Fix-segmentation-fault-on-two-subsequent-seeks-to-0-.patch
@@ -0,0 +1,27 @@
+From: Martin Steghoefer <martin at steghoefer.eu>
+Date: Sun, 20 Sep 2015 21:18:29 +0200
+Subject: Fix segmentation fault on two subsequent seeks to 0 (upstream r19164)
+
+Fixes a segmentation fault that occurs on two subsequent seeks to 0. This is one
+of three fixes that correct errors in the handling of the beginning-of-stream
+special case, introduced in the backport of r19159.
+
+Origin: backport, https://trac.xiph.org/changeset/19164
+Bug-Debian: http://bugs.debian.org/782831
+Last-Update: 2015-09-20
+---
+ lib/vorbisfile.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/lib/vorbisfile.c b/lib/vorbisfile.c
+index 1dcda9f..9594be9 100644
+--- a/lib/vorbisfile.c
++++ b/lib/vorbisfile.c
+@@ -1559,7 +1559,6 @@ int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
+            our page, right at the beginning of PCM data.  Set state
+            and return. */
+ 
+-        vf->offset=result;
+         vf->pcm_offset=total;
+ 
+         if(link!=vf->current_link){
diff --git a/debian/patches/0008-Fix-segmentation-fault-on-two-subsequent-seeks-to-0-.patch b/debian/patches/0008-Fix-segmentation-fault-on-two-subsequent-seeks-to-0-.patch
new file mode 100644
index 0000000..d89d6b6
--- /dev/null
+++ b/debian/patches/0008-Fix-segmentation-fault-on-two-subsequent-seeks-to-0-.patch
@@ -0,0 +1,202 @@
+From: Martin Steghoefer <martin at steghoefer.eu>
+Date: Sun, 20 Sep 2015 21:26:04 +0200
+Subject: Fix segmentation fault on two subsequent seeks to 0 (upstream r19165)
+
+Fixes a segmentation fault that occurs on two subsequent seeks to 0. This is one
+of three fixes that correct errors in the handling of the beginning-of-stream
+special case, introduced in the backport of r19159.
+
+Origin: backport, https://trac.xiph.org/changeset/19165
+Bug-Debian: http://bugs.debian.org/782831
+Last-Update: 2015-09-20
+---
+ lib/vorbisfile.c | 82 +++++++++++++++++++++++++-------------------------------
+ 1 file changed, 36 insertions(+), 46 deletions(-)
+
+diff --git a/lib/vorbisfile.c b/lib/vorbisfile.c
+index 9594be9..d018e09 100644
+--- a/lib/vorbisfile.c
++++ b/lib/vorbisfile.c
+@@ -80,11 +80,14 @@ static long _get_data(OggVorbis_File *vf){
+ /* save a tiny smidge of verbosity to make the code more readable */
+ static int _seek_helper(OggVorbis_File *vf,ogg_int64_t offset){
+   if(vf->datasource){
+-    if(!(vf->callbacks.seek_func)||
+-       (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET) == -1)
+-      return OV_EREAD;
+-    vf->offset=offset;
+-    ogg_sync_reset(&vf->oy);
++    /* only seek if the file position isn't already there */
++    if(vf->offset != offset){
++      if(!(vf->callbacks.seek_func)||
++         (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET) == -1)
++        return OV_EREAD;
++      vf->offset=offset;
++      ogg_sync_reset(&vf->oy);
++    }
+   }else{
+     /* shouldn't happen unless someone writes a broken callback */
+     return OV_EFAULT;
+@@ -138,14 +141,12 @@ static ogg_int64_t _get_next_page(OggVorbis_File *vf,ogg_page *og,
+   }
+ }
+ 
+-/* find the latest page beginning before the current stream cursor
+-   position. Much dirtier than the above as Ogg doesn't have any
+-   backward search linkage.  no 'readp' as it will certainly have to
+-   read. */
++/* find the latest page beginning before the passed in position. Much
++   dirtier than the above as Ogg doesn't have any backward search
++   linkage.  no 'readp' as it will certainly have to read. */
+ /* returns offset or OV_EREAD, OV_FAULT */
+-static ogg_int64_t _get_prev_page(OggVorbis_File *vf,ogg_page *og){
+-  ogg_int64_t begin=vf->offset;
+-  ogg_int64_t end=begin;
++static ogg_int64_t _get_prev_page(OggVorbis_File *vf,ogg_int64_t begin,ogg_page *og){
++  ogg_int64_t end = begin;
+   ogg_int64_t ret;
+   ogg_int64_t offset=-1;
+ 
+@@ -220,11 +221,10 @@ static int _lookup_page_serialno(ogg_page *og, long *serialno_list, int n){
+    info of last page of the matching serial number instead of the very
+    last page.  If no page of the specified serialno is seen, it will
+    return the info of last page and alter *serialno.  */
+-static ogg_int64_t _get_prev_page_serial(OggVorbis_File *vf,
++static ogg_int64_t _get_prev_page_serial(OggVorbis_File *vf, ogg_int64_t begin,
+                                          long *serial_list, int serial_n,
+                                          int *serialno, ogg_int64_t *granpos){
+   ogg_page og;
+-  ogg_int64_t begin=vf->offset;
+   ogg_int64_t end=begin;
+   ogg_int64_t ret;
+ 
+@@ -496,10 +496,10 @@ static int _bisect_forward_serialno(OggVorbis_File *vf,
+        down to (or just started with) a single link.  Now we need to
+        find the last vorbis page belonging to the first vorbis stream
+        for this link. */
+-
++    searched = end;
+     while(endserial != serialno){
+       endserial = serialno;
+-      vf->offset=_get_prev_page_serial(vf,currentno_list,currentnos,&endserial,&endgran);
++      searched=_get_prev_page_serial(vf,searched,currentno_list,currentnos,&endserial,&endgran);
+     }
+ 
+     vf->links=m+1;
+@@ -520,10 +520,15 @@ static int _bisect_forward_serialno(OggVorbis_File *vf,
+ 
+   }else{
+ 
++    /* last page is not in the starting stream's serial number list,
++       so we have multiple links.  Find where the stream that begins
++       our bisection ends. */
++
+     long *next_serialno_list=NULL;
+     int next_serialnos=0;
+     vorbis_info vi;
+     vorbis_comment vc;
++    int testserial = serialno+1;
+ 
+     /* the below guards against garbage seperating the last and
+        first pages of two links. */
+@@ -536,10 +541,8 @@ static int _bisect_forward_serialno(OggVorbis_File *vf,
+         bisect=(searched+endsearched)/2;
+       }
+ 
+-      if(bisect != vf->offset){
+-        ret=_seek_helper(vf,bisect);
+-        if(ret)return(ret);
+-      }
++      ret=_seek_helper(vf,bisect);
++      if(ret)return(ret);
+ 
+       last=_get_next_page(vf,&og,-1);
+       if(last==OV_EREAD)return(OV_EREAD);
+@@ -552,28 +555,22 @@ static int _bisect_forward_serialno(OggVorbis_File *vf,
+     }
+ 
+     /* Bisection point found */
+-
+     /* for the time being, fetch end PCM offset the simple way */
+-    {
+-      int testserial = serialno+1;
+-      vf->offset = next;
+-      while(testserial != serialno){
+-        testserial = serialno;
+-        vf->offset=_get_prev_page_serial(vf,currentno_list,currentnos,&testserial,&searchgran);
+-      }
++    searched = next;
++    while(testserial != serialno){
++      testserial = serialno;
++      searched = _get_prev_page_serial(vf,searched,currentno_list,currentnos,&testserial,&searchgran);
+     }
+ 
+-    if(vf->offset!=next){
+-      ret=_seek_helper(vf,next);
+-      if(ret)return(ret);
+-    }
++    ret=_seek_helper(vf,next);
++    if(ret)return(ret);
+ 
+     ret=_fetch_headers(vf,&vi,&vc,&next_serialno_list,&next_serialnos,NULL);
+     if(ret)return(ret);
+     serialno = vf->os.serialno;
+     dataoffset = vf->offset;
+ 
+-    /* this will consume a page, however the next bistection always
++    /* this will consume a page, however the next bisection always
+        starts with a raw seek */
+     pcmoffset = _initial_pcmoffset(vf,&vi);
+ 
+@@ -640,11 +637,11 @@ static int _open_seekable2(OggVorbis_File *vf){
+   /* Get the offset of the last page of the physical bitstream, or, if
+      we're lucky the last vorbis page of this link as most OggVorbis
+      files will contain a single logical bitstream */
+-  end=_get_prev_page_serial(vf,vf->serialnos+2,vf->serialnos[1],&endserial,&endgran);
++  end=_get_prev_page_serial(vf,vf->end,vf->serialnos+2,vf->serialnos[1],&endserial,&endgran);
+   if(end<0)return(end);
+ 
+   /* now determine bitstream structure recursively */
+-  if(_bisect_forward_serialno(vf,0,dataoffset,vf->offset,endgran,endserial,
++  if(_bisect_forward_serialno(vf,0,dataoffset,end,endgran,endserial,
+                               vf->serialnos+2,vf->serialnos[1],0)<0)return(OV_EREAD);
+ 
+   vf->offsets[0]=0;
+@@ -1459,11 +1456,8 @@ int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
+           bisect=begin;
+       }
+ 
+-      /* only seek if the file position isn't already there */
+-      if(bisect!=vf->offset){
+-        result=_seek_helper(vf,bisect);
+-        if(result) goto seek_error;
+-      }
++      result=_seek_helper(vf,bisect);
++      if(result) goto seek_error;
+ 
+       /* read loop within the bisection loop */
+       while(begin<end){
+@@ -1619,21 +1613,17 @@ int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
+              page. Keep fetching previous pages until we get one with
+              a granulepos or without the 'continued' flag set.  Then
+              just use raw_seek for simplicity. */
+-
+-          result=_seek_helper(vf,best);
+-          if(result<0) goto seek_error;
+-
+           /* Do not rewind past the beginning of link data; if we do,
+              it's either a bug or a broken stream */
++          result=best;
+           while(result>vf->dataoffsets[link]){
+-            result=_get_prev_page(vf,&og);
++            result=_get_prev_page(vf,result,&og);
+             if(result<0) goto seek_error;
+             if(ogg_page_serialno(&og)==vf->current_serialno &&
+                (ogg_page_granulepos(&og)>-1 ||
+                 !ogg_page_continued(&og))){
+               return ov_raw_seek(vf,result);
+             }
+-            vf->offset=result;
+           }
+         }
+         if(result<0){
diff --git a/debian/patches/0009-Fix-segmentation-fault-on-two-subsequent-seeks-to-0-.patch b/debian/patches/0009-Fix-segmentation-fault-on-two-subsequent-seeks-to-0-.patch
new file mode 100644
index 0000000..f018f61
--- /dev/null
+++ b/debian/patches/0009-Fix-segmentation-fault-on-two-subsequent-seeks-to-0-.patch
@@ -0,0 +1,59 @@
+From: Martin Steghoefer <martin at steghoefer.eu>
+Date: Sun, 20 Sep 2015 21:49:12 +0200
+Subject: Fix segmentation fault on two subsequent seeks to 0 (upstream r19171)
+
+Fixes a segmentation fault that occurs on two subsequent seeks to 0. This is one
+of three fixes that correct errors in the handling of the beginning-of-stream
+special case, introduced in the backport of r19159.
+
+Origin: backport, https://trac.xiph.org/changeset/19171
+Bug-Debian: http://bugs.debian.org/782831
+Last-Update: 2015-09-20
+---
+ lib/vorbisfile.c | 17 ++++++++++++++++-
+ 1 file changed, 16 insertions(+), 1 deletion(-)
+
+diff --git a/lib/vorbisfile.c b/lib/vorbisfile.c
+index d018e09..7644fd6 100644
+--- a/lib/vorbisfile.c
++++ b/lib/vorbisfile.c
+@@ -1439,8 +1439,21 @@ int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
+     ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime;
+     ogg_int64_t target=pos-total+begintime;
+     ogg_int64_t best=-1;
++    int         got_page=0;
+ 
+     ogg_page og;
++
++    /* if we have only one page, there will be no bisection.  Grab the page here */
++    if(begin==end){
++      result=_seek_helper(vf,begin);
++      if(result) goto seek_error;
++
++      result=_get_next_page(vf,&og,1);
++      if(result<0) goto seek_error;
++
++      got_page=1;
++    }
++
+     /* bisection loop */
+     while(begin<end){
+       ogg_int64_t bisect;
+@@ -1484,6 +1497,7 @@ int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
+           }
+         }else{
+           ogg_int64_t granulepos;
++          got_page=1;
+ 
+           /* got a page. analyze it */
+           /* only consider pages from primary vorbis stream */
+@@ -1546,7 +1560,8 @@ int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
+          bisection would 'fail' because our search target was before the
+          first PCM granule position fencepost. */
+ 
+-      if(begin == vf->dataoffsets[link] &&
++      if(got_page &&
++         begin == vf->dataoffsets[link] &&
+          ogg_page_serialno(&og)==vf->serialnos[link]){
+ 
+         /* Yes, this is the beginning-of-stream case. We already have
diff --git a/debian/patches/series b/debian/patches/series
index 3e65504..7d2f7b9 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -4,3 +4,6 @@
 0004-Add-sampling-rate-sanity-check-to-avoid-invalid-memo.patch
 0005-Fix-crash-on-corrupt-input-file-invalid-mode-index.patch
 0006-Take-into-account-error-codes-returned-from-vorbis_p.patch
+0007-Fix-segmentation-fault-on-two-subsequent-seeks-to-0-.patch
+0008-Fix-segmentation-fault-on-two-subsequent-seeks-to-0-.patch
+0009-Fix-segmentation-fault-on-two-subsequent-seeks-to-0-.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-xiph/libvorbis.git



More information about the pkg-xiph-commits mailing list