Mercurial > cpython-lru_cache-weakref
comparison Lib/cgi.py @ 21211:151b6967bd21 2.1
backport of 1.64, 1.65, 1.68:
1.64: Solve SF bug #231249: cgi.py opens too many (temporary) files.
1.65: Fix a denial-of-service attack, SF bug #443120.
1.68: "ib" should be "boundary"; reported by Neal Norwitz.
the first two of these are pretty severe bugs.
| author | Anthony Baxter <anthonybaxter@gmail.com> |
|---|---|
| date | Wed, 05 Dec 2001 05:10:28 +0000 |
| parents | 8323b098c6ce |
| children |
comparison
equal
deleted
inserted
replaced
| 21210:2d21650f46f8 | 21211:151b6967bd21 |
|---|---|
| 26 # parsing was inspired by code submitted by Andreas Paepcke. Guido van | 26 # parsing was inspired by code submitted by Andreas Paepcke. Guido van |
| 27 # Rossum rewrote, reformatted and documented the module and is currently | 27 # Rossum rewrote, reformatted and documented the module and is currently |
| 28 # responsible for its maintenance. | 28 # responsible for its maintenance. |
| 29 # | 29 # |
| 30 | 30 |
| 31 __version__ = "2.5" | 31 __version__ = "2.6" |
| 32 | 32 |
| 33 | 33 |
| 34 # Imports | 34 # Imports |
| 35 # ======= | 35 # ======= |
| 36 | 36 |
| 241 | 241 |
| 242 XXX This should really be subsumed by FieldStorage altogether -- no | 242 XXX This should really be subsumed by FieldStorage altogether -- no |
| 243 point in having two implementations of the same parsing algorithm. | 243 point in having two implementations of the same parsing algorithm. |
| 244 | 244 |
| 245 """ | 245 """ |
| 246 boundary = "" | |
| 246 if pdict.has_key('boundary'): | 247 if pdict.has_key('boundary'): |
| 247 boundary = pdict['boundary'] | 248 boundary = pdict['boundary'] |
| 248 else: | 249 if not valid_boundary(boundary): |
| 249 boundary = "" | 250 raise ValueError, ('Invalid boundary in multipart form: %s' |
| 251 % `boundary`) | |
| 252 | |
| 250 nextpart = "--" + boundary | 253 nextpart = "--" + boundary |
| 251 lastpart = "--" + boundary + "--" | 254 lastpart = "--" + boundary + "--" |
| 252 partdict = {} | 255 partdict = {} |
| 253 terminator = "" | 256 terminator = "" |
| 254 | 257 |
| 593 | 596 |
| 594 FieldStorageClass = None | 597 FieldStorageClass = None |
| 595 | 598 |
| 596 def read_multi(self, environ, keep_blank_values, strict_parsing): | 599 def read_multi(self, environ, keep_blank_values, strict_parsing): |
| 597 """Internal: read a part that is itself multipart.""" | 600 """Internal: read a part that is itself multipart.""" |
| 601 ib = self.innerboundary | |
| 602 if not valid_boundary(ib): | |
| 603 raise ValueError, ('Invalid boundary in multipart form: %s' | |
| 604 % `ib`) | |
| 598 self.list = [] | 605 self.list = [] |
| 599 klass = self.FieldStorageClass or self.__class__ | 606 klass = self.FieldStorageClass or self.__class__ |
| 600 part = klass(self.fp, {}, self.innerboundary, | 607 part = klass(self.fp, {}, ib, |
| 601 environ, keep_blank_values, strict_parsing) | 608 environ, keep_blank_values, strict_parsing) |
| 602 # Throw first part away | 609 # Throw first part away |
| 603 while not part.done: | 610 while not part.done: |
| 604 headers = rfc822.Message(self.fp) | 611 headers = rfc822.Message(self.fp) |
| 605 part = klass(self.fp, headers, self.innerboundary, | 612 part = klass(self.fp, headers, ib, |
| 606 environ, keep_blank_values, strict_parsing) | 613 environ, keep_blank_values, strict_parsing) |
| 607 self.list.append(part) | 614 self.list.append(part) |
| 608 self.skip_lines() | 615 self.skip_lines() |
| 609 | 616 |
| 610 def read_single(self): | 617 def read_single(self): |
| 631 self.file.write(data) | 638 self.file.write(data) |
| 632 todo = todo - len(data) | 639 todo = todo - len(data) |
| 633 | 640 |
| 634 def read_lines(self): | 641 def read_lines(self): |
| 635 """Internal: read lines until EOF or outerboundary.""" | 642 """Internal: read lines until EOF or outerboundary.""" |
| 636 self.file = self.make_file('') | 643 self.file = self.__file = StringIO() |
| 637 if self.outerboundary: | 644 if self.outerboundary: |
| 638 self.read_lines_to_outerboundary() | 645 self.read_lines_to_outerboundary() |
| 639 else: | 646 else: |
| 640 self.read_lines_to_eof() | 647 self.read_lines_to_eof() |
| 648 | |
| 649 def __write(self, line): | |
| 650 if self.__file is not None: | |
| 651 if self.__file.tell() + len(line) > 1000: | |
| 652 self.file = self.make_file('') | |
| 653 self.file.write(self.__file.getvalue()) | |
| 654 self.__file = None | |
| 655 self.file.write(line) | |
| 641 | 656 |
| 642 def read_lines_to_eof(self): | 657 def read_lines_to_eof(self): |
| 643 """Internal: read lines until EOF.""" | 658 """Internal: read lines until EOF.""" |
| 644 while 1: | 659 while 1: |
| 645 line = self.fp.readline() | 660 line = self.fp.readline() |
| 646 if not line: | 661 if not line: |
| 647 self.done = -1 | 662 self.done = -1 |
| 648 break | 663 break |
| 649 self.file.write(line) | 664 self.__write(line) |
| 650 | 665 |
| 651 def read_lines_to_outerboundary(self): | 666 def read_lines_to_outerboundary(self): |
| 652 """Internal: read lines until outerboundary.""" | 667 """Internal: read lines until outerboundary.""" |
| 653 next = "--" + self.outerboundary | 668 next = "--" + self.outerboundary |
| 654 last = next + "--" | 669 last = next + "--" |
| 672 elif line[-1] == "\n": | 687 elif line[-1] == "\n": |
| 673 delim = "\n" | 688 delim = "\n" |
| 674 line = line[:-1] | 689 line = line[:-1] |
| 675 else: | 690 else: |
| 676 delim = "" | 691 delim = "" |
| 677 self.file.write(odelim + line) | 692 self.__write(odelim + line) |
| 678 | 693 |
| 679 def skip_lines(self): | 694 def skip_lines(self): |
| 680 """Internal: skip lines until outer boundary if defined.""" | 695 """Internal: skip lines until outer boundary if defined.""" |
| 681 if not self.outerboundary or self.done: | 696 if not self.outerboundary or self.done: |
| 682 return | 697 return |
| 989 s = s.replace(">", ">") | 1004 s = s.replace(">", ">") |
| 990 if quote: | 1005 if quote: |
| 991 s = s.replace('"', """) | 1006 s = s.replace('"', """) |
| 992 return s | 1007 return s |
| 993 | 1008 |
| 1009 def valid_boundary(s, _vb_pattern="^[ -~]{0,200}[!-~]$"): | |
| 1010 import re | |
| 1011 return re.match(_vb_pattern, s) | |
| 994 | 1012 |
| 995 # Invoke mainline | 1013 # Invoke mainline |
| 996 # =============== | 1014 # =============== |
| 997 | 1015 |
| 998 # Call test() when this file is run as a script (not imported as a module) | 1016 # Call test() when this file is run as a script (not imported as a module) |
