Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add QuerystringState #97

Merged
merged 1 commit into from
Feb 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ lib64
pip-log.txt

# Unit test / coverage reports
.coverage
.coverage.*
.tox
nosetests.xml

Expand Down
35 changes: 21 additions & 14 deletions multipart/multipart.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,17 @@
# Unique missing object.
_missing = object()

# States for the querystring parser.
STATE_BEFORE_FIELD = 0
STATE_FIELD_NAME = 1
STATE_FIELD_DATA = 2

class QuerystringState(IntEnum):
"""Querystring parser states.

These are used to keep track of the state of the parser, and are used to determine
what to do when new data is encountered.
"""

BEFORE_FIELD = 0
FIELD_NAME = 1
FIELD_DATA = 2


class MultipartState(IntEnum):
Expand Down Expand Up @@ -727,7 +734,7 @@ class QuerystringParser(BaseParser):

def __init__(self, callbacks={}, strict_parsing=False, max_size=float("inf")):
super().__init__()
self.state = STATE_BEFORE_FIELD
self.state = QuerystringState.BEFORE_FIELD
self._found_sep = False

self.callbacks = callbacks
Expand Down Expand Up @@ -783,7 +790,7 @@ def _internal_write(self, data, length):
ch = data[i]

# Depending on our state...
if state == STATE_BEFORE_FIELD:
if state == QuerystringState.BEFORE_FIELD:
# If the 'found_sep' flag is set, we've already encountered
# and skipped a single separator. If so, we check our strict
# parsing flag and decide what to do. Otherwise, we haven't
Expand All @@ -810,10 +817,10 @@ def _internal_write(self, data, length):
# this state.
self.callback("field_start")
i -= 1
state = STATE_FIELD_NAME
state = QuerystringState.FIELD_NAME
found_sep = False

elif state == STATE_FIELD_NAME:
elif state == QuerystringState.FIELD_NAME:
# Try and find a separator - we ensure that, if we do, we only
# look for the equal sign before it.
sep_pos = data.find(b"&", i)
Expand All @@ -836,11 +843,11 @@ def _internal_write(self, data, length):
# added to it below, which means the next iteration of this
# loop will inspect the character after the equals sign.
i = equals_pos
state = STATE_FIELD_DATA
state = QuerystringState.FIELD_DATA
else:
# No equals sign found.
if not strict_parsing:
# See also comments in the STATE_FIELD_DATA case below.
# See also comments in the QuerystringState.FIELD_DATA case below.
# If we found the separator, we emit the name and just
# end - there's no data callback at all (not even with
# a blank value).
Expand All @@ -849,7 +856,7 @@ def _internal_write(self, data, length):
self.callback("field_end")

i = sep_pos - 1
state = STATE_BEFORE_FIELD
state = QuerystringState.BEFORE_FIELD
else:
# Otherwise, no separator in this block, so the
# rest of this chunk must be a name.
Expand All @@ -873,7 +880,7 @@ def _internal_write(self, data, length):
self.callback("field_name", data, i, length)
i = length

elif state == STATE_FIELD_DATA:
elif state == QuerystringState.FIELD_DATA:
# Try finding either an ampersand or a semicolon after this
# position.
sep_pos = data.find(b"&", i)
Expand All @@ -891,7 +898,7 @@ def _internal_write(self, data, length):
# "field_start" events only when we actually have data for
# a field of some sort.
i = sep_pos - 1
state = STATE_BEFORE_FIELD
state = QuerystringState.BEFORE_FIELD

# Otherwise, emit the rest as data and finish.
else:
Expand All @@ -917,7 +924,7 @@ def finalize(self):
then the on_end callback.
"""
# If we're currently in the middle of a field, we finish it.
if self.state == STATE_FIELD_DATA:
if self.state == QuerystringState.FIELD_DATA:
self.callback("field_end")
self.callback("end")

Expand Down