Code view:

A painting is a person's account of this edit as text, recorded independently of the node mapping - a rendering often has several equally defensible answers where the mapping has one. Deletions and insertions carry no position on the opposite side in a painting, so that panel draws no caret for them.

Before

1"""
2Cross Site Request Forgery Middleware.
3
4This module provides a middleware that implements protection
5against request forgeries from other sites.
6"""
7
8import hmac
9import logging
10import string
11from collections import defaultdict
12from urllib.parse import urlsplit
13
14from django.conf import settings
15from django.core.exceptions import DisallowedHost, ImproperlyConfigured
16from django.http import HttpHeaders, UnreadablePostError
17from django.urls import get_callable
18from django.utils.cache import patch_vary_headers
19from django.utils.crypto import get_random_string
20from django.utils.deprecation import MiddlewareMixin
21from django.utils.functional import cached_property
22from django.utils.http import is_same_domain
23from django.utils.log import log_response
24from django.utils.regex_helper import _lazy_re_compile
25
…lines 26–151 unchanged (126 lines)
152 length CSRF_TOKEN_LENGTH, it is a masked secret.
153 """
154 # Only unmask tokens that are exactly CSRF_TOKEN_LENGTH characters long.
155 if len(request_csrf_token) == CSRF_TOKEN_LENGTH:
156 request_csrf_token = _unmask_cipher_token(request_csrf_token)
157 assert len(request_csrf_token) == CSRF_SECRET_LENGTH
158 return hmac.compare_digest(request_csrf_token, csrf_secret)
159
160
161class RejectRequest(Exception):
162 def __init__(self, reason):
163 self.reason = reason
164
…lines 165–486 unchanged (322 lines)

After

1"""
2Cross Site Request Forgery Middleware.
3
4This module provides a middleware that implements protection
5against request forgeries from other sites.
6"""
7
8import logging
9import string
10from collections import defaultdict
11from urllib.parse import urlsplit
12
13from django.conf import settings
14from django.core.exceptions import DisallowedHost, ImproperlyConfigured
15from django.http import HttpHeaders, UnreadablePostError
16from django.urls import get_callable
17from django.utils.cache import patch_vary_headers
18from django.utils.crypto import constant_time_compare, get_random_string
19from django.utils.deprecation import MiddlewareMixin
20from django.utils.functional import cached_property
21from django.utils.http import is_same_domain
22from django.utils.log import log_response
23from django.utils.regex_helper import _lazy_re_compile
24
…lines 25–150 unchanged (126 lines)
151 length CSRF_TOKEN_LENGTH, it is a masked secret.
152 """
153 # Only unmask tokens that are exactly CSRF_TOKEN_LENGTH characters long.
154 if len(request_csrf_token) == CSRF_TOKEN_LENGTH:
155 request_csrf_token = _unmask_cipher_token(request_csrf_token)
156 assert len(request_csrf_token) == CSRF_SECRET_LENGTH
157 return constant_time_compare(request_csrf_token, csrf_secret)
158
159
160class RejectRequest(Exception):
161 def __init__(self, reason):
162 self.reason = reason
163
…lines 164–485 unchanged (322 lines)

Before

module
expression_statement
string
string_start "\"\"\""
string_content "\nCross Site Request Forgery Middleware.\n\nThis module provide"...
string_end "\"\"\""
import_statement
import "import"
dotted_name
identifier "hmac"
import_statement
import "import"
dotted_name
identifier "logging"
import_statement
import "import"
dotted_name
identifier "string"
import_from_statement
from "from"
dotted_name
identifier "collections"
import "import"
dotted_name
identifier "defaultdict"
import_from_statement
from "from"
dotted_name
identifier "urllib"
. "."
identifier "parse"
import "import"
dotted_name
identifier "urlsplit"
import_from_statement
from "from"
dotted_name
identifier "django"
. "."
identifier "conf"
import "import"
dotted_name
identifier "settings"
import_from_statement
from "from"
dotted_name
identifier "django"
. "."
identifier "core"
. "."
identifier "exceptions"
import "import"
dotted_name
identifier "DisallowedHost"
, ","
dotted_name
identifier "ImproperlyConfigured"
import_from_statement
from "from"
dotted_name
identifier "django"
. "."
identifier "http"
import "import"
dotted_name
identifier "HttpHeaders"
, ","
dotted_name
identifier "UnreadablePostError"
import_from_statement
from "from"
dotted_name
identifier "django"
. "."
identifier "urls"
import "import"
dotted_name
identifier "get_callable"
import_from_statement
from "from"
dotted_name
identifier "django"
. "."
identifier "utils"
. "."
identifier "cache"
import "import"
dotted_name
identifier "patch_vary_headers"
import_from_statement
from "from"
dotted_name
identifier "django"
. "."
identifier "utils"
. "."
identifier "crypto"
import "import"
dotted_name
identifier "get_random_string"
import_from_statement
from "from"
dotted_name
identifier "django"
. "."
identifier "utils"
. "."
identifier "deprecation"
import "import"
dotted_name
identifier "MiddlewareMixin"
import_from_statement
from "from"
dotted_name
identifier "django"
. "."
identifier "utils"
. "."
identifier "functional"
import "import"
dotted_name
identifier "cached_property"
import_from_statement
from "from"
dotted_name
identifier "django"
. "."
identifier "utils"
. "."
identifier "http"
import "import"
dotted_name
identifier "is_same_domain"
import_from_statement
from "from"
dotted_name
identifier "django"
. "."
identifier "utils"
. "."
identifier "log"
import "import"
dotted_name
identifier "log_response"
import_from_statement
from "from"
dotted_name
identifier "django"
. "."
identifier "utils"
. "."
identifier "regex_helper"
import "import"
dotted_name
identifier "_lazy_re_compile"
expression_statement
assignment
identifier "logger"
= "="
call
attribute
identifier "logging"
. "."
identifier "getLogger"
argument_list
( "("
string
string_start "\""
string_content "django.security.csrf"
string_end "\""
) ")"
comment "# This matches if any character is not in CSRF_ALLOWED_CHARS"...
expression_statement
assignment
identifier "invalid_token_chars_re"
= "="
call
identifier "_lazy_re_compile"
argument_list
( "("
string
string_start "\""
string_content "[^a-zA-Z0-9]"
string_end "\""
) ")"
expression_statement
assignment
identifier "REASON_BAD_ORIGIN"
= "="
string
string_start "\""
string_content "Origin checking failed - %s does not match any trusted origi"...
string_end "\""
expression_statement
assignment
identifier "REASON_NO_REFERER"
= "="
string
string_start "\""
string_content "Referer checking failed - no Referer."
string_end "\""
expression_statement
assignment
identifier "REASON_BAD_REFERER"
= "="
string
string_start "\""
string_content "Referer checking failed - %s does not match any trusted orig"...
string_end "\""
expression_statement
assignment
identifier "REASON_NO_CSRF_COOKIE"
= "="
string
string_start "\""
string_content "CSRF cookie not set."
string_end "\""
expression_statement
assignment
identifier "REASON_CSRF_TOKEN_MISSING"
= "="
string
string_start "\""
string_content "CSRF token missing."
string_end "\""
expression_statement
assignment
identifier "REASON_MALFORMED_REFERER"
= "="
string
string_start "\""
string_content "Referer checking failed - Referer is malformed."
string_end "\""
expression_statement
assignment
identifier "REASON_INSECURE_REFERER"
= "="
parenthesized_expression
( "("
string
string_start "\""
string_content "Referer checking failed - Referer is insecure while host is "...
string_end "\""
) ")"
comment "# The reason strings below are for passing to InvalidTokenFo"...
comment "# phrases without a subject because they can be in reference"...
comment "# cookie or non-cookie token."
expression_statement
assignment
identifier "REASON_INCORRECT_LENGTH"
= "="
string
string_start "\""
string_content "has incorrect length"
string_end "\""
expression_statement
assignment
identifier "REASON_INVALID_CHARACTERS"
= "="
string
string_start "\""
string_content "has invalid characters"
string_end "\""
expression_statement
assignment
identifier "CSRF_SECRET_LENGTH"
= "="
integer "32"
expression_statement
assignment
identifier "CSRF_TOKEN_LENGTH"
= "="
binary_operator
integer "2"
* "*"
identifier "CSRF_SECRET_LENGTH"
expression_statement
assignment
identifier "CSRF_ALLOWED_CHARS"
= "="
binary_operator
attribute
identifier "string"
. "."
identifier "ascii_letters"
+ "+"
attribute
identifier "string"
. "."
identifier "digits"
expression_statement
assignment
identifier "CSRF_SESSION_KEY"
= "="
string
string_start "\""
string_content "_csrftoken"
string_end "\""
function_definition (+24 nodes collapsed)
function_definition (+21 nodes collapsed)
function_definition (+119 nodes collapsed)
function_definition (+114 nodes collapsed)
function_definition (+57 nodes collapsed)
function_definition (+83 nodes collapsed)
function_definition (+21 nodes collapsed)
class_definition (+28 nodes collapsed)
function_definition (+64 nodes collapsed)
function_definition
def "def"
identifier "_does_token_match"
parameters
( "("
identifier "request_csrf_token"
, ","
identifier "csrf_secret"
) ")"
: ":"
block
expression_statement
string
string_start "\"\"\""
string_content "\n Return whether the given CSRF token matches the given C"...
string_end "\"\"\""
comment "# Only unmask tokens that are exactly CSRF_TOKEN_LENGTH char"...
if_statement (+23 nodes collapsed)
assert_statement
assert "assert"
comparison_operator
call
identifier "len"
argument_list
( "("
identifier "request_csrf_token"
) ")"
== "=="
identifier "CSRF_SECRET_LENGTH"
return_statement
return "return"
call
attribute
identifier "hmac"
. "."
identifier "compare_digest"
argument_list
( "("
identifier "request_csrf_token"
, ","
identifier "csrf_secret"
) ")"
class_definition (+28 nodes collapsed)
class_definition (+1922 nodes collapsed)

After

module
expression_statement
string
string_start "\"\"\""
string_content "\nCross Site Request Forgery Middleware.\n\nThis module provide"...
string_end "\"\"\""
import_statement
import "import"
dotted_name
identifier "logging"
import_statement
import "import"
dotted_name
identifier "string"
import_from_statement
from "from"
dotted_name
identifier "collections"
import "import"
dotted_name
identifier "defaultdict"
import_from_statement
from "from"
dotted_name
identifier "urllib"
. "."
identifier "parse"
import "import"
dotted_name
identifier "urlsplit"
import_from_statement
from "from"
dotted_name
identifier "django"
. "."
identifier "conf"
import "import"
dotted_name
identifier "settings"
import_from_statement
from "from"
dotted_name
identifier "django"
. "."
identifier "core"
. "."
identifier "exceptions"
import "import"
dotted_name
identifier "DisallowedHost"
, ","
dotted_name
identifier "ImproperlyConfigured"
import_from_statement
from "from"
dotted_name
identifier "django"
. "."
identifier "http"
import "import"
dotted_name
identifier "HttpHeaders"
, ","
dotted_name
identifier "UnreadablePostError"
import_from_statement
from "from"
dotted_name
identifier "django"
. "."
identifier "urls"
import "import"
dotted_name
identifier "get_callable"
import_from_statement
from "from"
dotted_name
identifier "django"
. "."
identifier "utils"
. "."
identifier "cache"
import "import"
dotted_name
identifier "patch_vary_headers"
import_from_statement
from "from"
dotted_name
identifier "django"
. "."
identifier "utils"
. "."
identifier "crypto"
import "import"
dotted_name
identifier "constant_time_compare"
, ","
dotted_name
identifier "get_random_string"
import_from_statement
from "from"
dotted_name
identifier "django"
. "."
identifier "utils"
. "."
identifier "deprecation"
import "import"
dotted_name
identifier "MiddlewareMixin"
import_from_statement
from "from"
dotted_name
identifier "django"
. "."
identifier "utils"
. "."
identifier "functional"
import "import"
dotted_name
identifier "cached_property"
import_from_statement
from "from"
dotted_name
identifier "django"
. "."
identifier "utils"
. "."
identifier "http"
import "import"
dotted_name
identifier "is_same_domain"
import_from_statement
from "from"
dotted_name
identifier "django"
. "."
identifier "utils"
. "."
identifier "log"
import "import"
dotted_name
identifier "log_response"
import_from_statement
from "from"
dotted_name
identifier "django"
. "."
identifier "utils"
. "."
identifier "regex_helper"
import "import"
dotted_name
identifier "_lazy_re_compile"
expression_statement
assignment
identifier "logger"
= "="
call
attribute
identifier "logging"
. "."
identifier "getLogger"
argument_list
( "("
string
string_start "\""
string_content "django.security.csrf"
string_end "\""
) ")"
comment "# This matches if any character is not in CSRF_ALLOWED_CHARS"...
expression_statement
assignment
identifier "invalid_token_chars_re"
= "="
call
identifier "_lazy_re_compile"
argument_list
( "("
string
string_start "\""
string_content "[^a-zA-Z0-9]"
string_end "\""
) ")"
expression_statement
assignment
identifier "REASON_BAD_ORIGIN"
= "="
string
string_start "\""
string_content "Origin checking failed - %s does not match any trusted origi"...
string_end "\""
expression_statement
assignment
identifier "REASON_NO_REFERER"
= "="
string
string_start "\""
string_content "Referer checking failed - no Referer."
string_end "\""
expression_statement
assignment
identifier "REASON_BAD_REFERER"
= "="
string
string_start "\""
string_content "Referer checking failed - %s does not match any trusted orig"...
string_end "\""
expression_statement
assignment
identifier "REASON_NO_CSRF_COOKIE"
= "="
string
string_start "\""
string_content "CSRF cookie not set."
string_end "\""
expression_statement
assignment
identifier "REASON_CSRF_TOKEN_MISSING"
= "="
string
string_start "\""
string_content "CSRF token missing."
string_end "\""
expression_statement
assignment
identifier "REASON_MALFORMED_REFERER"
= "="
string
string_start "\""
string_content "Referer checking failed - Referer is malformed."
string_end "\""
expression_statement
assignment
identifier "REASON_INSECURE_REFERER"
= "="
parenthesized_expression
( "("
string
string_start "\""
string_content "Referer checking failed - Referer is insecure while host is "...
string_end "\""
) ")"
comment "# The reason strings below are for passing to InvalidTokenFo"...
comment "# phrases without a subject because they can be in reference"...
comment "# cookie or non-cookie token."
expression_statement
assignment
identifier "REASON_INCORRECT_LENGTH"
= "="
string
string_start "\""
string_content "has incorrect length"
string_end "\""
expression_statement
assignment
identifier "REASON_INVALID_CHARACTERS"
= "="
string
string_start "\""
string_content "has invalid characters"
string_end "\""
expression_statement
assignment
identifier "CSRF_SECRET_LENGTH"
= "="
integer "32"
expression_statement
assignment
identifier "CSRF_TOKEN_LENGTH"
= "="
binary_operator
integer "2"
* "*"
identifier "CSRF_SECRET_LENGTH"
expression_statement
assignment
identifier "CSRF_ALLOWED_CHARS"
= "="
binary_operator
attribute
identifier "string"
. "."
identifier "ascii_letters"
+ "+"
attribute
identifier "string"
. "."
identifier "digits"
expression_statement
assignment
identifier "CSRF_SESSION_KEY"
= "="
string
string_start "\""
string_content "_csrftoken"
string_end "\""
function_definition (+24 nodes collapsed)
function_definition (+21 nodes collapsed)
function_definition (+119 nodes collapsed)
function_definition (+114 nodes collapsed)
function_definition (+57 nodes collapsed)
function_definition (+83 nodes collapsed)
function_definition (+21 nodes collapsed)
class_definition (+28 nodes collapsed)
function_definition (+64 nodes collapsed)
function_definition
def "def"
identifier "_does_token_match"
parameters
( "("
identifier "request_csrf_token"
, ","
identifier "csrf_secret"
) ")"
: ":"
block
expression_statement
string
string_start "\"\"\""
string_content "\n Return whether the given CSRF token matches the given C"...
string_end "\"\"\""
comment "# Only unmask tokens that are exactly CSRF_TOKEN_LENGTH char"...
if_statement (+23 nodes collapsed)
assert_statement
assert "assert"
comparison_operator
call
identifier "len"
argument_list
( "("
identifier "request_csrf_token"
) ")"
== "=="
identifier "CSRF_SECRET_LENGTH"
return_statement
return "return"
call
identifier "constant_time_compare"
argument_list
( "("
identifier "request_csrf_token"
, ","
identifier "csrf_secret"
) ")"
class_definition (+28 nodes collapsed)
class_definition (+1922 nodes collapsed)