diff Lib/cgi.py @ 39437:864172515ee7 2.4

Chris McDonough's patch to defend against certain DoS attacks on FieldStorage. SF bug #1112549. (backport from rev. 51190)
author Georg Brandl <georg@python.org>
date Fri, 11 Aug 2006 07:14:38 +0000
parents 846ba2972d7c
children
line wrap: on
line diff
--- a/Lib/cgi.py	Wed Aug 09 07:15:29 2006 +0000
+++ b/Lib/cgi.py	Fri Aug 11 07:14:38 2006 +0000
@@ -247,6 +247,10 @@
 
     XXX This should really be subsumed by FieldStorage altogether -- no
     point in having two implementations of the same parsing algorithm.
+    Also, FieldStorage protects itself better against certain DoS attacks
+    by limiting the size of the data read in one chunk.  The API here
+    does not support that kind of protection.  This also affects parse()
+    since it can call parse_multipart().
 
     """
     boundary = ""
@@ -695,7 +699,7 @@
     def read_lines_to_eof(self):
         """Internal: read lines until EOF."""
         while 1:
-            line = self.fp.readline()
+            line = self.fp.readline(1<<16)
             if not line:
                 self.done = -1
                 break
@@ -706,12 +710,13 @@
         next = "--" + self.outerboundary
         last = next + "--"
         delim = ""
+        last_line_lfend = True
         while 1:
-            line = self.fp.readline()
+            line = self.fp.readline(1<<16)
             if not line:
                 self.done = -1
                 break
-            if line[:2] == "--":
+            if line[:2] == "--" and last_line_lfend:
                 strippedline = line.strip()
                 if strippedline == next:
                     break
@@ -722,11 +727,14 @@
             if line[-2:] == "\r\n":
                 delim = "\r\n"
                 line = line[:-2]
+                last_line_lfend = True
             elif line[-1] == "\n":
                 delim = "\n"
                 line = line[:-1]
+                last_line_lfend = True
             else:
                 delim = ""
+                last_line_lfend = False
             self.__write(odelim + line)
 
     def skip_lines(self):
@@ -735,18 +743,20 @@
             return
         next = "--" + self.outerboundary
         last = next + "--"
+        last_line_lfend = True
         while 1:
-            line = self.fp.readline()
+            line = self.fp.readline(1<<16)
             if not line:
                 self.done = -1
                 break
-            if line[:2] == "--":
+            if line[:2] == "--" and last_line_lfend:
                 strippedline = line.strip()
                 if strippedline == next:
                     break
                 if strippedline == last:
                     self.done = 1
                     break
+            last_line_lfend = line.endswith('\n')
 
     def make_file(self, binary=None):
         """Overridable: return a readable & writable file.