From 958dfe2451f12ce25975aafbe1fc98105b49f673 Mon Sep 17 00:00:00 2001
From: Scott Wheeler <wheeler@kde.org>
Date: Fri, 1 Feb 2008 00:49:01 +0000
Subject: [PATCH] A couple of small bugs (the more significant ones were
 already fixed) from Oskar Liljeblad

BUG:126010


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@769284 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
---
 taglib/mpeg/mpegfile.cpp | 48 ++++++++++++++++++++++++----------------
 1 file changed, 29 insertions(+), 19 deletions(-)

diff --git a/taglib/mpeg/mpegfile.cpp b/taglib/mpeg/mpegfile.cpp
index 18dc75c0..221ccd6a 100644
--- a/taglib/mpeg/mpegfile.cpp
+++ b/taglib/mpeg/mpegfile.cpp
@@ -313,45 +313,55 @@ void MPEG::File::setID3v2FrameFactory(const ID3v2::FrameFactory *factory)
 
 long MPEG::File::nextFrameOffset(long position)
 {
-  // TODO: This will miss syncs spanning buffer read boundaries.
+  bool foundLastSyncPattern = false;
 
-  ByteVector buffer = readBlock(bufferSize());
-
-  while(buffer.size() > 0) {
+  ByteVector buffer;
+ 
+  while(true) {
     seek(position);
     buffer = readBlock(bufferSize());
 
-    for(int i = 0; i < int(buffer.size()) - 1; i++) {
+    if(buffer.size() <= 0)
+      return -1;
+
+    if(foundLastSyncPattern && secondSynchByte(buffer[0]))
+      return position - 1;
+ 
+    for(uint i = 0; i < buffer.size() - 1; i++) {
       if(uchar(buffer[i]) == 0xff && secondSynchByte(buffer[i + 1]))
         return position + i;
     }
-    position += bufferSize();
-  }
 
-  return -1;
+    foundLastSyncPattern = uchar(buffer[buffer.size() - 1]) == 0xff;
+    position += buffer.size();
+  }
 }
 
 long MPEG::File::previousFrameOffset(long position)
 {
-  // TODO: This will miss syncs spanning buffer read boundaries.
+  bool foundFirstSyncPattern = false;
+  ByteVector buffer;
 
-  while(int(position - bufferSize()) > int(bufferSize())) {
-    position -= bufferSize();
+  while (position > 0) {
+    long size = ulong(position) < bufferSize() ? position : bufferSize();
+    position -= size;
+ 
     seek(position);
-    ByteVector buffer = readBlock(bufferSize());
-
-    // If the amount of data is smaller than an MPEG header (4 bytes) there's no
-    // chance of this being valid.
-
-    if(buffer.size() < 4)
-      return -1;
+    buffer = readBlock(size);
 
+    if(buffer.size() <= 0)
+      break;
+ 
+    if(foundFirstSyncPattern && uchar(buffer[buffer.size() - 1]) == 0xff)
+      return position + buffer.size() - 1;
+ 
     for(int i = buffer.size() - 2; i >= 0; i--) {
       if(uchar(buffer[i]) == 0xff && secondSynchByte(buffer[i + 1]))
         return position + i;
     }
-  }
 
+    foundFirstSyncPattern = secondSynchByte(buffer[0]);
+  }
   return -1;
 }