Commits

mitsuhiko  committed 2f79cc3

Improved formparser test coverage.

  • Participants
  • Parent commits 26f63d5

Comments (0)

Files changed (2)

File tests/test_formparser.py

 from cStringIO import StringIO
 
 from werkzeug import Client, Request, Response, parse_form_data, \
-     create_environ, FileStorage
+     create_environ, FileStorage, formparser, create_environ
 from werkzeug.exceptions import RequestEntityTooLarge
 
 
     assert not data.form
 
 
+def test_broken_multipart():
+    """Broken multipart does not break the applicaiton"""
+    data = (
+        '--foo\r\n'
+        'Content-Disposition: form-data; name="test"; filename="test.txt"\r\n'
+        'Content-Transfer-Encoding: base64\r\n'
+        'Content-Type: text/plain\r\n\r\n'
+        'broken base 64'
+        '--foo--'
+    )
+    _, form, files = parse_form_data(create_environ(data=data, method='POST',
+                                     content_type='multipart/form-data; boundary=foo'))
+    assert not files
+    assert not form
+
+    assert_raises(ValueError, parse_form_data, create_environ(data=data, method='POST',
+                  content_type='multipart/form-data; boundary=foo'),
+                  silent=False)
+
+
 def test_multipart_file_no_content_type():
     """Chrome does not always provide a content type."""
     data = (
     # make sure we have a real file here, because we expect to be
     # on the disk.  > 1024 * 500
     assert isinstance(req.files['foo'].stream, file)
+
+
+def test_lowlevel():
+    """Lowlevel formparser tests"""
+    formparser._line_parse('foo') == ('foo', False)
+    formparser._line_parse('foo\r\n') == ('foo', True)
+    formparser._line_parse('foo\r') == ('foo', True)
+    formparser._line_parse('foo\n') == ('foo', True)
+
+    lineiter = iter('\n\n\nfoo\nbar\nbaz'.splitlines(True))
+    line = formparser._find_terminator(lineiter)
+    assert line == 'foo'
+    assert list(lineiter) == ['bar\n', 'baz']
+    assert formparser._find_terminator([]) == ''
+    assert formparser._find_terminator(['']) == ''
+
+    assert_raises(ValueError, formparser.parse_multipart, None, '', 20)
+    assert_raises(ValueError, formparser.parse_multipart, None, 'broken  ', 20)
+
+    data = '--foo\r\n\r\nHello World\r\n--foo--'
+    assert_raises(ValueError, formparser.parse_multipart, StringIO(data), 'foo', len(data))
+
+    data = '--foo\r\nContent-Disposition: form-field; name=foo\r\n' \
+           'Content-Transfer-Encoding: base64\r\n\r\nHello World\r\n--foo--'
+    assert_raises(ValueError, formparser.parse_multipart, StringIO(data), 'foo', len(data))
+
+    data = '--foo\r\nContent-Disposition: form-field; name=foo\r\n\r\nHello World\r\n'
+    assert_raises(ValueError, formparser.parse_multipart, StringIO(data), 'foo', len(data))
+
+    x = formparser.parse_multipart_headers(['foo: bar\r\n', ' x test\r\n'])
+    assert x['foo'] == 'bar\n x test'
+    assert_raises(ValueError, formparser.parse_multipart_headers, ['foo: bar\r\n', ' x test'])

File werkzeug/formparser.py

         raise ValueError('Missing boundary')
     if not is_valid_multipart_boundary(boundary):
         raise ValueError('Invalid boundary: %s' % boundary)
-    if len(boundary) > buffer_size:
+    if len(boundary) > buffer_size: # pragma: no cover
+        # this should never happen because we check for a minimum size
+        # of 1024 and boundaries may not be longer than 200.  The only
+        # situation when this happen is for non debug builds where
+        # the assert i skipped.
         raise ValueError('Boundary longer than buffer size')
 
     total_content_length = content_length
                     if in_memory > max_form_memory_size:
                         from werkzeug.exceptions import RequestEntityTooLarge
                         raise RequestEntityTooLarge()
-            else:
+            else: # pragma: no cover
                 raise ValueError('unexpected end of part')
 
             if is_file: