filterstring() and filterunicode() in Python/bltinmodule.c
blindly assumed that tp_as_sequence->sq_item always returns
a str or unicode object. This might fail with str or unicode
subclasses.

This patch checks whether the object returned from __getitem__
is a str/unicode object and raises a TypeError if not (and
the filter function returned true).

Furthermore the result for __getitem__ can be more than one
character long, so checks for enough memory have to be done.
diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py
index 55ea8d2..6e13050 100644
--- a/Lib/test/test_builtin.py
+++ b/Lib/test/test_builtin.py
@@ -367,6 +367,16 @@
                 raise ValueError
         self.assertRaises(ValueError, filter, lambda x: x >="3", badstr("1234"))
 
+        class badstr2(str):
+            def __getitem__(self, index):
+                return 42
+        self.assertRaises(TypeError, filter, lambda x: x >=42, badstr2("1234"))
+
+        class weirdstr(str):
+            def __getitem__(self, index):
+                return weirdstr(2*str.__getitem__(self, index))
+        self.assertEqual(filter(lambda x: x>="33", weirdstr("1234")), "3344")
+
         if have_unicode:
             # test bltinmodule.c::filterunicode()
             self.assertEqual(filter(None, unicode("12")), unicode("12"))
@@ -374,6 +384,17 @@
             self.assertRaises(TypeError, filter, 42, unicode("12"))
             self.assertRaises(ValueError, filter, lambda x: x >="3", badstr(unicode("1234")))
 
+            class badunicode(unicode):
+                def __getitem__(self, index):
+                    return 42
+            self.assertRaises(TypeError, filter, lambda x: x >=42, badunicode("1234"))
+
+            class weirdunicode(unicode):
+                def __getitem__(self, index):
+                    return weirdunicode(2*unicode.__getitem__(self, index))
+            self.assertEqual(
+                filter(lambda x: x>=unicode("33"), weirdunicode("1234")), unicode("3344"))
+
     def test_float(self):
         self.assertEqual(float(3.14), 3.14)
         self.assertEqual(float(314), 314.0)