From 9a8facd7042f9fc93b0e1e1c3eea38fa0a6c3147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edwin=20T=C3=B6r=C3=B6k?= Date: Tue, 16 Jan 2024 23:32:13 +0000 Subject: [PATCH] Avoid infinite loop in lexer on unclosed code block MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An unclosed code block will cause the lexer to loop infinitely in the 'block' rule, because 'eof' is part of the 'eol' rule and it'll keep matching the last rule. Add a separate rule for eof that terminates immediately, the way the first rule was written it would expect closing quotes after eof which would never match eof. Signed-off-by: Edwin Török --- lib/lexer_mdx.mll | 3 ++- test/bin/mdx-test/expect/dune.inc | 12 ++++++++++++ test/bin/mdx-test/expect/unclosed-block/test-case.md | 7 +++++++ .../expect/unclosed-block/test-case.md.expected | 8 ++++++++ 4 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 test/bin/mdx-test/expect/unclosed-block/test-case.md create mode 100644 test/bin/mdx-test/expect/unclosed-block/test-case.md.expected diff --git a/lib/lexer_mdx.mll b/lib/lexer_mdx.mll index 683abc818..960d087f4 100644 --- a/lib/lexer_mdx.mll +++ b/lib/lexer_mdx.mll @@ -56,7 +56,8 @@ rule text section = parse `Text str :: text section lexbuf } and block = parse - | eof | ws* as end_pad "```" ws* eol + | eof { [""] } + | ws* as end_pad "```" ws* eol { newline lexbuf; [end_pad] } | ([^'\n']* as str) eol diff --git a/test/bin/mdx-test/expect/dune.inc b/test/bin/mdx-test/expect/dune.inc index f489a3e2e..82bdf5887 100644 --- a/test/bin/mdx-test/expect/dune.inc +++ b/test/bin/mdx-test/expect/dune.inc @@ -575,6 +575,18 @@ (alias runtest) (action (diff trailing-whitespaces/test-case.md.expected trailing-whitespaces.actual))) +(rule + (target unclosed-block.actual) + (deps (package mdx) (source_tree unclosed-block)) + (action + (with-stdout-to %{target} + (chdir unclosed-block + (run ocaml-mdx test --output - test-case.md))))) + +(rule + (alias runtest) + (action (diff unclosed-block/test-case.md.expected unclosed-block.actual))) + (rule (target warnings.actual) (deps (package mdx) (source_tree warnings)) diff --git a/test/bin/mdx-test/expect/unclosed-block/test-case.md b/test/bin/mdx-test/expect/unclosed-block/test-case.md new file mode 100644 index 000000000..3b1b42a10 --- /dev/null +++ b/test/bin/mdx-test/expect/unclosed-block/test-case.md @@ -0,0 +1,7 @@ +Here is a good block: + +```ocaml +``` + +And here is one that is not closed, this should not cause an infinite loop in the lexer: +``` diff --git a/test/bin/mdx-test/expect/unclosed-block/test-case.md.expected b/test/bin/mdx-test/expect/unclosed-block/test-case.md.expected new file mode 100644 index 000000000..14a4ff194 --- /dev/null +++ b/test/bin/mdx-test/expect/unclosed-block/test-case.md.expected @@ -0,0 +1,8 @@ +Here is a good block: + +```ocaml +``` + +And here is one that is not closed, this should not cause an infinite loop in the lexer: +``` +```