[xiph-cvs] cvs commit: positron/positron MP3Info.py

Stan Seibert volsung at xiph.org
Wed Jul 2 19:14:08 PDT 2003



volsung     03/07/02 22:14:08

  Modified:    positron MP3Info.py
  Log:
  Tightening down the screws.  Fixed some bugs that made checking the next
  header too permissive.  Also require the random test to find three
  consecutive MPEG frames in a row.  Two was not enough to exclude some
  false positives (notably PNG files).

Revision  Changes    Path
1.11      +26 -13    positron/positron/MP3Info.py

Index: MP3Info.py
===================================================================
RCS file: /usr/local/cvsroot/positron/positron/MP3Info.py,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- MP3Info.py	2 Jul 2003 18:15:49 -0000	1.10
+++ MP3Info.py	3 Jul 2003 02:14:08 -0000	1.11
@@ -297,9 +297,6 @@
         self.emphasis = ""
         self.length = 0
 
-
-        # First do a check to see if this is really an MPEG file.
-        #
         # The longest possible frame for any MPEG audio file
         # is 4609 bytes for a MPEG 2, Layer 1 256 kbps, 8000Hz with
         # a padding slot.  Add an extra 4 bytes to ensure we get the
@@ -310,12 +307,15 @@
         # substring.
         #
         # We pick a location in the middle 50% of the file to
-        # do a header test.  If it passes, then we proceed with parsing
-        # (using much less restrictive searching)
+        # do a header test, and we require that we find three consecutive
+        # frame headers in a row, as calculated by their frame lengths.
+        # If it passes, then we proceed with parsing (using much less
+        # restrictive searching)
         test_pos = int(random.uniform(0.25,0.75) * self.filesize)
 
         offset, header = self._find_header(file, seeklimit=4616,
-                                           seekstart=test_pos)
+                                           seekstart=test_pos,
+                                           check_next_header=2)
         if offset == -1 or header is None:
             raise Error("Failed MPEG frame test.")
             
@@ -330,9 +330,9 @@
             raise Error("MPEG header not valid")
 
         self._parse_xing(file, seeklimit, seekstart)
-    
+
     def _find_header(self, file, seeklimit=_MP3_HEADER_SEEK_LIMIT,
-                     seekstart=0, check_next_header=True):
+                     seekstart=0, check_next_header=1):
         amt = 5120  # Multiple of 512 is hopefully more efficient to read from
                     # disk, and size ensure the random test will only
                     # read once
@@ -340,7 +340,8 @@
         read_more = False
 
         file.seek(seekstart, 0)
-        header = file.read(amt)
+        # Don't read more than we are allowed to see (size of header is 4)
+        header = file.read(min(amt,seeklimit+4))
         
         while curr_pos <= seeklimit:            
             # look for the sync byte
@@ -355,7 +356,7 @@
             elif ord(header[offset+1]) & 0xE0 == 0xE0:
 
                 # Finish now if we should not check the next header
-                if not check_next_header:
+                if check_next_header == 0:
                     return seekstart+offset, header[offset:offset+4]
 
                 # We have a possible winner, test parse this header and
@@ -365,12 +366,20 @@
                 self._parse_header(header[offset:offset+4])
                     
                 if self.valid:
+
+                    file_pos = file.tell()
+                    
                     next_off, next_header = \
                               self._find_header(file, seeklimit=0,
-                                                seekstart=seekstart+offset
-                                                        +self.framelength,
-                                                check_next_header=False)
+                                        seekstart=seekstart+offset
+                                                  +int(self.framelength),
+                                        check_next_header=check_next_header-1)
+
+                    # Move the file pointer back
+                    file.seek(file_pos,0)
+                    
                     if next_off != -1:
+#                        print file.name, seekstart, seeklimit, offset, self.framelength
                         return seekstart+offset, header[offset:offset+4]
                     else:
                         curr_pos = offset+2
@@ -449,6 +458,10 @@
             self.length = int(round((self.filesize / self.framelength) * (self.samplesperframe / self.samplerate)))
         except ZeroDivisionError:
             return  # Division by zero means the header is bad
+
+        # More sanity checks
+        if self.framelength < 0 or self.length < 0:
+            return
         
         self.valid = 1
 

<p><p>--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the commits mailing list