)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":38562,"name":"Richard Cruise","email":"rcruise@redhat.com","username":"rcruise"},"change_message_id":"0961fba1485cf06975a8a717818ecf4ba7a75cf8","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"d9a7b796_af1f40d2","updated":"2026-08-05 16:07:02.000000000","message":"LGTM","commit_id":"3d1873843103f855558254e4ecccd9a0591a7e3c"},{"author":{"_account_id":38360,"name":"Zachary Mark Raines","display_name":"Zachary Raines","email":"zachary.raines@canonical.com","username":"raineszm","status":"Sustaining Engineer @ Canonical"},"change_message_id":"7a31f6135761eaa61fbc74f9a500859e0dba4d5c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"3087a170_ba4642fd","updated":"2026-08-05 14:51:13.000000000","message":"One question about implementation approach.","commit_id":"3d1873843103f855558254e4ecccd9a0591a7e3c"},{"author":{"_account_id":34451,"name":"Fernando Royo","email":"froyo@redhat.com","username":"froyo"},"change_message_id":"ca1aa8b8735d2f56549eca4e323e70301f10ed3e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"1aed8ae3_c82b400d","updated":"2026-08-03 15:02:31.000000000","message":"lgtm","commit_id":"3d1873843103f855558254e4ecccd9a0591a7e3c"},{"author":{"_account_id":29244,"name":"Gregory Thiemonge","email":"gthiemon@redhat.com","username":"gthiemonge"},"change_message_id":"e38cf4aedca555ae5b375afd65bfa6bc577e6cc0","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"59038494_f8d48e55","updated":"2026-08-10 07:29:45.000000000","message":"recheck bug with pip and anubis","commit_id":"bad7074621562d90a38be4639c1ab3e245f5bf39"}],"octavia/common/jinja/haproxy/combined_listeners/jinja_cfg.py":[{"author":{"_account_id":34451,"name":"Fernando Royo","email":"froyo@redhat.com","username":"froyo"},"change_message_id":"dcca0b82aecd81da92c4f149a5e13a93a4060856","unresolved":true,"context_lines":[{"line_number":518,"context_line":""},{"line_number":519,"context_line":"    @staticmethod"},{"line_number":520,"context_line":"    def _sanitize_url(value, field_name, obj_id):"},{"line_number":521,"context_line":"        if value and validate.INVALID_URL_CHARS_RE.search(value):"},{"line_number":522,"context_line":"            LOG.warning(\"L7policy %s has invalid %s in DB, clearing\","},{"line_number":523,"context_line":"                        obj_id, field_name)"},{"line_number":524,"context_line":"            return None"}],"source_content_type":"text/x-python","patch_set":1,"id":"3e95a3c4_fefcda08","line":521,"range":{"start_line":521,"start_character":21,"end_line":521,"end_character":29},"updated":"2026-08-03 08:51:57.000000000","message":"Some import missing will fail on this (validate and LOG).  Indeed zuul already red on this ;)","commit_id":"abbfcf2fe51f92207e3bc06b5013502172ed71e7"},{"author":{"_account_id":29244,"name":"Gregory Thiemonge","email":"gthiemon@redhat.com","username":"gthiemonge"},"change_message_id":"af7403dfda625a8407b3ecc8b44bcde7f0dea974","unresolved":true,"context_lines":[{"line_number":518,"context_line":""},{"line_number":519,"context_line":"    @staticmethod"},{"line_number":520,"context_line":"    def _sanitize_url(value, field_name, obj_id):"},{"line_number":521,"context_line":"        if value and validate.INVALID_URL_CHARS_RE.search(value):"},{"line_number":522,"context_line":"            LOG.warning(\"L7policy %s has invalid %s in DB, clearing\","},{"line_number":523,"context_line":"                        obj_id, field_name)"},{"line_number":524,"context_line":"            return None"}],"source_content_type":"text/x-python","patch_set":1,"id":"6844dfbd_93fb603e","line":521,"range":{"start_line":521,"start_character":21,"end_line":521,"end_character":29},"in_reply_to":"3e95a3c4_fefcda08","updated":"2026-08-03 08:59:46.000000000","message":"thanks, I\u0027ll fix it, this patch was on a branch with a 2nd patch, I decided to not create a patchchain, so I isolated the patches, that probably explain it.\nMaybe I should put them back in the chain as they update the same files","commit_id":"abbfcf2fe51f92207e3bc06b5013502172ed71e7"}],"octavia/common/validate.py":[{"author":{"_account_id":38360,"name":"Zachary Mark Raines","display_name":"Zachary Raines","email":"zachary.raines@canonical.com","username":"raineszm","status":"Sustaining Engineer @ Canonical"},"change_message_id":"7a31f6135761eaa61fbc74f9a500859e0dba4d5c","unresolved":true,"context_lines":[{"line_number":41,"context_line":"_ListenerPUT \u003d \u0027octavia.api.v2.types.listener.ListenerPUT\u0027"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"# Reject control characters and spaces in URLs before passing to rfc3986."},{"line_number":45,"context_line":"# The rfc3986 library encodes these (e.g. \\n -\u003e %0A) before validating, so"},{"line_number":46,"context_line":"# they pass structural validation, but Octavia stores the raw input which"},{"line_number":47,"context_line":"# ends up in HAProxy config files — allowing config injection via newlines."}],"source_content_type":"text/x-python","patch_set":3,"id":"0a1fc030_a357d50d","line":44,"updated":"2026-08-05 14:51:13.000000000","message":"What is the benefit of storing the raw input and filtering like this, instead of using rfc3986.normalize_uri before storing?","commit_id":"3d1873843103f855558254e4ecccd9a0591a7e3c"},{"author":{"_account_id":29244,"name":"Gregory Thiemonge","email":"gthiemon@redhat.com","username":"gthiemonge"},"change_message_id":"449f5b81c4d337a79fcc1a71bc285a8c274cf7d2","unresolved":true,"context_lines":[{"line_number":41,"context_line":"_ListenerPUT \u003d \u0027octavia.api.v2.types.listener.ListenerPUT\u0027"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"# Reject control characters and spaces in URLs before passing to rfc3986."},{"line_number":45,"context_line":"# The rfc3986 library encodes these (e.g. \\n -\u003e %0A) before validating, so"},{"line_number":46,"context_line":"# they pass structural validation, but Octavia stores the raw input which"},{"line_number":47,"context_line":"# ends up in HAProxy config files — allowing config injection via newlines."}],"source_content_type":"text/x-python","patch_set":3,"id":"bef4acd9_75bfb437","line":44,"in_reply_to":"0a1fc030_a357d50d","updated":"2026-08-05 14:58:32.000000000","message":"good point, IMHO Octavia should not normalize (especially the spaces) what the user passes to the API, but it should reject it, however I found out that rfc3986.validators doesn\u0027t really validates, but it normalizes then validates, so it doesn\u0027t reject invalid URLs.","commit_id":"3d1873843103f855558254e4ecccd9a0591a7e3c"}]}
