)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"1a0d1d73e7033f1506c93b4457ec2e8e14494970","unresolved":true,"context_lines":[{"line_number":9,"context_line":"Tests for the new swift.common.utils.pickle module:"},{"line_number":10,"context_line":""},{"line_number":11,"context_line":"- unpickle() refuses malicious payloads (os.system, subprocess.Popen,"},{"line_number":12,"context_line":"  eval, __import__, list, and unrelated swift classes)"},{"line_number":13,"context_line":"- write_pickle() output is loadable by unpickle()"},{"line_number":14,"context_line":"- unpickle() loads the allowlisted types (dict, bytes, HeaderKeyDict)"},{"line_number":15,"context_line":"  back to equal values, at both pickle protocol 0 and the default"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"8eb42fa6_97884c35","line":12,"range":{"start_line":12,"start_character":20,"end_line":12,"end_character":24},"updated":"2026-05-26 23:07:12.000000000","message":"I question how \"malicious\" this really is ;-)","commit_id":"ca4d98bde9c4dad244d84fa8db429f1812668557"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"88e45d1852e17dfe79428192150fee758e996907","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"22056cea_c8102ac2","updated":"2026-05-22 15:39:42.000000000","message":"@Christian thanks for this. I suggested some minor additions here https://review.opendev.org/c/openstack/swift/+/989785 sq? add to pickle tests\n\nIf Tim agrees then this could be squashed into the parent.","commit_id":"ca4d98bde9c4dad244d84fa8db429f1812668557"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"1a0d1d73e7033f1506c93b4457ec2e8e14494970","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"48b45648_1ad21a60","updated":"2026-05-26 23:07:12.000000000","message":"I\u0027ll squash in.","commit_id":"ca4d98bde9c4dad244d84fa8db429f1812668557"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3b9ce053cde6d4f2afea09afa9160ddd3f62a477","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"2d62de06_d5ce7b6c","updated":"2026-05-22 15:40:07.000000000","message":"pls squash my changes into this if you like them","commit_id":"ca4d98bde9c4dad244d84fa8db429f1812668557"}],"test/unit/common/utils/test_pickle.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"88e45d1852e17dfe79428192150fee758e996907","unresolved":true,"context_lines":[{"line_number":27,"context_line":""},{"line_number":28,"context_line":"class TestUnpickle(unittest.TestCase):"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"    def test_loads_allowlisted_types(self):"},{"line_number":31,"context_line":"        obj \u003d {"},{"line_number":32,"context_line":"            \u0027headers\u0027: HeaderKeyDict({\u0027X-Foo\u0027: \u0027bar\u0027}),"},{"line_number":33,"context_line":"            \u0027body\u0027: b\u0027\\x00\\xff\\xfe\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"a63e865a_b93327f0","line":30,"range":{"start_line":30,"start_character":19,"end_line":30,"end_character":30},"updated":"2026-05-22 15:39:42.000000000","message":"nit: typo \"allowlisted\"","commit_id":"ca4d98bde9c4dad244d84fa8db429f1812668557"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"88e45d1852e17dfe79428192150fee758e996907","unresolved":true,"context_lines":[{"line_number":31,"context_line":"        obj \u003d {"},{"line_number":32,"context_line":"            \u0027headers\u0027: HeaderKeyDict({\u0027X-Foo\u0027: \u0027bar\u0027}),"},{"line_number":33,"context_line":"            \u0027body\u0027: b\u0027\\x00\\xff\\xfe\u0027,"},{"line_number":34,"context_line":"            \u0027count\u0027: 3,"},{"line_number":35,"context_line":"        }"},{"line_number":36,"context_line":"        # proto 0 (Swift\u0027s on-disk default) and the pickle default"},{"line_number":37,"context_line":"        # reach for different globals — exercise both."}],"source_content_type":"text/x-python","patch_set":2,"id":"a7e71842_52aecf0b","line":34,"updated":"2026-05-22 15:39:42.000000000","message":"nit: we could include some other types that are allowed e.g. int float bool\n\nnested dicts would also be interesting","commit_id":"ca4d98bde9c4dad244d84fa8db429f1812668557"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"1a0d1d73e7033f1506c93b4457ec2e8e14494970","unresolved":true,"context_lines":[{"line_number":33,"context_line":"            \u0027body\u0027: b\u0027\\x00\\xff\\xfe\u0027,"},{"line_number":34,"context_line":"            \u0027count\u0027: 3,"},{"line_number":35,"context_line":"        }"},{"line_number":36,"context_line":"        # proto 0 (Swift\u0027s on-disk default) and the pickle default"},{"line_number":37,"context_line":"        # reach for different globals — exercise both."},{"line_number":38,"context_line":"        for protocol in (0, pickle.DEFAULT_PROTOCOL):"},{"line_number":39,"context_line":"            with self.subTest(protocol\u003dprotocol):"}],"source_content_type":"text/x-python","patch_set":2,"id":"b80494a6_530f18b0","line":36,"range":{"start_line":36,"start_character":10,"end_line":36,"end_character":43},"updated":"2026-05-26 23:07:12.000000000","message":"That\u0027s the default for `write_pickle`, but there\u0027s an [awful](https://github.com/openstack/swift/blob/2.37.1/swift/obj/diskfile.py#L80) [lot](https://github.com/openstack/swift/blob/2.37.1/swift/common/db.py#L48) of [code](https://github.com/openstack/swift/blob/2.37.1/swift/obj/server.py#L1387) that explicitly writes with `protocol\u003d2` (introduced in python 2.3, highest version supported by py2).","commit_id":"ca4d98bde9c4dad244d84fa8db429f1812668557"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"1a0d1d73e7033f1506c93b4457ec2e8e14494970","unresolved":true,"context_lines":[{"line_number":35,"context_line":"        }"},{"line_number":36,"context_line":"        # proto 0 (Swift\u0027s on-disk default) and the pickle default"},{"line_number":37,"context_line":"        # reach for different globals — exercise both."},{"line_number":38,"context_line":"        for protocol in (0, pickle.DEFAULT_PROTOCOL):"},{"line_number":39,"context_line":"            with self.subTest(protocol\u003dprotocol):"},{"line_number":40,"context_line":"                restored \u003d unpickle(pickle.dumps(obj, protocol\u003dprotocol))"},{"line_number":41,"context_line":"                self.assertEqual(obj, restored)"}],"source_content_type":"text/x-python","patch_set":2,"id":"f9496f8c_7e696f21","line":38,"range":{"start_line":38,"start_character":28,"end_line":38,"end_character":51},"updated":"2026-05-26 23:07:12.000000000","message":"Do we ever actually use the default version? Seems risky for rolling upgrades (or worse, needing to roll *back* from a failed upgrade) -- I thought that was why we specified 2 in so many places.\n\nAlso, I\u0027m not so sure about the wisdom of testing a single protocol number that changes from version to version -- looking at our current Python support matrix, this could be 3, 4, or 5.\n\nWhat do we think about something more like\n```\nfor protocol in range(pickle.HIGHEST_PROTOCOL + 1):\n```\n?","commit_id":"ca4d98bde9c4dad244d84fa8db429f1812668557"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"88e45d1852e17dfe79428192150fee758e996907","unresolved":true,"context_lines":[{"line_number":80,"context_line":"    def test_writes_loadable_pickle(self):"},{"line_number":81,"context_line":"        dest \u003d os.path.join(self.tmpdir, \u0027sub\u0027, \u0027obj.pkl\u0027)"},{"line_number":82,"context_line":"        obj \u003d {\u0027headers\u0027: HeaderKeyDict({\u0027X-Foo\u0027: \u0027bar\u0027}),"},{"line_number":83,"context_line":"               \u0027body\u0027: b\u0027\\xff\u0027}"},{"line_number":84,"context_line":"        write_pickle(obj, dest)"},{"line_number":85,"context_line":"        with open(dest, \u0027rb\u0027) as fp:"},{"line_number":86,"context_line":"            restored \u003d unpickle(fp.read())"}],"source_content_type":"text/x-python","patch_set":2,"id":"0d411f81_6f6288a7","line":83,"updated":"2026-05-22 15:39:42.000000000","message":"It would be nice to include a nested dict with disallowed types","commit_id":"ca4d98bde9c4dad244d84fa8db429f1812668557"}]}
