def get(self, key, default=None): try: result = self.value[untrusted.string(key).value] return self._valueType(result) except KeyError: if default is None: return None else: return self._valueType(default)
for i in animalGenerator(): assert i in ("cat", "dog", "mouse") assert isinstance(i, str) for i in untrusted.iterator(animalGenerator()): assert i in ("cat", "dog", "mouse") assert isinstance(i, untrusted.string) it = untrusted.iterator(animalGenerator()) # an iterator always returns itself assert iter(it) is it assert same(untrusted.string("cat"), next(it)) assert same(untrusted.string("dog"), next(it)) assert same(untrusted.string("mouse"), next(it)) try: _ = next(it) raise AssertionError except StopIteration: pass # expected # test subclass works too class myiterator(untrusted.iterator): pass
for animal in untrustedAnimalList: try: print(animal) # won't work! except TypeError: print("Can't print(animal) without escaping it first!") print(animal.escape(html.escape)) firstAnimal, *restOfAnimals = untrustedAnimalList print(("The first animal is: " + firstAnimal).escape(html.escape)) # Like normal Python 3 list slices, a slice of an untrsuted.list is a copy, not a view print("The rest of animals are: " + repr(restOfAnimals)) # Nesting - here's a list of list of strings someValues = [fruits, animals, colors] untrustedValues = untrusted.sequenceOf(untrusted.sequence)(someValues) for things in untrustedValues: print("A list of related things: ") for thing in things: print(repr(thing)) print("things is " + repr(things)) s = 'My list is: ' + untrusted.string(', ').join(things).escape( html.escape) print(s) s = "My list reversed is: " + untrusted.string(', ').join( reversed(things)).escape(html.escape) print(s)
import html # for html.escape() import untrusted # example of a string that could be provided by an untrusted user firstName = untrusted.string("Grace") lastName = untrusted.string("<script>alert(\"hack attempt!\");</script>") # works seamlessly with native python strings: fullName = firstName + " " + lastName # fullName was tainted and keeps the untrusted.string type print(repr(fullName)) # <untrusted.string of length 46> # the normal string methods still work as you would expect fullName = fullName.title() # but you can't accidentally use it where a `str` is expected try: print(fullName) # raises TypeError - untrusted.string used as a `str`! fullName.encode('utf8') # also raises TypeError except TypeError: print("We caught an error, as expected!") # instead, you are forced to explicitly escape your string somehow print("<b>Escaped output:</b> " + fullName.escape(html.escape)) # prints safe HTML! print("<b>Escaped output:</b> " + fullName / html.escape) # use this easy shorthand! # But what if you want to pass an argument to the escape function?
# it = untrusted.iterator(open("example.txt"), valueType=untrusted.string) # Or, more simply, it = untrusted.iterator(open("example.txt")) print("repr(it): %s" % repr(it)) for i in it: print("repr(i): %s" % repr(i)) # You can come up with more complicated types, e.g. nested lists. someValues = [ ["cat", "dog", "zebra"], ["apple", "pear", "pineapple"], ["green", "red", "rainbow", "<span color=\"green\">red</span>"] ] myIteratorType = untrusted.iteratorOf(untrusted.iterator) it = myIteratorType(someValues) for things in it: print("A list of related things: ") for thing in things: print(repr(thing)) print("things is " + repr(things)) s = 'My list is: ' + untrusted.string(', ').join(things).escape(html.escape) print(s)
if type(a) != type(b): return False if isinstance(a, untrusted.string): a = a.value if isinstance(b, untrusted.string): b = b.value if a != b: return False return True # Test the test assert same("cat", "cat") assert not same("cat", "dog") assert same(untrusted.string("cat"), untrusted.string("cat")) assert not same(untrusted.string("cat"), untrusted.string("dog")) assert not same(untrusted.string("cat"), "cat") assert not same("cat", untrusted.string("cat")) assert not same("cat", None) assert not same(untrusted.string("cat"), None) assert not same(untrusted.string("cat"), customstring("cat")) assert same(None, None) # Test an untrusted.string is never None! try: _ = untrusted.string(None)