Esempio n. 1
0
        def __call__(self, *args, **kw):
            tainted = 0
            args = list(args)
            for i in range(len(args)):
                if isinstance(args[i], TaintedString):
                    tainted = 1
                    args[i] = str(args[i])
            for k, v in kw.items():
                if isinstance(v, TaintedString):
                    tainted = 1
                    kw[k] = str(v)
            args = tuple(args)

            retval = self._method(*args, **kw)
            if tainted and isinstance(retval, StringType) and '<' in retval:
                retval = TaintedString(retval)
            return retval
Esempio n. 2
0
    def render(self, md):
        args = self.args
        have_arg = args.has_key
        name = self.__name__

        val = self.expr

        if val is None:
            if md.has_key(name):
                if have_arg('url'):
                    val = md.getitem(name, 0)
                    val = val.absolute_url()
                else:
                    val = md[name]
            else:
                if have_arg('missing'):
                    return args['missing']
                else:
                    raise KeyError, name
        else:
            val = val.eval(md)
            if have_arg('url'): val = val.absolute_url()

        __traceback_info__ = name, val, args

        if have_arg('null') and not val and val != 0:
            # check for null (false but not zero, including None, [], '')
            return args['null']

        # handle special formats defined using fmt= first
        if have_arg('fmt'):
            _get = getattr(md, 'guarded_getattr', None)
            if _get is None:
                _get = getattr

            fmt = args['fmt']
            if have_arg('null') and not val and val != 0:
                try:
                    if hasattr(val, fmt):
                        val = _get(val, fmt)()
                    elif special_formats.has_key(fmt):
                        if fmt == 'html-quote' and \
                           isinstance(val, TaintedString):
                            # TaintedStrings will be quoted by default, don't
                            # double quote.
                            pass
                        else:
                            val = special_formats[fmt](val, name, md)
                    elif fmt == '':
                        val = ''
                    else:
                        if isinstance(val, TaintedString):
                            val = TaintedString(fmt % val)
                        else:
                            val = fmt % val
                except:
                    t, v = sys.exc_type, sys.exc_value
                    if hasattr(sys, 'exc_info'): t, v = sys.exc_info()[:2]
                    if val is None or not str(val): return args['null']
                    raise t, v

            else:
                # We duplicate the code here to avoid exception handler
                # which tends to screw up stack or leak
                if hasattr(val, fmt):
                    val = _get(val, fmt)()
                elif special_formats.has_key(fmt):
                    if fmt == 'html-quote' and \
                        isinstance(val, TaintedString):
                        # TaintedStrings will be quoted by default, don't
                        # double quote.
                        pass
                    else:
                        val = special_formats[fmt](val, name, md)
                elif fmt == '':
                    val = ''
                else:
                    if isinstance(val, TaintedString):
                        val = TaintedString(fmt % val)
                    else:
                        val = fmt % val

        # finally, pump it through the actual string format...
        fmt = self.fmt
        if fmt == 's':
            # Keep tainted strings as tainted strings here.
            if not isinstance(val, TaintedString):
                val = ustr(val)
        else:
            # Keep tainted strings as tainted strings here.
            wastainted = 0
            if isinstance(val, TaintedString): wastainted = 1
            val = ('%' + self.fmt) % (val, )
            if wastainted and '<' in val:
                val = TaintedString(val)

        # next, look for upper, lower, etc
        for f in self.modifiers:
            if f.__name__ == 'html_quote' and isinstance(val, TaintedString):
                # TaintedStrings will be quoted by default, don't double quote.
                continue
            val = f(val)

        if have_arg('size'):
            size = args['size']
            try:
                size = int(size)
            except:
                raise ValueError, (
                    '''a <code>size</code> attribute was used in a <code>var</code>
                tag with a non-integer value.''')
            if len(val) > size:
                val = val[:size]
                l = val.rfind(' ')
                if l > size / 2:
                    val = val[:l + 1]
                if have_arg('etc'): l = args['etc']
                else: l = '...'
                val = val + l

        if isinstance(val, TaintedString):
            val = val.quoted()

        return val
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,
        search_type=re.compile('(:[a-zA-Z][-a-zA-Z0-9_]+|\\.[xy])$').search,
        ):
        """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:

            # XXX begin monkeypatch
            contentType = None
            if fs.headers.has_key('content-type'):
              contentType = fs.headers['content-type']
              # cut off a possible charset definition
              if contentType.find(';') >= 0:
                contentType = contentType[0:contentType.find(';')]
            # Hm, maybe it's an SOAP
            # SOAP 1.1 has HTTP SOAPAction Field
            # SOAP 1.2 has Content-Type application/soap+xml
            #
            # found a Content-Type of text/xml-SOAP on a Microsoft page
            # this page points 3 HTTP-Fields for SOAP Requests:
            # MethodName, InterfaceName (opt) and MessageCall
            #
            if (environ.has_key('HTTP_SOAPACTION') or
                (contentType in ['application/soap+xml',
                                'text/xml',
                                 'text/xml-SOAP']) and fs.value.find('SOAP-ENV:Body') > 0):
                global soap
                if soap is None:
                      import soap
                fp.seek(0)
                directlyProvides(self, ISOAPRequest)
                sparser = soap.SOAPParser(fp.read())
                meth = sparser.method
                self.args = sparser.parse()
                response = soap.SOAPResponse(response)
                response._soap11 = environ.has_key('HTTP_SOAPACTION')
                response._soap12 = (contentType == 'application/soap+xml')
                response._contentType = contentType
                response._method = meth
                response._error_format = 'text/xml'
                other['RESPONSE'] = self.response = response
                other['REQUEST_METHOD'] = method
                self.maybe_webdav_client = 0
                # XXX end monkeypatch

                # Stash XML request for interpretation by a SOAP-aware view
                other['SOAPXML'] = fs.value
            # Hm, maybe it's an XML-RPC
            elif ('content-type' in fs.headers and
                'text/xml' in fs.headers['content-type'] and
                method == 'POST'):
                # Ye haaa, XML-RPC!
                global xmlrpc
                if xmlrpc is None:
                    from ZPublisher import xmlrpc
                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 = {}
            lt = type([])
            CGI_name = isCGI_NAMEs
            defaults = {}
            tainteddefaults = {}
            converter = None

            for item in fslist:

                isFileUpload = 0
                key = item.name
                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 CGI_name or key[:5] == '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))

                    # 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 latin-1 if it can not.
                                item = unicode(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:
                            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, lt):
                                        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, lt):
                                    tainted_mapping[tainted_key].append(item)
                                else:
                                    tainted_mapping[tainted_key] = [tfound,
                                                                    item]

                            if type(found) is lt:
                                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, lt):
                                    taintedform[tainted_key] = copied
                                else:
                                    taintedform[tainted_key] = [copied]
                            elif not isinstance(taintedform[tainted_key], lt):
                                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, lt):
                                taintedform[tainted_key].append(item)
                            else:
                                taintedform[tainted_key] = [tfound, item]

                        if type(found) is lt:
                            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, lt):
                            # the default value is a list
                            l = form[key]
                            if not isinstance(l, lt):
                                l = [l]

                            # First deal with tainted copies
                            if tainted_key in taintedform:
                                tainted = taintedform[tainted_key]
                                if not isinstance(tainted, lt):
                                    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 not defitem 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 not defitem 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 not defitem 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 not x 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
Esempio n. 4
0
    def render(self, md):
        args=self.args
        have_arg=args.has_key
        name=self.__name__

        val=self.expr

        if val is None:
            if md.has_key(name):
                if have_arg('url'):
                    val=md.getitem(name,0)
                    val=val.absolute_url()
                else:
                    val = md[name]
            else:
                if have_arg('missing'):
                    return args['missing']
                else:
                    raise KeyError, name
        else:
            val=val.eval(md)
            if have_arg('url'): val=val.absolute_url()

        __traceback_info__=name, val, args

        if have_arg('null') and not val and val != 0:
            # check for null (false but not zero, including None, [], '')
            return args['null']


        # handle special formats defined using fmt= first
        if have_arg('fmt'):
            _get = getattr(md, 'guarded_getattr', None)
            if _get is None:
                _get = getattr

            fmt=args['fmt']
            if have_arg('null') and not val and val != 0:
                try:
                    if hasattr(val, fmt):
                        val = _get(val, fmt)()
                    elif special_formats.has_key(fmt):
                        if fmt == 'html-quote' and \
                           isinstance(val, TaintedString):
                            # TaintedStrings will be quoted by default, don't
                            # double quote.
                            pass
                        else:
                            val = special_formats[fmt](val, name, md)
                    elif fmt=='': val=''
                    else:
                        if isinstance(val, TaintedString):
                            val = TaintedString(fmt % val)
                        else:
                            val = fmt % val
                except:
                    t, v= sys.exc_type, sys.exc_value
                    if hasattr(sys, 'exc_info'): t, v = sys.exc_info()[:2]
                    if val is None or not str(val): return args['null']
                    raise t, v

            else:
                # We duplicate the code here to avoid exception handler
                # which tends to screw up stack or leak
                if hasattr(val, fmt):
                    val = _get(val, fmt)()
                elif special_formats.has_key(fmt):
                    if fmt == 'html-quote' and \
                        isinstance(val, TaintedString):
                        # TaintedStrings will be quoted by default, don't
                        # double quote.
                        pass
                    else:
                        val = special_formats[fmt](val, name, md)
                elif fmt=='': val=''
                else:
                    if isinstance(val, TaintedString):
                        val = TaintedString(fmt % val)
                    else:
                        val = fmt % val

        # finally, pump it through the actual string format...
        fmt=self.fmt
        if fmt=='s':
            # Keep tainted strings as tainted strings here.
            if not isinstance(val, TaintedString):
                val=ustr(val)
        else:
            # Keep tainted strings as tainted strings here.
            wastainted = 0
            if isinstance(val, TaintedString): wastainted = 1
            val = ('%'+self.fmt) % (val,)
            if wastainted and '<' in val:
                val = TaintedString(val)

        # next, look for upper, lower, etc
        for f in self.modifiers:
            if f.__name__ == 'html_quote' and isinstance(val, TaintedString):
                # TaintedStrings will be quoted by default, don't double quote.
                continue
            val=f(val)

        if have_arg('size'):
            size=args['size']
            try: size=int(size)
            except: raise ValueError,(
                '''a <code>size</code> attribute was used in a <code>var</code>
                tag with a non-integer value.''')
            if len(val) > size:
                val=val[:size]
                l=val.rfind(' ')
                if l > size/2:
                    val=val[:l+1]
                if have_arg('etc'): l=args['etc']
                else: l='...'
                val=val+l

        if isinstance(val, TaintedString):
            val = val.quoted()

        return val