)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"0a738ad1385f702dc29b07beef50503f6aed869a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"04c15ed4_eb624555","updated":"2026-08-24 17:20:29.000000000","message":"Please see my inline comment","commit_id":"e411fd8f1037959c7fd736c5f12cc91527fbc5ed"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"21812f9a65ce34f70e7dd686bf9d66aaeb2838ea","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"2bfe565a_36ee62bd","updated":"2026-08-25 18:23:24.000000000","message":"recheck https://zuul.opendev.org/t/openstack/build/31e71681960b47b5800c2b9c2a1984ff does not seem to be related","commit_id":"2c295af948aa3697b1db45d28497d4b051185ccc"}],"swift/common/middleware/s3api/controllers/multi_upload.py":[{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"0a738ad1385f702dc29b07beef50503f6aed869a","unresolved":true,"context_lines":[{"line_number":169,"context_line":"    # NB: deliberately stricter than int(), which would accept things like"},{"line_number":170,"context_line":"    # \u00271_0\u0027 and unicode digits. Leading zeros are dropped in the pattern:"},{"line_number":171,"context_line":"    # AWS ignores any number of them, but they count towards int()\u0027s limit"},{"line_number":172,"context_line":"    match \u003d re.match(\u0027^([-+]?)0*([0-9]+)$\u0027, value)"},{"line_number":173,"context_line":"    if not match:"},{"line_number":174,"context_line":"        raise invalid()"},{"line_number":175,"context_line":"    sign, digits \u003d match.groups()"}],"source_content_type":"text/x-python","patch_set":1,"id":"26821951_305570e8","line":172,"updated":"2026-08-24 17:20:29.000000000","message":"This new regex has a backtracking issue, similar to the CVE we fixed a few weeks ago (https://review.opendev.org/c/openstack/swift/+/998950) when parsing strings that contain zeros, like \"0000!\" (the latter requires 10 iterations until it fails).\n\n\nExample fix:\n\n```\nmatch \u003d re.match(\u0027^([-+]?)0*([1-9][0-9]*|0)$\u0027, value)\n```\n\nHere is a reproducer that compares the two regex:\n\n```\n#!/usr/bin/env python3\nimport re\nimport timeit\n\nPATTERNS \u003d {\u0027vulnerable\u0027: \u0027^([-+]?)0*([0-9]+)$\u0027,\n            \u0027fixed\u0027: \u0027^([-+]?)0*([1-9][0-9]*|0)$\u0027}\n\nprint(\u0027a header value that fails to match: \"0\" * n + \"!\"\u0027)\nprint(\u0027%8s %14s %14s\u0027 % (\u0027n\u0027, *PATTERNS))\nfor n in (1000, 2000, 4000, 8000, 16000):\n    value \u003d \u00270\u0027 * n + \u0027!\u0027\n    print(\u0027%8d %13.6fs %13.6fs\u0027 % (n, *(\n        timeit.timeit(\u0027regex.match(value)\u0027, number\u003d1,\n                      globals\u003d{\u0027regex\u0027: re.compile(p), \u0027value\u0027: value})\n        for p in PATTERNS.values())))\n\n```","commit_id":"e411fd8f1037959c7fd736c5f12cc91527fbc5ed"},{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"cc78dbc34f5df898f243d0482fe56e7f9e8b27e4","unresolved":true,"context_lines":[{"line_number":169,"context_line":"    # NB: deliberately stricter than int(), which would accept things like"},{"line_number":170,"context_line":"    # \u00271_0\u0027 and unicode digits. Leading zeros are dropped in the pattern:"},{"line_number":171,"context_line":"    # AWS ignores any number of them, but they count towards int()\u0027s limit"},{"line_number":172,"context_line":"    match \u003d re.match(\u0027^([-+]?)0*([0-9]+)$\u0027, value)"},{"line_number":173,"context_line":"    if not match:"},{"line_number":174,"context_line":"        raise invalid()"},{"line_number":175,"context_line":"    sign, digits \u003d match.groups()"}],"source_content_type":"text/x-python","patch_set":1,"id":"c7551402_7393bce8","line":172,"in_reply_to":"26821951_305570e8","updated":"2026-08-24 17:45:49.000000000","message":"Well, taking a step back - we mostly likely should not use a regex at all here to extract an int.\n\nHow about using `req.get_validated_param`? Yes, it\u0027s not as strict as the regex, but we already use it in multiple places.\n\nhttps://github.com/openstack/swift/blob/master/swift/common/middleware/s3api/s3request.py#L2352C9-L2375","commit_id":"e411fd8f1037959c7fd736c5f12cc91527fbc5ed"},{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"a5eddb4934e144878781b86c48f3b157d830320f","unresolved":true,"context_lines":[{"line_number":169,"context_line":"    # NB: deliberately stricter than int(), which would accept things like"},{"line_number":170,"context_line":"    # \u00271_0\u0027 and unicode digits. Leading zeros are dropped in the pattern:"},{"line_number":171,"context_line":"    # AWS ignores any number of them, but they count towards int()\u0027s limit"},{"line_number":172,"context_line":"    match \u003d re.match(\u0027^([-+]?)0*([0-9]+)$\u0027, value)"},{"line_number":173,"context_line":"    if not match:"},{"line_number":174,"context_line":"        raise invalid()"},{"line_number":175,"context_line":"    sign, digits \u003d match.groups()"}],"source_content_type":"text/x-python","patch_set":1,"id":"d02375f5_65a204a7","line":172,"in_reply_to":"c4f41b20_47873f28","updated":"2026-08-25 08:07:28.000000000","message":"\u003e I don\u0027t think that would be good enough since `req.get_validated_param` works with the request\u0027s query parameters and `x-amz-mp-object-size` is a header.\n\nYou\u0027re right! I was too fast on this one.\n\n\u003e Maybe these rules are too strict and lead us to adding a whole bunch of logic... maybe its a question of do we want to allow python-ic numbers like \u00271_000_000\u0027?\n\nSee my inline comment - you could make this more strict without using a regex.","commit_id":"e411fd8f1037959c7fd736c5f12cc91527fbc5ed"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"92ed8bd36c49c241569c0c51c35582582dd4cea5","unresolved":true,"context_lines":[{"line_number":169,"context_line":"    # NB: deliberately stricter than int(), which would accept things like"},{"line_number":170,"context_line":"    # \u00271_0\u0027 and unicode digits. Leading zeros are dropped in the pattern:"},{"line_number":171,"context_line":"    # AWS ignores any number of them, but they count towards int()\u0027s limit"},{"line_number":172,"context_line":"    match \u003d re.match(\u0027^([-+]?)0*([0-9]+)$\u0027, value)"},{"line_number":173,"context_line":"    if not match:"},{"line_number":174,"context_line":"        raise invalid()"},{"line_number":175,"context_line":"    sign, digits \u003d match.groups()"}],"source_content_type":"text/x-python","patch_set":1,"id":"c4f41b20_47873f28","line":172,"in_reply_to":"c7551402_7393bce8","updated":"2026-08-24 20:31:30.000000000","message":"I don\u0027t think that would be good enough since `req.get_validated_param` works with the request\u0027s query parameters and `x-amz-mp-object-size` is a header.\n\nMaybe these rules are too strict and lead us to adding a whole bunch of logic... maybe its a question of do we want to allow python-ic numbers like \u00271_000_000\u0027?\n\nI think perhaps we can just update the commit to note that we just take the number and parse it as an int() and see where to go from there.","commit_id":"e411fd8f1037959c7fd736c5f12cc91527fbc5ed"},{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"a5eddb4934e144878781b86c48f3b157d830320f","unresolved":true,"context_lines":[{"line_number":164,"context_line":"        return None"},{"line_number":165,"context_line":""},{"line_number":166,"context_line":"    invalid_message \u003d ("},{"line_number":167,"context_line":"        \"Value for x-amz-mp-object-size header is invalid: \u0027%s\u0027\" % value)"},{"line_number":168,"context_line":"    try:"},{"line_number":169,"context_line":"        expected_size \u003d int(value)"},{"line_number":170,"context_line":"    except ValueError:"}],"source_content_type":"text/x-python","patch_set":3,"id":"8e166b1d_9d4aae84","line":167,"updated":"2026-08-25 08:07:28.000000000","message":"If you want to be more strict, you could add this (similar too line 747/806 in this file):\n\n```\nif any(c not in \u00270123456789\u0027 for c in value.lstrip(\u0027+-\u0027)):\n    raise InvalidRequest(invalid_message)\n```\n\nI like generators, but there is an even faster version of this:\n```\nif value.lstrip(\u0027+-\u0027).strip(\u00270123456789\u0027):\n    raise InvalidRequest(invalid_message)\n```","commit_id":"c7b3b8980d5a9b74d512290cde452c9a28e398c8"},{"author":{"_account_id":39146,"name":"Nathaniel Martes","display_name":"Nate Martes","email":"nmartes@NVIDIA.com","username":"nmartes"},"change_message_id":"37748c0341536299bb0e9b1e868d9724f32ae2e5","unresolved":true,"context_lines":[{"line_number":164,"context_line":"        return None"},{"line_number":165,"context_line":""},{"line_number":166,"context_line":"    invalid_message \u003d ("},{"line_number":167,"context_line":"        \"Value for x-amz-mp-object-size header is invalid: \u0027%s\u0027\" % value)"},{"line_number":168,"context_line":"    try:"},{"line_number":169,"context_line":"        expected_size \u003d int(value)"},{"line_number":170,"context_line":"    except ValueError:"}],"source_content_type":"text/x-python","patch_set":3,"id":"e703304f_63746147","line":167,"in_reply_to":"8e166b1d_9d4aae84","updated":"2026-08-25 15:28:59.000000000","message":"I like this approach a lot actually of just stripping what is valid and anything leftover is just an error. Thanks will add!","commit_id":"c7b3b8980d5a9b74d512290cde452c9a28e398c8"}]}
