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.

Thanks!

edit - sorry about the branch name. typo on my part.

https://bugs.python.org/issue34088