mirror of
https://github.com/django/django.git
synced 2025-10-30 17:16:10 +00:00
Fixed #15785 -- Stopped HttpRequest.read() from reading beyond the end of a wsgi.input stream and removed some redundant code in the multipartparser. Thanks, tomchristie, grahamd and isagalaev.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@16479 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
@@ -33,7 +33,7 @@ class MultiPartParser(object):
|
||||
A rfc2388 multipart/form-data parser.
|
||||
|
||||
``MultiValueDict.parse()`` reads the input stream in ``chunk_size`` chunks
|
||||
and returns a tuple of ``(MultiValueDict(POST), MultiValueDict(FILES))``. If
|
||||
and returns a tuple of ``(MultiValueDict(POST), MultiValueDict(FILES))``.
|
||||
"""
|
||||
def __init__(self, META, input_data, upload_handlers, encoding=None):
|
||||
"""
|
||||
@@ -65,14 +65,11 @@ class MultiPartParser(object):
|
||||
raise MultiPartParserError('Invalid boundary in multipart: %s' % boundary)
|
||||
|
||||
|
||||
#
|
||||
# Content-Length should contain the length of the body we are about
|
||||
# to receive.
|
||||
#
|
||||
try:
|
||||
content_length = int(META.get('HTTP_CONTENT_LENGTH', META.get('CONTENT_LENGTH',0)))
|
||||
except (ValueError, TypeError):
|
||||
# For now set it to 0; we'll try again later on down.
|
||||
content_length = 0
|
||||
|
||||
if content_length < 0:
|
||||
@@ -110,12 +107,10 @@ class MultiPartParser(object):
|
||||
if self._content_length == 0:
|
||||
return QueryDict(MultiValueDict(), encoding=self._encoding), MultiValueDict()
|
||||
|
||||
limited_input_data = LimitBytes(self._input_data, self._content_length)
|
||||
|
||||
# See if the handler will want to take care of the parsing.
|
||||
# This allows overriding everything if somebody wants it.
|
||||
for handler in handlers:
|
||||
result = handler.handle_raw_input(limited_input_data,
|
||||
result = handler.handle_raw_input(self._input_data,
|
||||
self._meta,
|
||||
self._content_length,
|
||||
self._boundary,
|
||||
@@ -128,7 +123,7 @@ class MultiPartParser(object):
|
||||
self._files = MultiValueDict()
|
||||
|
||||
# Instantiate the parser and stream:
|
||||
stream = LazyStream(ChunkIter(limited_input_data, self._chunk_size))
|
||||
stream = LazyStream(ChunkIter(self._input_data, self._chunk_size))
|
||||
|
||||
# Whether or not to signal a file-completion at the beginning of the loop.
|
||||
old_field_name = None
|
||||
@@ -225,10 +220,10 @@ class MultiPartParser(object):
|
||||
exhaust(stream)
|
||||
except StopUpload, e:
|
||||
if not e.connection_reset:
|
||||
exhaust(limited_input_data)
|
||||
exhaust(self._input_data)
|
||||
else:
|
||||
# Make sure that the request data is all fed
|
||||
exhaust(limited_input_data)
|
||||
exhaust(self._input_data)
|
||||
|
||||
# Signal that the upload has completed.
|
||||
for handler in handlers:
|
||||
@@ -390,27 +385,6 @@ class ChunkIter(object):
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
class LimitBytes(object):
|
||||
""" Limit bytes for a file object. """
|
||||
def __init__(self, fileobject, length):
|
||||
self._file = fileobject
|
||||
self.remaining = length
|
||||
|
||||
def read(self, num_bytes=None):
|
||||
"""
|
||||
Read data from the underlying file.
|
||||
If you ask for too much or there isn't anything left,
|
||||
this will raise an InputStreamExhausted error.
|
||||
"""
|
||||
if self.remaining <= 0:
|
||||
raise InputStreamExhausted()
|
||||
if num_bytes is None:
|
||||
num_bytes = self.remaining
|
||||
else:
|
||||
num_bytes = min(num_bytes, self.remaining)
|
||||
self.remaining -= num_bytes
|
||||
return self._file.read(num_bytes)
|
||||
|
||||
class InterBoundaryIter(object):
|
||||
"""
|
||||
A Producer that will iterate over boundaries.
|
||||
|
||||
Reference in New Issue
Block a user