Skip to content

Commit

Permalink
Add QuerystringState (#97)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kludex authored Feb 10, 2024
1 parent 4e24a3e commit 9c936b7
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 15 deletions.
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

0 comments on commit 9c936b7

Please sign in to comment.