Skip to content

Commit 59dd61a

Browse files
authored
Merge pull request #33 from iamgio/codeblock-fix
Fix StackOverflowError on long code block
2 parents 475073f + e27fe46 commit 59dd61a

File tree

3 files changed

+134
-59
lines changed

3 files changed

+134
-59
lines changed

quarkdown-core/src/main/kotlin/com/quarkdown/core/lexer/patterns/BaseMarkdownBlockTokenRegexPatterns.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ open class BaseMarkdownBlockTokenRegexPatterns {
105105
name = "FencesCode",
106106
wrap = ::FencesCodeToken,
107107
regex =
108-
"^ {0,3}((?<fenceschar>[`~]){3,})($|\\s*.+$)((.|\\s)+?)(\\k<fenceschar>{3,})"
108+
"^ {0,3}((?<fenceschar>[`~]){3,})($|\\s*.+$)(?s)(.+?)(\\k<fenceschar>{3,})[ \\t]*$"
109109
.toRegex(),
110110
)
111111

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package com.quarkdown.test
2+
3+
import com.quarkdown.core.ast.attributes.presence.hasCode
4+
import com.quarkdown.test.util.execute
5+
import kotlin.test.Test
6+
import kotlin.test.assertEquals
7+
import kotlin.test.assertFalse
8+
import kotlin.test.assertTrue
9+
10+
/**
11+
* Tests for code blocks and inline code.
12+
*/
13+
class CodeTest {
14+
@Test
15+
fun inline() {
16+
execute("`println(\"Hello, world!\")`") {
17+
assertEquals(
18+
"<p><span class=\"codespan-content\"><code>println(&quot;Hello, world!&quot;)</code></span></p>",
19+
it,
20+
)
21+
assertFalse(attributes.hasCode)
22+
}
23+
}
24+
25+
@Test
26+
fun `hex color preview`() {
27+
execute("`#FF0000`") {
28+
assertEquals(
29+
"<p>" +
30+
"<span class=\"codespan-content\">" +
31+
"<code>#FF0000</code>" +
32+
"<span style=\"background-color: rgba(255, 0, 0, 1.0);\" class=\"color-preview\"></span>" +
33+
"</span>" +
34+
"</p>",
35+
it,
36+
)
37+
assertFalse(attributes.hasCode)
38+
}
39+
}
40+
41+
@Test
42+
fun `rgb color preview`() {
43+
execute("`rgba(200, 100, 50, 0.5)`") {
44+
assertEquals(
45+
"<p>" +
46+
"<span class=\"codespan-content\">" +
47+
"<code>rgba(200, 100, 50, 0.5)</code>" +
48+
"<span style=\"background-color: rgba(200, 100, 50, 0.5);\" class=\"color-preview\"></span>" +
49+
"</span>" +
50+
"</p>",
51+
it,
52+
)
53+
assertFalse(attributes.hasCode)
54+
}
55+
}
56+
57+
@Test
58+
fun block() {
59+
execute("```\nprintln(\"Hello, world!\")\n```") {
60+
assertEquals("<pre><code>println(&quot;Hello, world!&quot;)</code></pre>", it)
61+
assertTrue(attributes.hasCode)
62+
}
63+
}
64+
65+
@Test
66+
fun `block with language`() {
67+
execute("```kotlin\nprintln(\"Hello, world!\")\n```") {
68+
assertEquals("<pre><code class=\"language-kotlin\">println(&quot;Hello, world!&quot;)</code></pre>", it)
69+
assertTrue(attributes.hasCode)
70+
}
71+
}
72+
73+
@Test
74+
fun `block with language and indentation`() {
75+
execute("```kotlin\nfun hello() {\n println(\"Hello, world!\")\n}\n```") {
76+
assertEquals(
77+
"<pre><code class=\"language-kotlin\">fun hello() {\n println(&quot;Hello, world!&quot;)\n}</code></pre>",
78+
it,
79+
)
80+
assertTrue(attributes.hasCode)
81+
}
82+
}
83+
84+
// #32
85+
@Test
86+
fun `long block`() {
87+
execute(
88+
"""
89+
```nohighlight
90+
1/1 file.ext - this_is_a_very_long_function_name_indeed()
91+
59/59 file.ext - this_is_a_very_long_function_name_indeed()
92+
11/11 file.ext - this_is_a_very_long_function_name_indeed()
93+
11/11 file.ext - this_is_a_very_long_function_name_indeed()
94+
11/11 file.ext - this_is_a_very_long_function_name_indeed()
95+
15/15 file.ext - this_is_a_very_long_function_name_indeed()
96+
4/4 file.ext - this_is_a_very_long_function_name_indeed()
97+
13/13 file.ext - this_is_a_very_long_function_name_indeed()
98+
14/14 file.ext - this_is_a_very_long_function_name_indeed()
99+
4/4 file.ext - this_is_a_very_long_function_name_indeed()
100+
15/15 file.ext - this_is_a_very_long_function_name_indeed()
101+
19/19 file.ext - this_is_a_very_long_function_name_indeed()
102+
12/12 file.ext - this_is_a_very_long_function_name_indeed()
103+
4/4 file.ext - this_is_a_very_long_function_name_indeed()
104+
14/14 file.ext - this_is_a_very_long_function_name_indeed()
105+
2/2 file.ext - this_is_a_very_long_function_name_indeed()
106+
8/8 file.ext - this_is_a_very_long_function_name_indeed()
107+
13/13 file.ext - this_is_a_very_long_function_name_indeed()
108+
4/4 file.ext - this_is_a_very_long_function_name_indeed()
109+
16/16 file.ext - this_is_a_very_long_function_name_indeed()
110+
*** 19/21 file.ext - this_is_a_very_long_function_name_indeed()
111+
2/2 file.ext - this_is_a_very_long_function_name_indeed()
112+
2/2 file.ext - this_is_a_very_long_function_name_indeed()
113+
2/2 file.ext - this_is_a_very_long_function_name_indeed()
114+
2/2 file.ext - this_is_a_very_long_function_name_indeed()
115+
2/2 file.ext - this_is_a_very_long_function_name_indeed()
116+
2/2 file.ext - this_is_a_very_long_function_name_indeed()
117+
16/16 file.ext - this_is_a_very_long_function_name_indeed()
118+
*** 23/25 file.ext - this_is_a_very_long_function_name_indeed()
119+
1/1 file.ext - this_is_a_very_long_function_name_indeed()
120+
1/1 file.ext - this_is_a_very_long_function_name_indeed()
121+
7/7 file.ext - this_is_a_very_long_function_name_indeed()
122+
3/3 file.ext - this_is_a_very_long_function_name_indeed()
123+
*** 81/82 file_1.ext - this_is_a_very_long_function_name_indeed()
124+
*** 0/87 file_1.ext - this_is_a_very_long_function_name_indeed()
125+
```
126+
""".trimIndent(),
127+
) {
128+
assertTrue(it.startsWith("<pre><code class=\"language-nohighlight\">"))
129+
assertTrue(it.endsWith("</code></pre>"))
130+
assertEquals(35, it.lines().size)
131+
}
132+
}
133+
}

quarkdown-test/src/test/kotlin/com/quarkdown/test/NodesTest.kt

Lines changed: 0 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
package com.quarkdown.test
22

3-
import com.quarkdown.core.ast.attributes.presence.hasCode
43
import com.quarkdown.core.ast.attributes.presence.hasMath
54
import com.quarkdown.test.util.execute
65
import kotlin.test.Test
76
import kotlin.test.assertEquals
8-
import kotlin.test.assertFalse
97
import kotlin.test.assertTrue
108

119
/**
@@ -314,62 +312,6 @@ class NodesTest {
314312
}
315313
}
316314

317-
@Test
318-
fun code() {
319-
execute("`println(\"Hello, world!\")`") {
320-
assertEquals(
321-
"<p><span class=\"codespan-content\"><code>println(&quot;Hello, world!&quot;)</code></span></p>",
322-
it,
323-
)
324-
assertFalse(attributes.hasCode)
325-
}
326-
327-
// Color preview
328-
execute("`#FF0000`") {
329-
assertEquals(
330-
"<p>" +
331-
"<span class=\"codespan-content\">" +
332-
"<code>#FF0000</code>" +
333-
"<span style=\"background-color: rgba(255, 0, 0, 1.0);\" class=\"color-preview\"></span>" +
334-
"</span>" +
335-
"</p>",
336-
it,
337-
)
338-
assertFalse(attributes.hasCode)
339-
}
340-
341-
execute("`rgba(200, 100, 50, 0.5)`") {
342-
assertEquals(
343-
"<p>" +
344-
"<span class=\"codespan-content\">" +
345-
"<code>rgba(200, 100, 50, 0.5)</code>" +
346-
"<span style=\"background-color: rgba(200, 100, 50, 0.5);\" class=\"color-preview\"></span>" +
347-
"</span>" +
348-
"</p>",
349-
it,
350-
)
351-
assertFalse(attributes.hasCode)
352-
}
353-
354-
execute("```\nprintln(\"Hello, world!\")\n```") {
355-
assertEquals("<pre><code>println(&quot;Hello, world!&quot;)</code></pre>", it)
356-
assertTrue(attributes.hasCode)
357-
}
358-
359-
execute("```kotlin\nprintln(\"Hello, world!\")\n```") {
360-
assertEquals("<pre><code class=\"language-kotlin\">println(&quot;Hello, world!&quot;)</code></pre>", it)
361-
assertTrue(attributes.hasCode)
362-
}
363-
364-
execute("```kotlin\nfun hello() {\n println(\"Hello, world!\")\n}\n```") {
365-
assertEquals(
366-
"<pre><code class=\"language-kotlin\">fun hello() {\n println(&quot;Hello, world!&quot;)\n}</code></pre>",
367-
it,
368-
)
369-
assertTrue(attributes.hasCode)
370-
}
371-
}
372-
373315
@Test
374316
fun tables() {
375317
execute("| Header 1 | Header 2 |\n|----------|----------|\n| Cell 1 | Cell 2 |") {

0 commit comments

Comments
 (0)