# Buggy code
def processInputs(
    self,
    # "static" variables that we want to be local for speed
    SEQUENCE=1,
    DEFAULT=2,
    RECORD=4,
    RECORDS=8,
    REC=12,  # RECORD | RECORDS
    EMPTY=16,
    CONVERTED=32,
    hasattr=hasattr,
    getattr=getattr,
    setattr=setattr,
):
    """Process request inputs

    We need to delay input parsing so that it is done under
    publisher control for error handling purposes.
    """
    response = self.response
    environ = self.environ
    method = environ.get("REQUEST_METHOD", "GET")

    if method != "GET":
        fp = self.stdin
    else:
        fp = None

    form = self.form
    other = self.other
    taintedform = self.taintedform

    # If 'QUERY_STRING' is not present in environ
    # FieldStorage will try to get it from sys.argv[1]
    # which is not what we need.
    if "QUERY_STRING" not in environ:
        environ["QUERY_STRING"] = ""

    meth = None
    fs = ZopeFieldStorage(fp=fp, environ=environ, keep_blank_values=1)
    if not hasattr(fs, "list") or fs.list is None:
        if "HTTP_SOAPACTION" in environ:
            # Stash XML request for interpretation by a SOAP-aware view
            other["SOAPXML"] = fs.value
        elif (
            xmlrpc is not None
            and method == "POST"
            and (
                "content-type" in fs.headers
                and "text/xml" in fs.headers["content-type"]
            )
        ):
            # Ye haaa, XML-RPC!
            meth, self.args = xmlrpc.parse_input(fs.value)
            response = xmlrpc.response(response)
            other["RESPONSE"] = self.response = response
            self.maybe_webdav_client = 0
        else:
            self._file = fs.file
    else:
        fslist = fs.list
        tuple_items = {}
        defaults = {}
        tainteddefaults = {}
        converter = None

        for item in fslist:
            isFileUpload = 0
            key = item.name
            if key is None:
                continue

            if (
                hasattr(item, "file")
                and hasattr(item, "filename")
                and hasattr(item, "headers")
            ):
                if item.file and (
                    item.filename is not None
                    # RFC 1867 says that all fields get a content-type.
                    # or 'content-type' in map(lower, item.headers.keys())
                ):
                    item = FileUpload(item)
                    isFileUpload = 1
                else:
                    item = item.value

            flags = 0
            character_encoding = ""
            # Variables for potentially unsafe values.
            tainted = None
            converter_type = None

            # Loop through the different types and set
            # the appropriate flags

            # We'll search from the back to the front.
            # We'll do the search in two steps.  First, we'll
            # do a string search, and then we'll check it with
            # a re search.

            l = key.rfind(":")
            if l >= 0:
                mo = search_type(key, l)
                if mo:
                    l = mo.start(0)
                else:
                    l = -1

                while l >= 0:
                    type_name = key[l + 1 :]
                    key = key[:l]
                    c = get_converter(type_name, None)

                    if c is not None:
                        converter = c
                        converter_type = type_name
                        flags = flags | CONVERTED
                    elif type_name == "list":
                        flags = flags | SEQUENCE
                    elif type_name == "tuple":
                        tuple_items[key] = 1
                        flags = flags | SEQUENCE
                    elif type_name == "method" or type_name == "action":
                        if l:
                            meth = key
                        else:
                            meth = item
                    elif type_name == "default_method" or type_name == "default_action":
                        if not meth:
                            if l:
                                meth = key
                            else:
                                meth = item
                    elif type_name == "default":
                        flags = flags | DEFAULT
                    elif type_name == "record":
                        flags = flags | RECORD
                    elif type_name == "records":
                        flags = flags | RECORDS
                    elif type_name == "ignore_empty":
                        if not item:
                            flags = flags | EMPTY
                    elif has_codec(type_name):
                        character_encoding = type_name

                    l = key.rfind(":")
                    if l < 0:
                        break
                    mo = search_type(key, l)
                    if mo:
                        l = mo.start(0)
                    else:
                        l = -1

            # Filter out special names from form:
            if key in isCGI_NAMEs or key.startswith("HTTP_"):
                continue

            # If the key is tainted, mark it so as well.
            tainted_key = key
            if "<" in key:
                tainted_key = TaintedString(key)

            if flags:
                # skip over empty fields
                if flags & EMPTY:
                    continue

                # Split the key and its attribute
                if flags & REC:
                    key = key.split(".")
                    key, attr = ".".join(key[:-1]), key[-1]

                    # Update the tainted_key if necessary
                    tainted_key = key
                    if "<" in key:
                        tainted_key = TaintedString(key)

                    # Attributes cannot hold a <.
                    if "<" in attr:
                        raise ValueError(
                            "%s is not a valid record attribute name"
                            % escape(attr, True)
                        )

                # defer conversion
                if flags & CONVERTED:
                    try:
                        if character_encoding:
                            # We have a string with a specified character
                            # encoding.  This gets passed to the converter
                            # either as unicode, if it can handle it, or
                            # crunched back down to utf-8 if it can not.
                            if isinstance(item, binary_type):
                                item = text_type(item, character_encoding)
                            if hasattr(converter, "convert_unicode"):
                                item = converter.convert_unicode(item)
                            else:
                                item = converter(item.encode(default_encoding))
                        else:
                            item = converter(item)

                        # Flag potentially unsafe values
                        if converter_type in (
                            "string",
                            "required",
                            "text",
                            "ustring",
                            "utext",
                        ):
                            if not isFileUpload and "<" in item:
                                tainted = TaintedString(item)
                        elif converter_type in ("tokens", "lines", "utokens", "ulines"):
                            is_tainted = 0
                            tainted = item[:]
                            for i in range(len(tainted)):
                                if "<" in tainted[i]:
                                    is_tainted = 1
                                    tainted[i] = TaintedString(tainted[i])
                            if not is_tainted:
                                tainted = None

                    except Exception:
                        if not item and not (flags & DEFAULT) and key in defaults:
                            item = defaults[key]
                            if flags & RECORD:
                                item = getattr(item, attr)
                            if flags & RECORDS:
                                item = getattr(item[-1], attr)
                            if tainted_key in tainteddefaults:
                                tainted = tainteddefaults[tainted_key]
                                if flags & RECORD:
                                    tainted = getattr(tainted, attr)
                                if flags & RECORDS:
                                    tainted = getattr(tainted[-1], attr)
                        else:
                            raise

                elif not isFileUpload and "<" in item:
                    # Flag potentially unsafe values
                    tainted = TaintedString(item)

                # If the key is tainted, we need to store stuff in the
                # tainted dict as well, even if the value is safe.
                if "<" in tainted_key and tainted is None:
                    tainted = item

                # Determine which dictionary to use
                if flags & DEFAULT:
                    mapping_object = defaults
                    tainted_mapping = tainteddefaults
                else:
                    mapping_object = form
                    tainted_mapping = taintedform

                # Insert in dictionary
                if key in mapping_object:
                    if flags & RECORDS:
                        # Get the list and the last record
                        # in the list. reclist is mutable.
                        reclist = mapping_object[key]
                        x = reclist[-1]

                        if tainted:
                            # Store a tainted copy as well
                            if tainted_key not in tainted_mapping:
                                tainted_mapping[tainted_key] = deepcopy(reclist)
                            treclist = tainted_mapping[tainted_key]
                            lastrecord = treclist[-1]

                            if not hasattr(lastrecord, attr):
                                if flags & SEQUENCE:
                                    tainted = [tainted]
                                setattr(lastrecord, attr, tainted)
                            else:
                                if flags & SEQUENCE:
                                    getattr(lastrecord, attr).append(tainted)
                                else:
                                    newrec = record()
                                    setattr(newrec, attr, tainted)
                                    treclist.append(newrec)

                        elif tainted_key in tainted_mapping:
                            # If we already put a tainted value into this
                            # recordset, we need to make sure the whole
                            # recordset is built.
                            treclist = tainted_mapping[tainted_key]
                            lastrecord = treclist[-1]
                            copyitem = item

                            if not hasattr(lastrecord, attr):
                                if flags & SEQUENCE:
                                    copyitem = [copyitem]
                                setattr(lastrecord, attr, copyitem)
                            else:
                                if flags & SEQUENCE:
                                    getattr(lastrecord, attr).append(copyitem)
                                else:
                                    newrec = record()
                                    setattr(newrec, attr, copyitem)
                                    treclist.append(newrec)

                        if not hasattr(x, attr):
                            # If the attribute does not
                            # exist, setit
                            if flags & SEQUENCE:
                                item = [item]
                            setattr(x, attr, item)
                        else:
                            if flags & SEQUENCE:
                                # If the attribute is a
                                # sequence, append the item
                                # to the existing attribute
                                y = getattr(x, attr)
                                y.append(item)
                                setattr(x, attr, y)
                            else:
                                # Create a new record and add
                                # it to the list
                                n = record()
                                setattr(n, attr, item)
                                mapping_object[key].append(n)
                    elif flags & RECORD:
                        b = mapping_object[key]
                        if flags & SEQUENCE:
                            item = [item]
                            if not hasattr(b, attr):
                                # if it does not have the
                                # attribute, set it
                                setattr(b, attr, item)
                            else:
                                # it has the attribute so
                                # append the item to it
                                setattr(b, attr, getattr(b, attr) + item)
                        else:
                            # it is not a sequence so
                            # set the attribute
                            setattr(b, attr, item)

                        # Store a tainted copy as well if necessary
                        if tainted:
                            if tainted_key not in tainted_mapping:
                                tainted_mapping[tainted_key] = deepcopy(
                                    mapping_object[key]
                                )
                            b = tainted_mapping[tainted_key]
                            if flags & SEQUENCE:
                                seq = getattr(b, attr, [])
                                seq.append(tainted)
                                setattr(b, attr, seq)
                            else:
                                setattr(b, attr, tainted)

                        elif tainted_key in tainted_mapping:
                            # If we already put a tainted value into this
                            # record, we need to make sure the whole record
                            # is built.
                            b = tainted_mapping[tainted_key]
                            if flags & SEQUENCE:
                                seq = getattr(b, attr, [])
                                seq.append(item)
                                setattr(b, attr, seq)
                            else:
                                setattr(b, attr, item)

                    else:
                        # it is not a record or list of records
                        found = mapping_object[key]

                        if tainted:
                            # Store a tainted version if necessary
                            if tainted_key not in tainted_mapping:
                                copied = deepcopy(found)
                                if isinstance(copied, list):
                                    tainted_mapping[tainted_key] = copied
                                else:
                                    tainted_mapping[tainted_key] = [copied]
                            tainted_mapping[tainted_key].append(tainted)

                        elif tainted_key in tainted_mapping:
                            # We may already have encountered a tainted
                            # value for this key, and the tainted_mapping
                            # needs to hold all the values.
                            tfound = tainted_mapping[tainted_key]
                            if isinstance(tfound, list):
                                tainted_mapping[tainted_key].append(item)
                            else:
                                tainted_mapping[tainted_key] = [tfound, item]

                        if isinstance(found, list):
                            found.append(item)
                        else:
                            found = [found, item]
                            mapping_object[key] = found
                else:
                    # The dictionary does not have the key
                    if flags & RECORDS:
                        # Create a new record, set its attribute
                        # and put it in the dictionary as a list
                        a = record()
                        if flags & SEQUENCE:
                            item = [item]
                        setattr(a, attr, item)
                        mapping_object[key] = [a]

                        if tainted:
                            # Store a tainted copy if necessary
                            a = record()
                            if flags & SEQUENCE:
                                tainted = [tainted]
                            setattr(a, attr, tainted)
                            tainted_mapping[tainted_key] = [a]

                    elif flags & RECORD:
                        # Create a new record, set its attribute
                        # and put it in the dictionary
                        if flags & SEQUENCE:
                            item = [item]
                        r = mapping_object[key] = record()
                        setattr(r, attr, item)

                        if tainted:
                            # Store a tainted copy if necessary
                            if flags & SEQUENCE:
                                tainted = [tainted]
                            r = tainted_mapping[tainted_key] = record()
                            setattr(r, attr, tainted)
                    else:
                        # it is not a record or list of records
                        if flags & SEQUENCE:
                            item = [item]
                        mapping_object[key] = item

                        if tainted:
                            # Store a tainted copy if necessary
                            if flags & SEQUENCE:
                                tainted = [tainted]
                            tainted_mapping[tainted_key] = tainted

            else:
                # This branch is for case when no type was specified.
                mapping_object = form

                if not isFileUpload and "<" in item:
                    tainted = TaintedString(item)
                elif "<" in key:
                    tainted = item

                # Insert in dictionary
                if key in mapping_object:
                    # it is not a record or list of records
                    found = mapping_object[key]

                    if tainted:
                        # Store a tainted version if necessary
                        if tainted_key not in taintedform:
                            copied = deepcopy(found)
                            if isinstance(copied, list):
                                taintedform[tainted_key] = copied
                            else:
                                taintedform[tainted_key] = [copied]
                        elif not isinstance(taintedform[tainted_key], list):
                            taintedform[tainted_key] = [taintedform[tainted_key]]
                        taintedform[tainted_key].append(tainted)

                    elif tainted_key in taintedform:
                        # We may already have encountered a tainted value
                        # for this key, and the taintedform needs to hold
                        # all the values.
                        tfound = taintedform[tainted_key]
                        if isinstance(tfound, list):
                            taintedform[tainted_key].append(item)
                        else:
                            taintedform[tainted_key] = [tfound, item]

                    if isinstance(found, list):
                        found.append(item)
                    else:
                        found = [found, item]
                        mapping_object[key] = found
                else:
                    mapping_object[key] = item
                    if tainted:
                        taintedform[tainted_key] = tainted

        # insert defaults into form dictionary
        if defaults:
            for key, value in defaults.items():
                tainted_key = key
                if "<" in key:
                    tainted_key = TaintedString(key)

                if key not in form:
                    # if the form does not have the key,
                    # set the default
                    form[key] = value

                    if tainted_key in tainteddefaults:
                        taintedform[tainted_key] = tainteddefaults[tainted_key]
                else:
                    # The form has the key
                    tdefault = tainteddefaults.get(tainted_key, value)
                    if isinstance(value, record):
                        # if the key is mapped to a record, get the
                        # record
                        r = form[key]

                        # First deal with tainted defaults.
                        if tainted_key in taintedform:
                            tainted = taintedform[tainted_key]
                            for k, v in tdefault.__dict__.items():
                                if not hasattr(tainted, k):
                                    setattr(tainted, k, v)

                        elif tainted_key in tainteddefaults:
                            # Find out if any of the tainted default
                            # attributes needs to be copied over.
                            missesdefault = 0
                            for k, v in tdefault.__dict__.items():
                                if not hasattr(r, k):
                                    missesdefault = 1
                                    break
                            if missesdefault:
                                tainted = deepcopy(r)
                                for k, v in tdefault.__dict__.items():
                                    if not hasattr(tainted, k):
                                        setattr(tainted, k, v)
                                taintedform[tainted_key] = tainted

                        for k, v in value.__dict__.items():
                            # loop through the attributes and value
                            # in the default dictionary
                            if not hasattr(r, k):
                                # if the form dictionary doesn't have
                                # the attribute, set it to the default
                                setattr(r, k, v)
                        form[key] = r

                    elif isinstance(value, list):
                        # the default value is a list
                        l = form[key]
                        if not isinstance(l, list):
                            l = [l]

                        # First deal with tainted copies
                        if tainted_key in taintedform:
                            tainted = taintedform[tainted_key]
                            if not isinstance(tainted, list):
                                tainted = [tainted]
                            for defitem in tdefault:
                                if isinstance(defitem, record):
                                    for k, v in defitem.__dict__.items():
                                        for origitem in tainted:
                                            if not hasattr(origitem, k):
                                                setattr(origitem, k, v)
                                else:
                                    if defitem not in tainted:
                                        tainted.append(defitem)
                            taintedform[tainted_key] = tainted

                        elif tainted_key in tainteddefaults:
                            missesdefault = 0
                            for defitem in tdefault:
                                if isinstance(defitem, record):
                                    try:
                                        for k, v in defitem.__dict__.items():
                                            for origitem in l:
                                                if not hasattr(origitem, k):
                                                    missesdefault = 1
                                                    raise NestedLoopExit
                                    except NestedLoopExit:
                                        break
                                else:
                                    if defitem not in l:
                                        missesdefault = 1
                                        break
                            if missesdefault:
                                tainted = deepcopy(l)
                                for defitem in tdefault:
                                    if isinstance(defitem, record):
                                        for k, v in defitem.__dict__.items():
                                            for origitem in tainted:
                                                if not hasattr(origitem, k):
                                                    setattr(origitem, k, v)
                                    else:
                                        if defitem not in tainted:
                                            tainted.append(defitem)
                                taintedform[tainted_key] = tainted

                        for x in value:
                            # for each x in the list
                            if isinstance(x, record):
                                # if the x is a record
                                for k, v in x.__dict__.items():
                                    # loop through each
                                    # attribute and value in
                                    # the record

                                    for y in l:
                                        # loop through each
                                        # record in the form
                                        # list if it doesn't
                                        # have the attributes
                                        # in the default
                                        # dictionary, set them

                                        if not hasattr(y, k):
                                            setattr(y, k, v)
                            else:
                                # x is not a record
                                if x not in l:
                                    l.append(x)
                        form[key] = l
                    else:
                        # The form has the key, the key is not mapped
                        # to a record or sequence so do nothing
                        pass

        # Convert to tuples
        if tuple_items:
            for key in tuple_items.keys():
                # Split the key and get the attr
                k = key.split(".")
                k, attr = ".".join(k[:-1]), k[-1]
                a = attr
                new = ""
                # remove any type_names in the attr
                while not a == "":
                    a = a.split(":")
                    a, new = ":".join(a[:-1]), a[-1]
                attr = new
                if k in form:
                    # If the form has the split key get its value
                    tainted_split_key = k
                    if "<" in k:
                        tainted_split_key = TaintedString(k)
                    item = form[k]
                    if isinstance(item, record):
                        # if the value is mapped to a record, check if it
                        # has the attribute, if it has it, convert it to
                        # a tuple and set it
                        if hasattr(item, attr):
                            value = tuple(getattr(item, attr))
                            setattr(item, attr, value)
                    else:
                        # It is mapped to a list of  records
                        for x in item:
                            # loop through the records
                            if hasattr(x, attr):
                                # If the record has the attribute
                                # convert it to a tuple and set it
                                value = tuple(getattr(x, attr))
                                setattr(x, attr, value)

                    # Do the same for the tainted counterpart
                    if tainted_split_key in taintedform:
                        tainted = taintedform[tainted_split_key]
                        if isinstance(item, record):
                            seq = tuple(getattr(tainted, attr))
                            setattr(tainted, attr, seq)
                        else:
                            for trec in tainted:
                                if hasattr(trec, attr):
                                    seq = getattr(trec, attr)
                                    seq = tuple(seq)
                                    setattr(trec, attr, seq)
                else:
                    # the form does not have the split key
                    tainted_key = key
                    if "<" in key:
                        tainted_key = TaintedString(key)
                    if key in form:
                        # if it has the original key, get the item
                        # convert it to a tuple
                        item = form[key]
                        item = tuple(form[key])
                        form[key] = item

                    if tainted_key in taintedform:
                        tainted = tuple(taintedform[tainted_key])
                        taintedform[tainted_key] = tainted

    if meth:
        if "PATH_INFO" in environ:
            path = environ["PATH_INFO"]
            while path[-1:] == "/":
                path = path[:-1]
        else:
            path = ""
        other["PATH_INFO"] = path = "%s/%s" % (path, meth)
        self._hacked_path = 1


# Traceback (ValueError)
Traceback (most recent call last):
File "/tmp/z2py36/lib/python3.6/site-packages/waitress/channel.py", line 338, in service
task.service()
File "/tmp/z2py36/lib/python3.6/site-packages/waitress/task.py", line 169, in service
self.execute()
File "/tmp/z2py36/lib/python3.6/site-packages/waitress/task.py", line 399, in execute
app_iter = self.channel.server.application(env, start_response)
File "/tmp/z2py36/lib/python3.6/site-packages/ZPublisher/httpexceptions.py", line 33, in __call__
return self.application(environ, start_response)
File "/tmp/z2py36/lib/python3.6/site-packages/ZPublisher/WSGIPublisher.py", line 238, in publish_module
request, response, module_info, _publish=_publish)
File "/tmp/z2py36/lib/python3.6/site-packages/ZPublisher/WSGIPublisher.py", line 211, in _publish_response
reraise(exc.__class__, exc, sys.exc_info()[2])
File "/tmp/z2py36/lib/python3.6/site-packages/six.py", line 686, in reraise
raise value
File "/tmp/z2py36/lib/python3.6/site-packages/ZPublisher/WSGIPublisher.py", line 172, in _publish_response
response = _publish(request, module_info)
File "/tmp/z2py36/lib/python3.6/site-packages/ZPublisher/WSGIPublisher.py", line 162, in publish
bind=1)
File "/tmp/z2py36/lib/python3.6/site-packages/ZPublisher/mapply.py", line 85, in mapply
return debug(object, args, context)
File "/tmp/z2py36/lib/python3.6/site-packages/ZPublisher/WSGIPublisher.py", line 57, in call_object
return obj(*args)
File "/tmp/z2py36/lib/python3.6/site-packages/OFS/Image.py", line 83, in manage_addFile
newFile.manage_upload(file)
File "/tmp/z2py36/lib/python3.6/site-packages/OFS/Image.py", line 506, in manage_upload
data, size = self._read_data(file)
File "/tmp/z2py36/lib/python3.6/site-packages/OFS/Image.py", line 554, in _read_data
seek(0, 2)
File "/tmp/z2py36/lib/python3.6/tempfile.py", line 483, in func_wrapper
return func(*args, **kwargs)
ValueError: seek of closed file

# Fixed code
def processInputs(
    self,
    # "static" variables that we want to be local for speed
    SEQUENCE=1,
    DEFAULT=2,
    RECORD=4,
    RECORDS=8,
    REC=12,  # RECORD | RECORDS
    EMPTY=16,
    CONVERTED=32,
    hasattr=hasattr,
    getattr=getattr,
    setattr=setattr,
):
    """Process request inputs

    We need to delay input parsing so that it is done under
    publisher control for error handling purposes.
    """
    response = self.response
    environ = self.environ
    method = environ.get("REQUEST_METHOD", "GET")

    if method != "GET":
        fp = self.stdin
    else:
        fp = None

    form = self.form
    other = self.other
    taintedform = self.taintedform

    # If 'QUERY_STRING' is not present in environ
    # FieldStorage will try to get it from sys.argv[1]
    # which is not what we need.
    if "QUERY_STRING" not in environ:
        environ["QUERY_STRING"] = ""

    meth = None
    fs = ZopeFieldStorage(fp=fp, environ=environ, keep_blank_values=1)

    # Keep a reference to the FieldStorage. Otherwise it's
    # __del__ method is called too early and closing FieldStorage.file.
    self._hold(fs)

    if not hasattr(fs, "list") or fs.list is None:
        if "HTTP_SOAPACTION" in environ:
            # Stash XML request for interpretation by a SOAP-aware view
            other["SOAPXML"] = fs.value
        elif (
            xmlrpc is not None
            and method == "POST"
            and (
                "content-type" in fs.headers
                and "text/xml" in fs.headers["content-type"]
            )
        ):
            # Ye haaa, XML-RPC!
            meth, self.args = xmlrpc.parse_input(fs.value)
            response = xmlrpc.response(response)
            other["RESPONSE"] = self.response = response
            self.maybe_webdav_client = 0
        else:
            self._file = fs.file
    else:
        fslist = fs.list
        tuple_items = {}
        defaults = {}
        tainteddefaults = {}
        converter = None

        for item in fslist:
            isFileUpload = 0
            key = item.name
            if key is None:
                continue

            if (
                hasattr(item, "file")
                and hasattr(item, "filename")
                and hasattr(item, "headers")
            ):
                if item.file and (
                    item.filename is not None
                    # RFC 1867 says that all fields get a content-type.
                    # or 'content-type' in map(lower, item.headers.keys())
                ):
                    item = FileUpload(item)
                    isFileUpload = 1
                else:
                    item = item.value

            flags = 0
            character_encoding = ""
            # Variables for potentially unsafe values.
            tainted = None
            converter_type = None

            # Loop through the different types and set
            # the appropriate flags

            # We'll search from the back to the front.
            # We'll do the search in two steps.  First, we'll
            # do a string search, and then we'll check it with
            # a re search.

            l = key.rfind(":")
            if l >= 0:
                mo = search_type(key, l)
                if mo:
                    l = mo.start(0)
                else:
                    l = -1

                while l >= 0:
                    type_name = key[l + 1 :]
                    key = key[:l]
                    c = get_converter(type_name, None)

                    if c is not None:
                        converter = c
                        converter_type = type_name
                        flags = flags | CONVERTED
                    elif type_name == "list":
                        flags = flags | SEQUENCE
                    elif type_name == "tuple":
                        tuple_items[key] = 1
                        flags = flags | SEQUENCE
                    elif type_name == "method" or type_name == "action":
                        if l:
                            meth = key
                        else:
                            meth = item
                    elif type_name == "default_method" or type_name == "default_action":
                        if not meth:
                            if l:
                                meth = key
                            else:
                                meth = item
                    elif type_name == "default":
                        flags = flags | DEFAULT
                    elif type_name == "record":
                        flags = flags | RECORD
                    elif type_name == "records":
                        flags = flags | RECORDS
                    elif type_name == "ignore_empty":
                        if not item:
                            flags = flags | EMPTY
                    elif has_codec(type_name):
                        character_encoding = type_name

                    l = key.rfind(":")
                    if l < 0:
                        break
                    mo = search_type(key, l)
                    if mo:
                        l = mo.start(0)
                    else:
                        l = -1

            # Filter out special names from form:
            if key in isCGI_NAMEs or key.startswith("HTTP_"):
                continue

            # If the key is tainted, mark it so as well.
            tainted_key = key
            if "<" in key:
                tainted_key = TaintedString(key)

            if flags:
                # skip over empty fields
                if flags & EMPTY:
                    continue

                # Split the key and its attribute
                if flags & REC:
                    key = key.split(".")
                    key, attr = ".".join(key[:-1]), key[-1]

                    # Update the tainted_key if necessary
                    tainted_key = key
                    if "<" in key:
                        tainted_key = TaintedString(key)

                    # Attributes cannot hold a <.
                    if "<" in attr:
                        raise ValueError(
                            "%s is not a valid record attribute name"
                            % escape(attr, True)
                        )

                # defer conversion
                if flags & CONVERTED:
                    try:
                        if character_encoding:
                            # We have a string with a specified character
                            # encoding.  This gets passed to the converter
                            # either as unicode, if it can handle it, or
                            # crunched back down to utf-8 if it can not.
                            if isinstance(item, binary_type):
                                item = text_type(item, character_encoding)
                            if hasattr(converter, "convert_unicode"):
                                item = converter.convert_unicode(item)
                            else:
                                item = converter(item.encode(default_encoding))
                        else:
                            item = converter(item)

                        # Flag potentially unsafe values
                        if converter_type in (
                            "string",
                            "required",
                            "text",
                            "ustring",
                            "utext",
                        ):
                            if not isFileUpload and "<" in item:
                                tainted = TaintedString(item)
                        elif converter_type in ("tokens", "lines", "utokens", "ulines"):
                            is_tainted = 0
                            tainted = item[:]
                            for i in range(len(tainted)):
                                if "<" in tainted[i]:
                                    is_tainted = 1
                                    tainted[i] = TaintedString(tainted[i])
                            if not is_tainted:
                                tainted = None

                    except Exception:
                        if not item and not (flags & DEFAULT) and key in defaults:
                            item = defaults[key]
                            if flags & RECORD:
                                item = getattr(item, attr)
                            if flags & RECORDS:
                                item = getattr(item[-1], attr)
                            if tainted_key in tainteddefaults:
                                tainted = tainteddefaults[tainted_key]
                                if flags & RECORD:
                                    tainted = getattr(tainted, attr)
                                if flags & RECORDS:
                                    tainted = getattr(tainted[-1], attr)
                        else:
                            raise

                elif not isFileUpload and "<" in item:
                    # Flag potentially unsafe values
                    tainted = TaintedString(item)

                # If the key is tainted, we need to store stuff in the
                # tainted dict as well, even if the value is safe.
                if "<" in tainted_key and tainted is None:
                    tainted = item

                # Determine which dictionary to use
                if flags & DEFAULT:
                    mapping_object = defaults
                    tainted_mapping = tainteddefaults
                else:
                    mapping_object = form
                    tainted_mapping = taintedform

                # Insert in dictionary
                if key in mapping_object:
                    if flags & RECORDS:
                        # Get the list and the last record
                        # in the list. reclist is mutable.
                        reclist = mapping_object[key]
                        x = reclist[-1]

                        if tainted:
                            # Store a tainted copy as well
                            if tainted_key not in tainted_mapping:
                                tainted_mapping[tainted_key] = deepcopy(reclist)
                            treclist = tainted_mapping[tainted_key]
                            lastrecord = treclist[-1]

                            if not hasattr(lastrecord, attr):
                                if flags & SEQUENCE:
                                    tainted = [tainted]
                                setattr(lastrecord, attr, tainted)
                            else:
                                if flags & SEQUENCE:
                                    getattr(lastrecord, attr).append(tainted)
                                else:
                                    newrec = record()
                                    setattr(newrec, attr, tainted)
                                    treclist.append(newrec)

                        elif tainted_key in tainted_mapping:
                            # If we already put a tainted value into this
                            # recordset, we need to make sure the whole
                            # recordset is built.
                            treclist = tainted_mapping[tainted_key]
                            lastrecord = treclist[-1]
                            copyitem = item

                            if not hasattr(lastrecord, attr):
                                if flags & SEQUENCE:
                                    copyitem = [copyitem]
                                setattr(lastrecord, attr, copyitem)
                            else:
                                if flags & SEQUENCE:
                                    getattr(lastrecord, attr).append(copyitem)
                                else:
                                    newrec = record()
                                    setattr(newrec, attr, copyitem)
                                    treclist.append(newrec)

                        if not hasattr(x, attr):
                            # If the attribute does not
                            # exist, setit
                            if flags & SEQUENCE:
                                item = [item]
                            setattr(x, attr, item)
                        else:
                            if flags & SEQUENCE:
                                # If the attribute is a
                                # sequence, append the item
                                # to the existing attribute
                                y = getattr(x, attr)
                                y.append(item)
                                setattr(x, attr, y)
                            else:
                                # Create a new record and add
                                # it to the list
                                n = record()
                                setattr(n, attr, item)
                                mapping_object[key].append(n)
                    elif flags & RECORD:
                        b = mapping_object[key]
                        if flags & SEQUENCE:
                            item = [item]
                            if not hasattr(b, attr):
                                # if it does not have the
                                # attribute, set it
                                setattr(b, attr, item)
                            else:
                                # it has the attribute so
                                # append the item to it
                                setattr(b, attr, getattr(b, attr) + item)
                        else:
                            # it is not a sequence so
                            # set the attribute
                            setattr(b, attr, item)

                        # Store a tainted copy as well if necessary
                        if tainted:
                            if tainted_key not in tainted_mapping:
                                tainted_mapping[tainted_key] = deepcopy(
                                    mapping_object[key]
                                )
                            b = tainted_mapping[tainted_key]
                            if flags & SEQUENCE:
                                seq = getattr(b, attr, [])
                                seq.append(tainted)
                                setattr(b, attr, seq)
                            else:
                                setattr(b, attr, tainted)

                        elif tainted_key in tainted_mapping:
                            # If we already put a tainted value into this
                            # record, we need to make sure the whole record
                            # is built.
                            b = tainted_mapping[tainted_key]
                            if flags & SEQUENCE:
                                seq = getattr(b, attr, [])
                                seq.append(item)
                                setattr(b, attr, seq)
                            else:
                                setattr(b, attr, item)

                    else:
                        # it is not a record or list of records
                        found = mapping_object[key]

                        if tainted:
                            # Store a tainted version if necessary
                            if tainted_key not in tainted_mapping:
                                copied = deepcopy(found)
                                if isinstance(copied, list):
                                    tainted_mapping[tainted_key] = copied
                                else:
                                    tainted_mapping[tainted_key] = [copied]
                            tainted_mapping[tainted_key].append(tainted)

                        elif tainted_key in tainted_mapping:
                            # We may already have encountered a tainted
                            # value for this key, and the tainted_mapping
                            # needs to hold all the values.
                            tfound = tainted_mapping[tainted_key]
                            if isinstance(tfound, list):
                                tainted_mapping[tainted_key].append(item)
                            else:
                                tainted_mapping[tainted_key] = [tfound, item]

                        if isinstance(found, list):
                            found.append(item)
                        else:
                            found = [found, item]
                            mapping_object[key] = found
                else:
                    # The dictionary does not have the key
                    if flags & RECORDS:
                        # Create a new record, set its attribute
                        # and put it in the dictionary as a list
                        a = record()
                        if flags & SEQUENCE:
                            item = [item]
                        setattr(a, attr, item)
                        mapping_object[key] = [a]

                        if tainted:
                            # Store a tainted copy if necessary
                            a = record()
                            if flags & SEQUENCE:
                                tainted = [tainted]
                            setattr(a, attr, tainted)
                            tainted_mapping[tainted_key] = [a]

                    elif flags & RECORD:
                        # Create a new record, set its attribute
                        # and put it in the dictionary
                        if flags & SEQUENCE:
                            item = [item]
                        r = mapping_object[key] = record()
                        setattr(r, attr, item)

                        if tainted:
                            # Store a tainted copy if necessary
                            if flags & SEQUENCE:
                                tainted = [tainted]
                            r = tainted_mapping[tainted_key] = record()
                            setattr(r, attr, tainted)
                    else:
                        # it is not a record or list of records
                        if flags & SEQUENCE:
                            item = [item]
                        mapping_object[key] = item

                        if tainted:
                            # Store a tainted copy if necessary
                            if flags & SEQUENCE:
                                tainted = [tainted]
                            tainted_mapping[tainted_key] = tainted

            else:
                # This branch is for case when no type was specified.
                mapping_object = form

                if not isFileUpload and "<" in item:
                    tainted = TaintedString(item)
                elif "<" in key:
                    tainted = item

                # Insert in dictionary
                if key in mapping_object:
                    # it is not a record or list of records
                    found = mapping_object[key]

                    if tainted:
                        # Store a tainted version if necessary
                        if tainted_key not in taintedform:
                            copied = deepcopy(found)
                            if isinstance(copied, list):
                                taintedform[tainted_key] = copied
                            else:
                                taintedform[tainted_key] = [copied]
                        elif not isinstance(taintedform[tainted_key], list):
                            taintedform[tainted_key] = [taintedform[tainted_key]]
                        taintedform[tainted_key].append(tainted)

                    elif tainted_key in taintedform:
                        # We may already have encountered a tainted value
                        # for this key, and the taintedform needs to hold
                        # all the values.
                        tfound = taintedform[tainted_key]
                        if isinstance(tfound, list):
                            taintedform[tainted_key].append(item)
                        else:
                            taintedform[tainted_key] = [tfound, item]

                    if isinstance(found, list):
                        found.append(item)
                    else:
                        found = [found, item]
                        mapping_object[key] = found
                else:
                    mapping_object[key] = item
                    if tainted:
                        taintedform[tainted_key] = tainted

        # insert defaults into form dictionary
        if defaults:
            for key, value in defaults.items():
                tainted_key = key
                if "<" in key:
                    tainted_key = TaintedString(key)

                if key not in form:
                    # if the form does not have the key,
                    # set the default
                    form[key] = value

                    if tainted_key in tainteddefaults:
                        taintedform[tainted_key] = tainteddefaults[tainted_key]
                else:
                    # The form has the key
                    tdefault = tainteddefaults.get(tainted_key, value)
                    if isinstance(value, record):
                        # if the key is mapped to a record, get the
                        # record
                        r = form[key]

                        # First deal with tainted defaults.
                        if tainted_key in taintedform:
                            tainted = taintedform[tainted_key]
                            for k, v in tdefault.__dict__.items():
                                if not hasattr(tainted, k):
                                    setattr(tainted, k, v)

                        elif tainted_key in tainteddefaults:
                            # Find out if any of the tainted default
                            # attributes needs to be copied over.
                            missesdefault = 0
                            for k, v in tdefault.__dict__.items():
                                if not hasattr(r, k):
                                    missesdefault = 1
                                    break
                            if missesdefault:
                                tainted = deepcopy(r)
                                for k, v in tdefault.__dict__.items():
                                    if not hasattr(tainted, k):
                                        setattr(tainted, k, v)
                                taintedform[tainted_key] = tainted

                        for k, v in value.__dict__.items():
                            # loop through the attributes and value
                            # in the default dictionary
                            if not hasattr(r, k):
                                # if the form dictionary doesn't have
                                # the attribute, set it to the default
                                setattr(r, k, v)
                        form[key] = r

                    elif isinstance(value, list):
                        # the default value is a list
                        l = form[key]
                        if not isinstance(l, list):
                            l = [l]

                        # First deal with tainted copies
                        if tainted_key in taintedform:
                            tainted = taintedform[tainted_key]
                            if not isinstance(tainted, list):
                                tainted = [tainted]
                            for defitem in tdefault:
                                if isinstance(defitem, record):
                                    for k, v in defitem.__dict__.items():
                                        for origitem in tainted:
                                            if not hasattr(origitem, k):
                                                setattr(origitem, k, v)
                                else:
                                    if defitem not in tainted:
                                        tainted.append(defitem)
                            taintedform[tainted_key] = tainted

                        elif tainted_key in tainteddefaults:
                            missesdefault = 0
                            for defitem in tdefault:
                                if isinstance(defitem, record):
                                    try:
                                        for k, v in defitem.__dict__.items():
                                            for origitem in l:
                                                if not hasattr(origitem, k):
                                                    missesdefault = 1
                                                    raise NestedLoopExit
                                    except NestedLoopExit:
                                        break
                                else:
                                    if defitem not in l:
                                        missesdefault = 1
                                        break
                            if missesdefault:
                                tainted = deepcopy(l)
                                for defitem in tdefault:
                                    if isinstance(defitem, record):
                                        for k, v in defitem.__dict__.items():
                                            for origitem in tainted:
                                                if not hasattr(origitem, k):
                                                    setattr(origitem, k, v)
                                    else:
                                        if defitem not in tainted:
                                            tainted.append(defitem)
                                taintedform[tainted_key] = tainted

                        for x in value:
                            # for each x in the list
                            if isinstance(x, record):
                                # if the x is a record
                                for k, v in x.__dict__.items():
                                    # loop through each
                                    # attribute and value in
                                    # the record

                                    for y in l:
                                        # loop through each
                                        # record in the form
                                        # list if it doesn't
                                        # have the attributes
                                        # in the default
                                        # dictionary, set them

                                        if not hasattr(y, k):
                                            setattr(y, k, v)
                            else:
                                # x is not a record
                                if x not in l:
                                    l.append(x)
                        form[key] = l
                    else:
                        # The form has the key, the key is not mapped
                        # to a record or sequence so do nothing
                        pass

        # Convert to tuples
        if tuple_items:
            for key in tuple_items.keys():
                # Split the key and get the attr
                k = key.split(".")
                k, attr = ".".join(k[:-1]), k[-1]
                a = attr
                new = ""
                # remove any type_names in the attr
                while not a == "":
                    a = a.split(":")
                    a, new = ":".join(a[:-1]), a[-1]
                attr = new
                if k in form:
                    # If the form has the split key get its value
                    tainted_split_key = k
                    if "<" in k:
                        tainted_split_key = TaintedString(k)
                    item = form[k]
                    if isinstance(item, record):
                        # if the value is mapped to a record, check if it
                        # has the attribute, if it has it, convert it to
                        # a tuple and set it
                        if hasattr(item, attr):
                            value = tuple(getattr(item, attr))
                            setattr(item, attr, value)
                    else:
                        # It is mapped to a list of  records
                        for x in item:
                            # loop through the records
                            if hasattr(x, attr):
                                # If the record has the attribute
                                # convert it to a tuple and set it
                                value = tuple(getattr(x, attr))
                                setattr(x, attr, value)

                    # Do the same for the tainted counterpart
                    if tainted_split_key in taintedform:
                        tainted = taintedform[tainted_split_key]
                        if isinstance(item, record):
                            seq = tuple(getattr(tainted, attr))
                            setattr(tainted, attr, seq)
                        else:
                            for trec in tainted:
                                if hasattr(trec, attr):
                                    seq = getattr(trec, attr)
                                    seq = tuple(seq)
                                    setattr(trec, attr, seq)
                else:
                    # the form does not have the split key
                    tainted_key = key
                    if "<" in key:
                        tainted_key = TaintedString(key)
                    if key in form:
                        # if it has the original key, get the item
                        # convert it to a tuple
                        item = form[key]
                        item = tuple(form[key])
                        form[key] = item

                    if tainted_key in taintedform:
                        tainted = tuple(taintedform[tainted_key])
                        taintedform[tainted_key] = tainted

    if meth:
        if "PATH_INFO" in environ:
            path = environ["PATH_INFO"]
            while path[-1:] == "/":
                path = path[:-1]
        else:
            path = ""
        other["PATH_INFO"] = path = "%s/%s" % (path, meth)
        self._hacked_path = 1