Mercurial > p > roundup > code
diff test/rest_common.py @ 8268:05d8806b25ad
fix: issue2551387 - TypeError: not indexable.
Fix crash due to uninitialized list element on a (Mini)FieldStorage
when unexpected input is posted via wsgi. This doesn't happen when
running roundup-server. It might happen under other front ends.
Moved the code that sets '.list = [] if .list == None' to the main
flow. Added an exception hander that logs the value of self.form if
self.form.list raises an AttributeError. This exception should never
happen if I understand the code correctly (but I probably don't).
Fixed a number of test cases that were broken because I was calling
Client and passing '[]' rather than a cgi.formStorage object.
Added test cases:
create a FileStorage (self.form) with .list = None.
check AttributeError exception and verify logging.
Problem reported and debugged by Christof Meerwald.
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Sun, 12 Jan 2025 12:34:52 -0500 |
| parents | 8c1e0459b73d |
| children | 1ffa1f42e1da |
line wrap: on
line diff
--- a/test/rest_common.py Thu Jan 09 10:14:55 2025 -0500 +++ b/test/rest_common.py Sun Jan 12 12:34:52 2025 -0500 @@ -3,6 +3,7 @@ import shutil import sys import errno +import logging from time import sleep from datetime import datetime, timedelta @@ -76,6 +77,10 @@ class TestCase(): + @pytest.fixture(autouse=True) + def inject_fixtures(self, caplog): + self._caplog = caplog + backend = None url_pfx = 'http://tracker.example/cgi-bin/roundup.cgi/bugs/rest/data/' @@ -291,7 +296,8 @@ 'HTTP_ORIGIN': 'http://tracker.example' } self.dummy_client = client.Client(self.instance, MockNull(), - self.client_env, [], None) + self.client_env, + cgi.FieldStorage(), None) self.dummy_client.request.headers.get = self.get_header self.dummy_client.db = self.db @@ -2294,6 +2300,30 @@ self.assertNotIn("X-Content-Type-Options", self.server.client.additional_headers) + def testBadFormAttributeErrorException(self): + env = { + 'PATH_INFO': 'rest/data/user', + 'HTTP_HOST': 'localhost', + 'TRACKER_NAME': 'rounduptest', + "REQUEST_METHOD": "GET" + } + + + with self._caplog.at_level(logging.ERROR, logger="roundup"): + with self.assertRaises(AttributeError) as exc: + self.dummy_client = client.Client( + self.instance, MockNull(), env, [], None) + + self.assertEqual(exc.exception.args[0], + "'list' object has no attribute 'list'") + + # log should look like (with string not broken into parts): + # [('roundup', 40, + # 'Invalid self.form found (please report to the ' + # 'roundup-users mailing list): []')] + log = self._caplog.record_tuples[:] + self.assertIn("Invalid self.form found", log[0][2]) + def testDispatchBadAccept(self): # simulate: /rest/data/issue expect failure unknown accept settings body=b'{ "title": "Joe Doe has problems", \ @@ -4508,8 +4538,9 @@ 'TRACKER_NAME': 'rounduptest', "REQUEST_METHOD": "GET" } + self.dummy_client = client.Client(self.instance, MockNull(), env, - [], None) + cgi.FieldStorage(), None) self.dummy_client.db = self.db self.dummy_client.request.headers.get = self.get_header self.empty_form = cgi.FieldStorage() @@ -4517,7 +4548,6 @@ self.terse_form.list = [ cgi.MiniFieldStorage('@verbose', '0'), ] - self.dummy_client.form = cgi.FieldStorage() self.dummy_client.form.list = [ cgi.MiniFieldStorage('@fields', 'username,address'), ] @@ -4575,7 +4605,7 @@ ) self.dummy_client = client.Client(self.instance, MockNull(), env, - [], None) + cgi.FieldStorage(), None) self.dummy_client.db = self.db self.dummy_client.request.headers.get = self.get_header self.empty_form = cgi.FieldStorage() @@ -4645,7 +4675,7 @@ } self.dummy_client = client.Client(self.instance, MockNull(), env, - [], None) + cgi.FieldStorage(), None) self.dummy_client.db = self.db self.dummy_client.request.headers.get = self.get_header self.empty_form = cgi.FieldStorage() @@ -4710,7 +4740,7 @@ "REQUEST_METHOD": "GET" } self.dummy_client = client.Client(self.instance, MockNull(), env, - [], None) + cgi.FieldStorage(), None) self.dummy_client.db = self.db self.dummy_client.request.headers.get = self.get_header self.empty_form = cgi.FieldStorage() @@ -4781,7 +4811,7 @@ "REQUEST_METHOD": "GET" } self.dummy_client = client.Client(self.instance, MockNull(), env, - [], None) + cgi.FieldStorage(), None) self.dummy_client.db = self.db self.dummy_client.request.headers.get = self.get_header self.empty_form = cgi.FieldStorage() @@ -4849,7 +4879,7 @@ "REQUEST_METHOD": "GET" } self.dummy_client = client.Client(self.instance, MockNull(), env, - [], None) + cgi.FieldStorage(), None) self.dummy_client.db = self.db self.dummy_client.request.headers.get = self.get_header self.empty_form = cgi.FieldStorage() @@ -4891,7 +4921,7 @@ "REQUEST_METHOD": "GET" } self.dummy_client = client.Client(self.instance, MockNull(), env, - [], None) + cgi.FieldStorage(), None) self.dummy_client.db = self.db self.dummy_client.request.headers.get = self.get_header self.empty_form = cgi.FieldStorage() @@ -4930,7 +4960,7 @@ "REQUEST_METHOD": "GET" } self.dummy_client = client.Client(self.instance, MockNull(), env, - [], None) + cgi.FieldStorage(), None) self.dummy_client.db = self.db self.dummy_client.request.headers.get = self.get_header self.empty_form = cgi.FieldStorage() @@ -4966,7 +4996,7 @@ "REQUEST_METHOD": "GET" } self.dummy_client = client.Client(self.instance, MockNull(), env, - [], None) + cgi.FieldStorage(), None) self.dummy_client.db = self.db self.dummy_client.request.headers.get = self.get_header self.empty_form = cgi.FieldStorage() @@ -5003,7 +5033,7 @@ "REQUEST_METHOD": "GET" } self.dummy_client = client.Client(self.instance, MockNull(), env, - [], None) + cgi.FieldStorage(), None) self.dummy_client.db = self.db self.dummy_client.request.headers.get = self.get_header self.empty_form = cgi.FieldStorage() @@ -5039,7 +5069,7 @@ "REQUEST_METHOD": "GET" } self.dummy_client = client.Client(self.instance, MockNull(), env, - [], None) + cgi.FieldStorage(), None) self.dummy_client.db = self.db self.dummy_client.request.headers.get = self.get_header self.empty_form = cgi.FieldStorage()
