Skip to content

Commit

Permalink
twisted#12015 Replace cgi.escape and cgi.parse_header (twisted#12016)
Browse files Browse the repository at this point in the history
  • Loading branch information
adiroiban committed Nov 3, 2023
2 parents db0d980 + b4d3a83 commit ef5b35d
Show file tree
Hide file tree
Showing 16 changed files with 37 additions and 42 deletions.
6 changes: 3 additions & 3 deletions docs/core/howto/tutorial/listings/finger/finger15.tac
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Read from file, announce on the web!
import cgi
import html

from twisted.application import service, strports
from twisted.internet import defer, protocol, reactor
Expand Down Expand Up @@ -39,9 +39,9 @@ class FingerResource(resource.Resource):
messagevalue = messagevalue.decode("ascii")
if username:
username = username.decode("ascii")
username = cgi.escape(username)
username = html.escape(username)
if messagevalue is not None:
messagevalue = cgi.escape(messagevalue)
messagevalue = html.escape(messagevalue)
text = f"<h1>{username}</h1><p>{messagevalue}</p>"
else:
text = f"<h1>{username}</h1><p>No such user</p>"
Expand Down
2 changes: 0 additions & 2 deletions docs/core/howto/tutorial/listings/finger/finger16.tac
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
# Read from file, announce on the web, irc
import cgi

from twisted.application import internet, service, strports
from twisted.internet import defer, endpoints, protocol, reactor
from twisted.protocols import basic
Expand Down
2 changes: 0 additions & 2 deletions docs/core/howto/tutorial/listings/finger/finger17.tac
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
# Read from file, announce on the web, irc, xml-rpc
import cgi

from twisted.application import internet, service, strports
from twisted.internet import defer, endpoints, protocol, reactor
from twisted.protocols import basic
Expand Down
4 changes: 2 additions & 2 deletions docs/core/howto/tutorial/listings/finger/finger18.tac
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Do everything properly
import cgi
import html

from twisted.application import internet, service, strports
from twisted.internet import defer, endpoints, protocol, reactor
Expand Down Expand Up @@ -70,7 +70,7 @@ class UserStatus(resource.Resource):

def render_GET(self, request):
d = self.service.getUser(self.user)
d.addCallback(cgi.escape)
d.addCallback(html.escape)
d.addCallback(lambda m: "<h1>%s</h1>" % self.user + "<p>%s</p>" % m)
d.addCallback(request.write)
d.addCallback(lambda _: request.finish())
Expand Down
4 changes: 2 additions & 2 deletions docs/core/howto/tutorial/listings/finger/finger19.tac
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Do everything properly, and componentize
import cgi
import html

from zope.interface import Interface, implementer

Expand Down Expand Up @@ -196,7 +196,7 @@ class UserStatus(resource.Resource):

def render_GET(self, request):
d = self.service.getUser(self.user)
d.addCallback(cgi.escape)
d.addCallback(html.escape)
d.addCallback(lambda m: "<h1>%s</h1>" % self.user + "<p>%s</p>" % m)
d.addCallback(request.write)
d.addCallback(lambda _: request.finish())
Expand Down
4 changes: 2 additions & 2 deletions docs/core/howto/tutorial/listings/finger/finger19a.tac
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Do everything properly, and componentize
import cgi
import html

from zope.interface import Interface, implementer

Expand Down Expand Up @@ -179,7 +179,7 @@ class UserStatus(resource.Resource):

def render_GET(self, request):
d = self.service.getUser(self.user)
d.addCallback(cgi.escape)
d.addCallback(html.escape)
d.addCallback(lambda m: "<h1>%s</h1>" % self.user + "<p>%s</p>" % m)
d.addCallback(request.write)
d.addCallback(lambda _: request.finish())
Expand Down
4 changes: 2 additions & 2 deletions docs/core/howto/tutorial/listings/finger/finger19b.tac
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Do everything properly, and componentize
import cgi
import html
import pwd

from zope.interface import Interface, implementer
Expand Down Expand Up @@ -205,7 +205,7 @@ class UserStatus(resource.Resource):

def render_GET(self, request):
d = self.service.getUser(self.user)
d.addCallback(cgi.escape)
d.addCallback(html.escape)
d.addCallback(lambda m: "<h1>%s</h1>" % self.user + "<p>%s</p>" % m)
d.addCallback(request.write)
d.addCallback(lambda _: request.finish())
Expand Down
4 changes: 2 additions & 2 deletions docs/core/howto/tutorial/listings/finger/finger19c.tac
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Do everything properly, and componentize
import cgi
import html
import os
import pwd

Expand Down Expand Up @@ -206,7 +206,7 @@ class UserStatus(resource.Resource):

def render_GET(self, request):
d = self.service.getUser(self.user)
d.addCallback(cgi.escape)
d.addCallback(html.escape)
d.addCallback(lambda m: "<h1>%s</h1>" % self.user + "<p>%s</p>" % m)
d.addCallback(request.write)
d.addCallback(lambda _: request.finish())
Expand Down
2 changes: 0 additions & 2 deletions docs/core/howto/tutorial/listings/finger/finger20.tac
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
# Do everything properly, and componentize
import cgi

from zope.interface import Interface, implementer

from twisted.application import internet, service, strports
Expand Down
2 changes: 0 additions & 2 deletions docs/core/howto/tutorial/listings/finger/finger21.tac
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
# Do everything properly, and componentize
import cgi

from zope.interface import Interface, implementer

from twisted.application import internet, service, strports
Expand Down
2 changes: 0 additions & 2 deletions docs/core/howto/tutorial/listings/finger/finger22.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
# Do everything properly, and componentize
import cgi

from zope.interface import Interface, implementer

from OpenSSL import SSL
Expand Down
12 changes: 6 additions & 6 deletions docs/web/howto/web-in-60/handling-posts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ understand the possible negative consequences.


As usual, we start with some imports. In addition to the Twisted imports,
this example uses the ``cgi`` module to `escape user-enteredcontent <http://en.wikipedia.org/wiki/Cross-site_scripting>`_ for inclusion in the output.
this example uses the ``html`` module to `escape user-enteredcontent <http://en.wikipedia.org/wiki/Cross-site_scripting>`_ for inclusion in the output.



Expand All @@ -44,7 +44,7 @@ this example uses the ``cgi`` module to `escape user-enteredcontent <http://en.w
from twisted.web.resource import Resource
from twisted.internet import reactor, endpoints
import cgi
import html
Expand Down Expand Up @@ -82,7 +82,7 @@ method will allow it to accept ``POST`` requests:
...
def render_POST(self, request):
args = request.args[b"the-field"][0].decode("utf-8")
escapedArgs = cgi.escape(args)
escapedArgs = html.escape(args)
return (b"<!DOCTYPE html><html><head><meta charset='utf-8'>"
b"<title></title></head><body>"
b"You submitted: " + escapedArgs.encode('utf-8'))
Expand All @@ -96,7 +96,7 @@ provides access to the contents of the form. The keys in this
dictionary are the names of inputs in the form. Each value is a list
containing bytes objects (since there can be multiple inputs with the same
name), which is why we had to extract the first element to pass
to ``cgi.escape`` . ``request.args`` will be
to ``html.escape`` . ``request.args`` will be
populated from form contents whenever a ``POST`` request is
made with a content type
of ``application/x-www-form-urlencoded``
Expand Down Expand Up @@ -146,7 +146,7 @@ Here's the complete source for the example:
from twisted.web.resource import Resource
from twisted.internet import reactor, endpoints
import cgi
import html
class FormPage(Resource):
def render_GET(self, request):
Expand All @@ -156,7 +156,7 @@ Here's the complete source for the example:
def render_POST(self, request):
args = request.args[b"the-field"][0].decode("utf-8")
escapedArgs = cgi.escape(args)
escapedArgs = html.escape(args)
return (b"<!DOCTYPE html><html><head><meta charset='utf-8'>"
b"<title></title></head><body>"
b"You submitted: " + escapedArgs.encode('utf-8'))
Expand Down
6 changes: 3 additions & 3 deletions docs/web/howto/web-in-60/other-request-bodies.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ directly:
...
def render_POST(self, request):
content = request.content.read().decode("utf-8")
escapedContent = cgi.escape(content)
escapedContent = html.escape(content)
return (b"<!DOCTYPE html><html><head><meta charset='utf-8'>"
b"<title></title></head><body>"
b"You submitted: " +
Expand Down Expand Up @@ -68,7 +68,7 @@ only ``render_POST`` changed:
from twisted.web.resource import Resource
from twisted.internet import reactor, endpoints
import cgi
import html
class FormPage(Resource):
def render_GET(self, request):
Expand All @@ -78,7 +78,7 @@ only ``render_POST`` changed:
def render_POST(self, request):
content = request.content.read().decode("utf-8")
escapedContent = cgi.escape(content)
escapedContent = html.escape(content)
return (b"<!DOCTYPE html><html><head><meta charset='utf-8'>"
b"<title></title></head><body>"
b"You submitted: " +
Expand Down
17 changes: 11 additions & 6 deletions src/twisted/web/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
it, as in the HTTP 1.1 chunked I{Transfer-Encoding} (RFC 7230 section 4.1).
This limits how much data may be buffered when decoding the line.
"""
from __future__ import annotations

__all__ = [
"SWITCHING",
Expand Down Expand Up @@ -107,6 +108,7 @@
import tempfile
import time
import warnings
from email.message import EmailMessage
from io import BytesIO
from typing import AnyStr, Callable, List, Optional, Tuple
from urllib.parse import (
Expand Down Expand Up @@ -224,15 +226,18 @@
monthname_lower = [name and name.lower() for name in monthname]


def _parseHeader(line):
# cgi.parse_header requires a str
key, pdict = cgi.parse_header(line.decode("charmap"))
def _parseContentType(line: bytes) -> tuple[bytes, dict[str, bytes]]:
msg = EmailMessage()
msg["content-type"] = line.decode("charmap")

key = msg.get_content_type()
pdict = msg["content-type"].params

# We want the key as bytes, and cgi.parse_multipart (which consumes
# pdict) expects a dict of str keys but bytes values
key = key.encode("charmap")
encodedKey = key.encode("charmap")
pdict = {x: y.encode("charmap") for x, y in pdict.items()}
return (key, pdict)
return (encodedKey, pdict)


def urlparse(url):
Expand Down Expand Up @@ -973,7 +978,7 @@ def requestReceived(self, command, path, version):

if self.method == b"POST" and ctype and clength:
mfd = b"multipart/form-data"
key, pdict = _parseHeader(ctype)
key, pdict = _parseContentType(ctype)
# This weird CONTENT-LENGTH param is required by
# cgi.parse_multipart() in some versions of Python 3.7+, see
# bpo-29979. It looks like this will be relaxed and backported, see
Expand Down
1 change: 1 addition & 0 deletions src/twisted/web/newsfragments/12015.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Remove usage of cgi.escape and cgi.parse_header.
7 changes: 3 additions & 4 deletions src/twisted/web/test/test_cgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,8 @@
"""

URL_PARAMETER_CGI = """\
import cgi
fs = cgi.FieldStorage()
param = fs.getvalue("param")
import os
param = str(os.environ['QUERY_STRING'])
print("Header: OK")
print("")
print(param)
Expand Down Expand Up @@ -384,7 +383,7 @@ def test_urlParameters(self):
return d

def _test_urlParameters_1(self, res):
expected = f"1234{os.linesep}"
expected = f"param=1234{os.linesep}"
expected = expected.encode("ascii")
self.assertEqual(res, expected)

Expand Down

0 comments on commit ef5b35d

Please sign in to comment.