From c1ba0c783fc59dc8d00b9b8aed7250569bcc14d4 Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Mon, 9 Dec 2013 07:38:18 +0100 Subject: fix possible uncaught ValueError from scgi servers With unicode strings it no longer holds that if s.isdigit() then you can safely int(s), because there are more digits (such as ^3 \xb3) accepted by isdigit. This can cause an uncaught ValueError in certain places if the remote scgi server presents bogus data. Thanks to Klaus Aehlig for pointing out what isdigit accepts. --- wsgitools/scgi/asynchronous.py | 12 +++++++----- wsgitools/scgi/forkpool.py | 11 +++++++---- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/wsgitools/scgi/asynchronous.py b/wsgitools/scgi/asynchronous.py index 3009593..51c1d55 100644 --- a/wsgitools/scgi/asynchronous.py +++ b/wsgitools/scgi/asynchronous.py @@ -78,10 +78,11 @@ class SCGIConnection(asyncore.dispatcher): if self.state == SCGIConnection.NEW: if b':' in self.inbuff: reqlen, self.inbuff = self.inbuff.split(b':', 1) - if not reqlen.isdigit(): + try: + reqlen = int(reqlen) + except ValueError: # invalid request format self.close() - return # invalid request format - reqlen = int(reqlen) + return if reqlen > self.maxrequestsize: self.close() return # request too long @@ -105,10 +106,11 @@ class SCGIConnection(asyncore.dispatcher): if self.reqlen == 0: if self.inbuff.startswith(b','): self.inbuff = self.inbuff[1:] - if not self.environ.get("CONTENT_LENGTH", "bad").isdigit(): + try: + self.reqlen = int(self.environ["CONTENT_LENGTH"]) + except ValueError: self.close() return - self.reqlen = int(self.environ["CONTENT_LENGTH"]) if self.reqlen > self.maxpostsize: self.close() return diff --git a/wsgitools/scgi/forkpool.py b/wsgitools/scgi/forkpool.py index 150ed44..1f4cdee 100644 --- a/wsgitools/scgi/forkpool.py +++ b/wsgitools/scgi/forkpool.py @@ -405,10 +405,11 @@ class SCGIServer: con.close() return length, data = data.split(b':', 1) - if not length.isdigit(): # clear protocol violation + try: + length = int(length) + except ValueError: # clear protocol violation con.close() return - length = int(length) while len(data) != length + 1: # read one byte beyond try: @@ -471,12 +472,14 @@ class SCGIServer: response_head[0] = False # set but nothing sent return dumbsend - if not environ.get("CONTENT_LENGTH", "bad").isdigit(): + try: + content_length = int(environ["CONTENT_LENGTH"]) + except ValueError: con.close() return _convert_environ(environ, multiprocess=True) - sfw = SocketFileWrapper(con, int(environ["CONTENT_LENGTH"])) + sfw = SocketFileWrapper(con, content_length) environ["wsgi.input"] = sfw result = self.wsgiapp(environ, start_response) -- cgit v1.2.3