summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHelmut Grohne <helmut@subdivi.de>2013-12-09 07:38:18 +0100
committerHelmut Grohne <helmut@subdivi.de>2013-12-09 07:38:18 +0100
commitc1ba0c783fc59dc8d00b9b8aed7250569bcc14d4 (patch)
treede5139a6f71f5403795caa20d237ba59815b5bcc
parent27ed9839582c4fce9a0fff82281fb2e302be808e (diff)
downloadwsgitools-c1ba0c783fc59dc8d00b9b8aed7250569bcc14d4.tar.gz
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.
-rw-r--r--wsgitools/scgi/asynchronous.py12
-rw-r--r--wsgitools/scgi/forkpool.py11
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)