[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