  
          template = self.engine.get_template('template_backends/csrf.html')
          content = template.render(request=request)
  
          expected = (
              '<input type="hidden" name="csrfmiddlewaretoken" '
              'value="{}" />'.format(get_token(request)))
  
          self.assertHTMLEqual(content, expected)
  
      def test_no_directory_traversal(self):
          with self.assertRaises(TemplateDoesNotExist):
              self.engine.get_template('../forbidden/template_backends/hello.html')
  
 
</s> remove     CSRF_KEY_LENGTH, CsrfViewMiddleware, get_token,
 </s> add     CSRF_TOKEN_LENGTH, CsrfViewMiddleware,
    _compare_salted_tokens as equivalent_tokens, get_token, </s> remove         self.assertEqual(len(csrf_cookie.value), CSRF_KEY_LENGTH)
 </s> add         self.assertEqual(len(csrf_cookie.value), CSRF_TOKEN_LENGTH)

    def test_process_view_token_invalid_chars(self):
        """
        If the token contains non-alphanumeric characters, it is ignored and a
        new token is created.
        """
        token = ('!@#' + self._csrf_id)[:CSRF_TOKEN_LENGTH]
        req = self._get_GET_no_csrf_cookie_request()
        req.COOKIES[settings.CSRF_COOKIE_NAME] = token
        CsrfViewMiddleware().process_view(req, token_view, (), {})
        resp = token_view(req)
        resp2 = CsrfViewMiddleware().process_response(req, resp)
        csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, False)
        self.assertEqual(len(csrf_cookie.value), CSRF_TOKEN_LENGTH)
        self.assertNotEqual(csrf_cookie.value, token)

    def test_process_view_token_invalid_bytes(self):
        """
        If the token contains improperly encoded unicode, it is ignored and a
        new token is created.
        """
        token = (b"<1>\xc2\xa1" + force_bytes(self._csrf_id, 'ascii'))[:CSRF_TOKEN_LENGTH]
        req = self._get_GET_no_csrf_cookie_request()
        req.COOKIES[settings.CSRF_COOKIE_NAME] = token
        # We expect a UnicodeWarning here, because we used broken utf-8 on purpose
        with warnings.catch_warnings():
            warnings.filterwarnings("ignore", category=UnicodeWarning)
            CsrfViewMiddleware().process_view(req, token_view, (), {})
        resp = token_view(req)
        resp2 = CsrfViewMiddleware().process_response(req, resp)
        csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, False)
        self.assertEqual(len(csrf_cookie.value), CSRF_TOKEN_LENGTH)
        self.assertNotEqual(csrf_cookie.value, token) </s> remove    outgoing POST forms.  The value of this field is the value of the CSRF
   cookie.
 </s> add    outgoing POST forms. The value of this field is, again, the value of the
   secret, with a salt which is both added to it and used to scramble it. The
   salt is regenerated on every call to ``get_token()`` so that the form field
   value is changed in every such response. </s> remove         response.csrf_processing_done = True
 </s> add         response.csrf_cookie_set = True
        expected = '<input type="hidden" name="csrfmiddlewaretoken" value="([^"]+)" />'
        match = re.match(expected, content) or re.match(expected.replace('"', "'"), content)
        self.assertTrue(match, "hidden csrftoken field not found in output")
        self.assertTrue(equivalent_tokens(match.group(1), get_token(request)))
  
          template = self.engine.get_template('template_backends/csrf.html')
          content = template.render(request=request)
  
        expected = '<input type="hidden" name="csrfmiddlewaretoken" value="([^"]+)" />'
        match = re.match(expected, content) or re.match(expected.replace('"', "'"), content)
        self.assertTrue(match, "hidden csrftoken field not found in output")
        self.assertTrue(equivalent_tokens(match.group(1), get_token(request)))
        expected = '<input type="hidden" name="csrfmiddlewaretoken" value="([^"]+)" />'
        match = re.match(expected, content) or re.match(expected.replace('"', "'"), content)
        self.assertTrue(match, "hidden csrftoken field not found in output")
        self.assertTrue(equivalent_tokens(match.group(1), get_token(request)))
        expected = '<input type="hidden" name="csrfmiddlewaretoken" value="([^"]+)" />'
        match = re.match(expected, content) or re.match(expected.replace('"', "'"), content)
        self.assertTrue(match, "hidden csrftoken field not found in output")
        self.assertTrue(equivalent_tokens(match.group(1), get_token(request)))
        expected = '<input type="hidden" name="csrfmiddlewaretoken" value="([^"]+)" />'
        match = re.match(expected, content) or re.match(expected.replace('"', "'"), content)
        self.assertTrue(match, "hidden csrftoken field not found in output")
        self.assertTrue(equivalent_tokens(match.group(1), get_token(request)))
        expected = '<input type="hidden" name="csrfmiddlewaretoken" value="([^"]+)" />'
        match = re.match(expected, content) or re.match(expected.replace('"', "'"), content)
        self.assertTrue(match, "hidden csrftoken field not found in output")
        self.assertTrue(equivalent_tokens(match.group(1), get_token(request)))
  
      def test_no_directory_traversal(self):
          with self.assertRaises(TemplateDoesNotExist):
              self.engine.get_template('../forbidden/template_backends/hello.html')
  
keep keep keep keep replace replace replace replace replace keep keep keep keep keep
 Fixed #20869 -- made CSRF tokens change every request by salt-encrypting them

Note that the cookie is not changed every request, just the token retrieved
by the `get_token()` method (used also by the `{% csrf_token %}` tag).

While at it, made token validation strict: Where, before, any length was
accepted and non-ASCII chars were ignored, we now treat anything other than
`[A-Za-z0-9]{64}` as invalid (except for 32-char tokens, which, for
backwards-compatibility, are accepted and replaced by 64-char ones).

Thanks Trac user patrys for reporting, github user adambrenecki
for initial patch, Tim Graham for help, and Curtis Maloney,
Collin Anderson, Florian Apolloner, Markus Holtermann & Jon Dufresne
for reviews. 
tests/template_backends/test_dummy.py