bpo-34088: sndhdr.what() doesn't fail on bad input. by davidawad · Pull Request #8319 · python/cpython (original) (raw)
What this is
This is a very small fix for sndhdr.py
so it can take bad input and not croak. This was originally reported by Jussi Judin on BPO here.
To reproduce this these crashes you can try the following examples:
$ echo UklGRjAwMDBXQVZFZm10IDAwMDABADAwMDAwMDAwMDAwMDAw | python3.7 -mbase64 -d > in.file
$ python3.7 sndhdr/test.py in.file
Traceback (most recent call last):
File "sndhdr/test.py", line 4, in <module>
sndhdr.what(sys.argv[1])
File "/tmp/python-3.7-bin/lib/python3.7/sndhdr.py", line 54, in what
res = whathdr(filename)
File "/tmp/python-3.7-bin/lib/python3.7/sndhdr.py", line 63, in whathdr
res = tf(h, f)
File "/tmp/python-3.7-bin/lib/python3.7/sndhdr.py", line 163, in test_wav
w = wave.open(f, 'r')
File "/tmp/python-3.7-bin/lib/python3.7/wave.py", line 510, in open
return Wave_read(f)
File "/tmp/python-3.7-bin/lib/python3.7/wave.py", line 164, in __init__
self.initfp(f)
File "/tmp/python-3.7-bin/lib/python3.7/wave.py", line 153, in initfp
chunk.skip()
File "/tmp/python-3.7-bin/lib/python3.7/chunk.py", line 160, in skip
self.file.seek(n, 1)
File "/tmp/python-3.7-bin/lib/python3.7/chunk.py", line 113, in seek
raise RuntimeError
RuntimeError
Another second crash comes from sndhdr module itself (again base64 encoded data is first decoded on command line):
$ echo AAA= | python3.7 -mbase64 -d > in.file
$ python3.7 sndhdr/test.py in.fileTraceback (most recent call last):
File "sndhdr/test.py", line 4, in <module>
sndhdr.what(sys.argv[1])
File "/tmp/python-3.7-bin/lib/python3.7/sndhdr.py", line 54, in what
res = whathdr(filename)
File "/tmp/python-3.7-bin/lib/python3.7/sndhdr.py", line 63, in whathdr
res = tf(h, f)
File "/tmp/python-3.7-bin/lib/python3.7/sndhdr.py", line 192, in test_sndr
rate = get_short_le(h[2:4])
File "/tmp/python-3.7-bin/lib/python3.7/sndhdr.py", line 213, in get_short_le
return (b[1] << 8) | b[0]
IndexError: index out of range
What this does
Right now this PR just handles some of the Exceptions caused by bad input and returns None
based on @vstinner 's comments in the BPO.
How did I test this?
I ran the unit tests and retried the test cases from the bpo post.
(cpython-venv) [ david@lithium ] ~/Projects/PYTHON/cpython
$>coverage run --pylib Lib/test/test_sndhdr.py
..
----------------------------------------------------------------------
Ran 2 tests in 0.005s
OK
(cpython-venv) [ david@lithium ] ~/Projects/PYTHON/cpython
$>
Quick questions
So I have two questions about how this should be handled. This is my first python patch so I don't know if there's a better way to do this.
- Should we only handle the specific exceptions that are created in these two examples? or is there a cleaner, more pythonic way to handle it?
- Should I add test cases for bad inputs to the test_sndhdr.py file?
Thanks!
edit - sorry about the branch name. typo on my part.