From 1fb06bbc10a7bd621c694a33137cf16b23b07a02 Mon Sep 17 00:00:00 2001 From: Sam Bull Date: Sun, 6 Aug 2023 00:33:16 +0100 Subject: [PATCH] Fix error pointer on linebreaks (#7480) Fixes #7468. --- CHANGES/7468.bugfix | 1 + aiohttp/_http_parser.pyx | 4 ++-- tests/test_http_parser.py | 22 +++++++++++++++++++++- 3 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 CHANGES/7468.bugfix diff --git a/CHANGES/7468.bugfix b/CHANGES/7468.bugfix new file mode 100644 index 00000000000..3f9c256ca0c --- /dev/null +++ b/CHANGES/7468.bugfix @@ -0,0 +1 @@ +Fixed output of parsing errors on `\n`. -- by :user:`Dreamsorcerer` diff --git a/aiohttp/_http_parser.pyx b/aiohttp/_http_parser.pyx index 4f39dd0c978..8b7d48245d2 100644 --- a/aiohttp/_http_parser.pyx +++ b/aiohttp/_http_parser.pyx @@ -548,8 +548,8 @@ cdef class HttpParser: else: after = cparser.llhttp_get_error_pos(self._cparser) before = data[:after - self.py_buf.buf] - after_b = after.split(b"\n", 1)[0] - before = before.rsplit(b"\n", 1)[-1] + after_b = after.split(b"\r\n", 1)[0] + before = before.rsplit(b"\r\n", 1)[-1] data = before + after_b pointer = " " * (len(repr(before))-1) + "^" ex = parser_error_from_errno(self._cparser, data, pointer) diff --git a/tests/test_http_parser.py b/tests/test_http_parser.py index 8113fb94dd1..18706a3bae2 100644 --- a/tests/test_http_parser.py +++ b/tests/test_http_parser.py @@ -131,7 +131,27 @@ def test_invalid_character(loop: Any, protocol: Any, request: Any) -> None: error_detail = re.escape( r""": - b'Set-Cookie: abc\x01def\r' + b'Set-Cookie: abc\x01def' + ^""" + ) + with pytest.raises(http_exceptions.BadHttpMessage, match=error_detail): + parser.feed_data(text) + + +@pytest.mark.skipif(NO_EXTENSIONS, reason="Only tests C parser.") +def test_invalid_linebreak(loop: Any, protocol: Any, request: Any) -> None: + parser = HttpRequestParserC( + protocol, + loop, + 2**16, + max_line_size=8190, + max_field_size=8190, + ) + text = b"GET /world HTTP/1.1\r\nHost: 127.0.0.1\n\r\n" + error_detail = re.escape( + r""": + + b'Host: 127.0.0.1\n' ^""" ) with pytest.raises(http_exceptions.BadHttpMessage, match=error_detail):