[frameworks/syntax-highlighting] /: RTF: Fix unbounded context stack growth

Christoph Cullmann <[email protected]>
Newsgroups gmane.comp.kde.cvs
Message-ID <[email protected]>
Git commit 2b8a80270a31a6173f36bd4e2c3f5164ea99509b by Christoph Cullmann, on behalf of Ramil Nurmanov.
Committed on 20/07/2026 at 22:02.
Pushed by cullmann into branch 'master'.

RTF: Fix unbounded context stack growth

Return from the temporary backslash and parameter contexts using #pop instead of pushing a new context_normal instance.

The previous transitions left the completed contexts on the stack for every RTF control word. This caused the highlighting state to grow throughout the document, resulting in excessive memory usage and increasingly slow highlighting for large RTF files.

A  +102  -0    autotests/folding/rtf_for_test.rtf.fold
A  +109  -0    autotests/html/rtf_for_test.rtf.dark.html
A  +109  -0    autotests/html/rtf_for_test.rtf.html
A  +102  -0    autotests/input/rtf_for_test.rtf
A  +102  -0    autotests/reference/rtf_for_test.rtf.ref
M  +4    -4    data/syntax/rtf.xml

https://invent.kde.org/frameworks/syntax-highlighting/-/commit/2b8a80270a31a6173f36bd4e2c3f5164ea99509b

diff --git a/autotests/folding/rtf_for_test.rtf.fold b/autotests/folding/rtf_for_test.rtf.fold
new file mode 100644
index 000000000..72927e5a3
--- /dev/null
+++ b/autotests/folding/rtf_for_test.rtf.fold
@@ -0,0 +1,102 @@
+<beginfold id='1'>{</beginfold id='1'>\rtf1\ansi\ansicpg1252\deff0\deflang1033<beginfold id='1'>{</beginfold id='1'>\fonttbl<beginfold id='1'>{</beginfold id='1'>\f0\fmodern\fprq1\fcharset0 Courier New;<endfold id='1'>}</endfold id='1'><endfold id='1'>}</endfold id='1'><beginfold id='1'>{</beginfold id='1'>\colortbl ;\red0\green0\blue255;\red0\green128\blue0;\red128\green0\blue128;\red255\green0\blue0;\red0\green0\blue0;<endfold id='1'>}</endfold id='1'>\viewkind4\uc1\pard\f0\fs20
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
+<beginfold id='1'>{</beginfold id='1'><beginfold id='1'>{</beginfold id='1'>\cf5     <endfold id='1'>}</endfold id='1'><beginfold id='1'>{</beginfold id='1'>\cf5 )<endfold id='1'>}</endfold id='1'> <beginfold id='1'>{</beginfold id='1'>\cf3\i "str110"\i0 <endfold id='1'>}</endfold id='1'> <beginfold id='1'>{</beginfold id='1'>\cf4 40888<endfold id='1'>}</endfold id='1'> <beginfold id='1'>{</beginfold id='1'>\cf4 49192<endfold id='1'>}</endfold id='1'> \par<endfold id='1'>}</endfold id='1'>
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
+<beginfold id='1'>{</beginfold id='1'><beginfold id='1'>{</beginfold id='1'>\cf5                 <endfold id='1'>}</endfold id='1'><beginfold id='1'>{</beginfold id='1'>\cf5 ;<endfold id='1'>}</endfold id='1'> <beginfold id='1'>{</beginfold id='1'>\cf1\b void\b0 <endfold id='1'>}</endfold id='1'> <beginfold id='1'>{</beginfold id='1'>\cf5 =<endfold id='1'>}</endfold id='1'> <beginfold id='1'>{</beginfold id='1'>\cf5 ;<endfold id='1'>}</endfold id='1'> \par<endfold id='1'>}</endfold id='1'>
[suppressed due to size limit]
+<beginfold id='1'>{</beginfold id='1'><beginfold id='1'>{</beginfold id='1'>\cf5     <endfold id='1'>}</endfold id='1'><beginfold id='1'>{</beginfold id='1'>\cf5 )<endfold id='1'>}</endfold id='1'> <beginfold id='1'>{</beginfold id='1'>\cf2 widget349<endfold id='1'>}</endfold id='1'> <beginfold id='1'>{</beginfold id='1'>\cf1\b return\b0 <endfold id='1'>}</endfold id='1'> <beginfold id='1'>{</beginfold id='1'>\cf5 =<endfold id='1'>}</endfold id='1'> \par<endfold id='1'>}</endfold id='1'>
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
+<endfold id='1'>}</endfold id='1'>
diff --git a/autotests/html/rtf_for_test.rtf.dark.html b/autotests/html/rtf_for_test.rtf.dark.html
new file mode 100644
index 000000000..c9727f521
--- /dev/null
+++ b/autotests/html/rtf_for_test.rtf.dark.html
@@ -0,0 +1,109 @@
+<!DOCTYPE html>
+<html><head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+<title>rtf_for_test.rtf</title>
+<meta name="generator" content="KF5::SyntaxHighlighting - Definition (Rich Text Format) - Theme (Breeze Dark)"/>
+</head><body style="background-color:#232629;color:#cfcfc2"><pre>
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
+<span style="font-weight:bold">}</span>
+</pre></body></html>
diff --git a/autotests/html/rtf_for_test.rtf.html b/autotests/html/rtf_for_test.rtf.html
new file mode 100644
index 000000000..550b0c1d6
--- /dev/null
+++ b/autotests/html/rtf_for_test.rtf.html
@@ -0,0 +1,109 @@
+<!DOCTYPE html>
+<html><head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+<title>rtf_for_test.rtf</title>
+<meta name="generator" content="KF5::SyntaxHighlighting - Definition (Rich Text Format) - Theme (Breeze Light)"/>
+</head><body style="background-color:#ffffff;color:#1f1c1b"><pre>
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
+<span style="font-weight:bold">}</span>
+</pre></body></html>
diff --git a/autotests/input/rtf_for_test.rtf b/autotests/input/rtf_for_test.rtf
new file mode 100644
index 000000000..b79a1558c
--- /dev/null
+++ b/autotests/input/rtf_for_test.rtf
@@ -0,0 +1,102 @@
+{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fmodern\fprq1\fcharset0 Courier New;}}{\colortbl ;\red0\green0\blue255;\red0\green128\blue0;\red128\green0\blue128;\red255\green0\blue0;\red0\green0\blue0;}\viewkind4\uc1\pard\f0\fs20
+{{\cf5 }{\cf1\b return\b0 } {\cf1\b while\b0 } {\cf5 ,} {\cf5 ;} {\cf1\b void\b0 } {\cf1\b else\b0 } {\cf1\b const\b0 } {\cf4 73563} {\cf1\b const\b0 } \par}
+{{\cf5     }{\cf1\b static\b0 } {\cf2 counter777} {\cf5 ,} {\cf2 index159} {\cf1\b class\b0 } {\cf1\b void\b0 } {\cf1\b class\b0 } \par}
+{{\cf5         }{\cf2 counter747} {\cf2 value996} {\cf3\i "str80"\i0 } {\cf4 82397} {\cf4 47400} {\cf4 92349} {\cf1\b for\b0 } {\cf5 (} \par}
+{{\cf5             }{\cf3\i "str389"\i0 } {\cf2 handler166} {\cf2 result686} {\cf2 value623} {\cf4 70010} \par}
+{{\cf5                 }{\cf1\b int\b0 } {\cf2 stream224} {\cf4 7331} {\cf1\b if\b0 } {\cf5 \}} {\cf2 result935} {\cf3\i "str897"\i0 } {\cf5 )} {\cf4 51856} \par}
+{{\cf5 }{\cf2 index142} {\cf1\b const\b0 } {\cf2 config438} {\cf3\i "str408"\i0 } {\cf2 buffer521} {\cf2 counter881} {\cf1\b while\b0 } {\cf5 \}} {\cf4 50432} \par}
+{{\cf5     }{\cf4 61348} {\cf2 stream881} {\cf3\i "str696"\i0 } {\cf5 ,} {\cf3\i "str768"\i0 } {\cf2 handler114} {\cf2 buffer464} \par}
+{{\cf5         }{\cf3\i "str896"\i0 } {\cf5 ;} {\cf5 ;} {\cf3\i "str891"\i0 } \par}
+{{\cf5             }{\cf2 stream623} {\cf1\b class\b0 } {\cf5 ;} {\cf3\i "str944"\i0 } {\cf2 counter613} {\cf2 counter114} {\cf3\i "str899"\i0 } {\cf3\i "str826"\i0 } {\cf2 counter246} \par}
+{{\cf5                 }{\cf3\i "str87"\i0 } {\cf5 =} {\cf1\b const\b0 } {\cf5 )} {\cf4 72063} {\cf1\b const\b0 } {\cf3\i "str433"\i0 } {\cf3\i "str951"\i0 } \par}
+{{\cf5 }{\cf5 ,} {\cf1\b return\b0 } {\cf2 handler448} {\cf3\i "str462"\i0 } {\cf1\b for\b0 } {\cf1\b if\b0 } {\cf4 30161} {\cf4 942} \par}
+{{\cf5     }{\cf5 (} {\cf1\b if\b0 } {\cf3\i "str72"\i0 } {\cf2 index685} \par}
+{{\cf5         }{\cf1\b while\b0 } {\cf5 ;} {\cf4 31850} {\cf5 =} {\cf2 value99} {\cf4 46438} {\cf2 widget884} \par}
+{{\cf5             }{\cf1\b else\b0 } {\cf1\b class\b0 } {\cf5 (} {\cf1\b for\b0 } {\cf2 buffer432} {\cf1\b int\b0 } {\cf1\b else\b0 } {\cf2 stream100} {\cf1\b const\b0 } \par}
+{{\cf5                 }{\cf3\i "str948"\i0 } {\cf5 )} {\cf1\b int\b0 } {\cf2 context924} \par}
+{{\cf5 }{\cf1\b if\b0 } {\cf3\i "str271"\i0 } {\cf3\i "str803"\i0 } {\cf2 context713} \par}
+{{\cf5     }{\cf3\i "str569"\i0 } {\cf4 63788} {\cf1\b return\b0 } {\cf1\b if\b0 } {\cf4 71066} {\cf1\b class\b0 } {\cf1\b static\b0 } {\cf2 stream161} {\cf1\b const\b0 } \par}
+{{\cf5         }{\cf3\i "str70"\i0 } {\cf4 88501} {\cf3\i "str413"\i0 } {\cf1\b static\b0 } \par}
+{{\cf5             }{\cf4 5209} {\cf4 54948} {\cf4 74085} {\cf2 index209} {\cf4 41180} \par}
+{{\cf5                 }{\cf2 buffer687} {\cf4 59929} {\cf2 value9} {\cf2 config102} {\cf1\b for\b0 } \par}
+{{\cf5 }{\cf2 handler902} {\cf1\b for\b0 } {\cf2 buffer448} {\cf5 ,} {\cf2 stream8} {\cf4 72692} {\cf2 value961} {\cf3\i "str270"\i0 } \par}
+{{\cf5     }{\cf3\i "str760"\i0 } {\cf4 35697} {\cf2 result734} {\cf2 index517} \par}
+{{\cf5         }{\cf2 counter94} {\cf4 36265} {\cf1\b class\b0 } {\cf5 ,} {\cf3\i "str165"\i0 } {\cf5 ;} {\cf5 ;} \par}
+{{\cf5             }{\cf1\b while\b0 } {\cf2 handler596} {\cf4 56333} {\cf1\b return\b0 } \par}
+{{\cf5                 }{\cf3\i "str815"\i0 } {\cf3\i "str40"\i0 } {\cf3\i "str215"\i0 } {\cf4 87416} {\cf1\b const\b0 } {\cf3\i "str416"\i0 } \par}
+{{\cf5 }{\cf5 )} {\cf3\i "str999"\i0 } {\cf5 )} {\cf3\i "str25"\i0 } {\cf1\b class\b0 } {\cf5 \}} {\cf5 =} {\cf5 )} \par}
+{{\cf5     }{\cf1\b else\b0 } {\cf2 counter879} {\cf2 result836} {\cf3\i "str358"\i0 } {\cf2 result228} {\cf1\b for\b0 } \par}
+{{\cf5         }{\cf2 value990} {\cf5 \{} {\cf4 52386} {\cf4 70282} {\cf2 counter118} {\cf3\i "str267"\i0 } {\cf1\b return\b0 } \par}
+{{\cf5             }{\cf1\b void\b0 } {\cf2 handler446} {\cf4 67033} {\cf1\b static\b0 } \par}
+{{\cf5                 }{\cf2 context1} {\cf2 stream703} {\cf5 ,} {\cf5 )} {\cf2 value971} \par}
+{{\cf5 }{\cf3\i "str638"\i0 } {\cf2 value737} {\cf3\i "str519"\i0 } {\cf2 context334} {\cf2 index567} {\cf1\b void\b0 } {\cf4 49695} {\cf4 22810} {\cf4 39446} \par}
+{{\cf5     }{\cf2 counter311} {\cf2 context804} {\cf4 85813} {\cf2 widget452} {\cf4 67000} {\cf2 buffer674} {\cf1\b const\b0 } \par}
+{{\cf5         }{\cf4 43933} {\cf1\b for\b0 } {\cf4 29444} {\cf5 )} {\cf1\b for\b0 } {\cf3\i "str625"\i0 } {\cf5 (} {\cf2 config199} {\cf5 \}} \par}
+{{\cf5             }{\cf2 buffer671} {\cf4 98430} {\cf3\i "str906"\i0 } {\cf1\b void\b0 } {\cf1\b const\b0 } {\cf2 stream255} {\cf3\i "str124"\i0 } \par}
+{{\cf5                 }{\cf1\b int\b0 } {\cf4 73259} {\cf4 98992} {\cf3\i "str627"\i0 } {\cf5 ;} {\cf2 stream456} {\cf3\i "str761"\i0 } \par}
+{{\cf5 }{\cf2 result860} {\cf4 68327} {\cf2 result281} {\cf2 index240} {\cf2 handler914} {\cf2 buffer154} {\cf1\b while\b0 } \par}
+{{\cf5     }{\cf1\b void\b0 } {\cf2 stream477} {\cf2 result852} {\cf2 config968} {\cf4 75456} {\cf2 counter965} {\cf2 context873} {\cf3\i "str855"\i0 } {\cf2 stream819} \par}
+{{\cf5         }{\cf3\i "str499"\i0 } {\cf1\b void\b0 } {\cf2 context344} {\cf4 52994} {\cf5 =} {\cf2 buffer637} {\cf2 context606} {\cf4 3552} \par}
+{{\cf5             }{\cf4 17786} {\cf3\i "str186"\i0 } {\cf1\b void\b0 } {\cf2 widget334} \par}
+{{\cf5                 }{\cf5 \}} {\cf2 context258} {\cf5 \}} {\cf1\b const\b0 } {\cf1\b class\b0 } {\cf1\b else\b0 } \par}
+{{\cf5 }{\cf1\b if\b0 } {\cf3\i "str204"\i0 } {\cf5 ;} {\cf1\b while\b0 } {\cf2 value577} {\cf3\i "str476"\i0 } {\cf4 48351} {\cf1\b static\b0 } {\cf3\i "str735"\i0 } \par}
+{{\cf5     }{\cf5 )} {\cf3\i "str110"\i0 } {\cf4 40888} {\cf4 49192} \par}
+{{\cf5         }{\cf3\i "str203"\i0 } {\cf1\b for\b0 } {\cf1\b return\b0 } {\cf3\i "str614"\i0 } {\cf5 =} {\cf3\i "str801"\i0 } {\cf1\b const\b0 } \par}
+{{\cf5             }{\cf4 9038} {\cf2 handler12} {\cf5 =} {\cf2 context983} {\cf2 widget724} {\cf1\b while\b0 } {\cf5 ,} \par}
+{{\cf5                 }{\cf4 70539} {\cf5 \}} {\cf2 config274} {\cf2 result850} {\cf3\i "str285"\i0 } {\cf3\i "str249"\i0 } \par}
+{{\cf5 }{\cf4 87580} {\cf2 counter506} {\cf3\i "str186"\i0 } {\cf2 handler816} {\cf2 index901} {\cf4 36211} {\cf4 67715} \par}
+{{\cf5     }{\cf1\b void\b0 } {\cf2 result707} {\cf2 widget458} {\cf5 (} {\cf2 context708} \par}
+{{\cf5         }{\cf2 config377} {\cf2 stream352} {\cf2 stream338} {\cf2 widget277} {\cf2 result123} \par}
+{{\cf5             }{\cf1\b else\b0 } {\cf5 =} {\cf4 25105} {\cf1\b int\b0 } {\cf2 config778} {\cf2 index102} {\cf5 \{} {\cf1\b while\b0 } {\cf2 stream129} \par}
+{{\cf5                 }{\cf1\b if\b0 } {\cf4 91411} {\cf3\i "str653"\i0 } {\cf3\i "str502"\i0 } {\cf1\b if\b0 } {\cf4 61524} \par}
+{{\cf5 }{\cf2 buffer988} {\cf1\b int\b0 } {\cf1\b else\b0 } {\cf2 value590} {\cf4 7026} {\cf1\b static\b0 } {\cf3\i "str87"\i0 } \par}
+{{\cf5     }{\cf1\b void\b0 } {\cf4 81057} {\cf1\b const\b0 } {\cf2 widget304} {\cf3\i "str439"\i0 } \par}
+{{\cf5         }{\cf4 7894} {\cf4 97004} {\cf1\b for\b0 } {\cf4 34687} {\cf4 20585} {\cf1\b const\b0 } \par}
+{{\cf5             }{\cf1\b void\b0 } {\cf2 config481} {\cf2 result295} {\cf5 ,} \par}
+{{\cf5                 }{\cf1\b for\b0 } {\cf3\i "str806"\i0 } {\cf5 ;} {\cf4 25928} {\cf2 stream230} {\cf4 34816} {\cf5 (} \par}
+{{\cf5 }{\cf1\b return\b0 } {\cf4 74607} {\cf3\i "str449"\i0 } {\cf1\b return\b0 } \par}
+{{\cf5     }{\cf2 index512} {\cf2 widget82} {\cf4 56626} {\cf5 ;} {\cf2 value234} {\cf3\i "str856"\i0 } {\cf3\i "str601"\i0 } {\cf3\i "str783"\i0 } {\cf4 35325} \par}
+{{\cf5         }{\cf1\b while\b0 } {\cf2 widget938} {\cf2 config446} {\cf4 64451} {\cf3\i "str481"\i0 } {\cf2 handler328} {\cf4 21079} {\cf2 widget295} \par}
+{{\cf5             }{\cf3\i "str833"\i0 } {\cf5 (} {\cf2 handler258} {\cf2 context885} {\cf2 counter673} {\cf3\i "str473"\i0 } {\cf2 result530} {\cf2 widget640} {\cf2 counter208} \par}
+{{\cf5                 }{\cf2 index448} {\cf3\i "str496"\i0 } {\cf1\b static\b0 } {\cf5 ,} {\cf1\b const\b0 } {\cf1\b void\b0 } \par}
+{{\cf5 }{\cf1\b else\b0 } {\cf2 value663} {\cf5 \}} {\cf3\i "str298"\i0 } \par}
+{{\cf5     }{\cf5 \}} {\cf5 \}} {\cf1\b const\b0 } {\cf1\b for\b0 } {\cf3\i "str520"\i0 } {\cf5 )} {\cf3\i "str282"\i0 } {\cf5 =} \par}
+{{\cf5         }{\cf2 stream273} {\cf5 \{} {\cf5 =} {\cf4 86499} {\cf2 buffer457} {\cf2 handler340} {\cf4 71228} \par}
+{{\cf5             }{\cf2 handler890} {\cf1\b for\b0 } {\cf4 30613} {\cf3\i "str420"\i0 } {\cf1\b int\b0 } {\cf5 =} {\cf2 buffer507} \par}
+{{\cf5                 }{\cf1\b static\b0 } {\cf2 value895} {\cf5 (} {\cf2 widget15} \par}
+{{\cf5 }{\cf1\b while\b0 } {\cf1\b return\b0 } {\cf2 context665} {\cf1\b class\b0 } {\cf3\i "str879"\i0 } {\cf2 handler641} {\cf5 =} {\cf2 stream36} {\cf4 30771} \par}
+{{\cf5     }{\cf4 37667} {\cf3\i "str764"\i0 } {\cf1\b else\b0 } {\cf5 ,} {\cf3\i "str454"\i0 } {\cf1\b return\b0 } {\cf3\i "str47"\i0 } {\cf2 counter300} {\cf2 context149} \par}
+{{\cf5         }{\cf2 config698} {\cf5 )} {\cf1\b static\b0 } {\cf3\i "str634"\i0 } {\cf4 65230} \par}
+{{\cf5             }{\cf1\b int\b0 } {\cf4 60236} {\cf2 counter920} {\cf5 \{} {\cf4 20706} {\cf1\b class\b0 } {\cf3\i "str306"\i0 } {\cf4 55615} \par}
+{{\cf5                 }{\cf2 index203} {\cf3\i "str873"\i0 } {\cf2 result390} {\cf4 75341} {\cf2 index22} {\cf3\i "str674"\i0 } {\cf2 counter579} {\cf3\i "str796"\i0 } {\cf5 (} \par}
+{{\cf5 }{\cf5 =} {\cf3\i "str293"\i0 } {\cf5 )} {\cf4 46179} {\cf1\b for\b0 } {\cf4 88835} {\cf5 =} {\cf4 17927} \par}
+{{\cf5     }{\cf1\b if\b0 } {\cf2 widget34} {\cf4 95991} {\cf1\b return\b0 } {\cf2 context179} {\cf1\b const\b0 } {\cf3\i "str374"\i0 } {\cf2 index850} {\cf1\b int\b0 } \par}
+{{\cf5         }{\cf5 \{} {\cf5 \}} {\cf3\i "str144"\i0 } {\cf5 )} {\cf3\i "str741"\i0 } {\cf4 52089} \par}
+{{\cf5             }{\cf2 context14} {\cf2 value465} {\cf2 index598} {\cf2 handler110} {\cf4 61797} {\cf1\b const\b0 } {\cf2 config226} {\cf4 83283} \par}
+{{\cf5                 }{\cf3\i "str309"\i0 } {\cf4 15292} {\cf1\b if\b0 } {\cf2 widget118} {\cf1\b const\b0 } {\cf1\b int\b0 } {\cf2 stream429} \par}
+{{\cf5 }{\cf5 )} {\cf3\i "str670"\i0 } {\cf1\b int\b0 } {\cf4 36666} {\cf1\b class\b0 } {\cf1\b int\b0 } {\cf3\i "str875"\i0 } {\cf2 handler557} \par}
+{{\cf5     }{\cf2 context282} {\cf1\b else\b0 } {\cf3\i "str843"\i0 } {\cf2 result657} {\cf4 2799} {\cf1\b class\b0 } {\cf1\b while\b0 } {\cf5 )} {\cf1\b const\b0 } \par}
+{{\cf5         }{\cf4 30539} {\cf2 buffer807} {\cf3\i "str2"\i0 } {\cf2 buffer133} {\cf2 buffer112} \par}
+{{\cf5             }{\cf3\i "str134"\i0 } {\cf1\b for\b0 } {\cf4 2068} {\cf1\b if\b0 } {\cf1\b void\b0 } {\cf2 value487} {\cf2 handler525} {\cf4 59245} {\cf2 config44} \par}
+{{\cf5                 }{\cf5 =} {\cf4 39535} {\cf2 counter62} {\cf3\i "str867"\i0 } {\cf2 value502} {\cf5 \}} {\cf1\b else\b0 } {\cf2 buffer67} {\cf1\b static\b0 } \par}
+{{\cf5 }{\cf4 93343} {\cf2 config543} {\cf2 stream619} {\cf2 value873} {\cf4 72264} {\cf5 )} {\cf2 result423} {\cf2 widget408} {\cf2 value320} \par}
+{{\cf5     }{\cf2 index383} {\cf3\i "str703"\i0 } {\cf3\i "str68"\i0 } {\cf1\b else\b0 } {\cf1\b else\b0 } {\cf5 \{} {\cf5 ;} \par}
+{{\cf5         }{\cf4 73608} {\cf4 87819} {\cf1\b class\b0 } {\cf3\i "str963"\i0 } \par}
+{{\cf5             }{\cf3\i "str738"\i0 } {\cf1\b return\b0 } {\cf4 46090} {\cf1\b const\b0 } {\cf1\b int\b0 } {\cf1\b else\b0 } {\cf2 stream376} \par}
+{{\cf5                 }{\cf5 ;} {\cf1\b void\b0 } {\cf5 =} {\cf5 ;} \par}
+{{\cf5 }{\cf4 3441} {\cf4 86223} {\cf5 \{} {\cf1\b return\b0 } {\cf5 \{} {\cf3\i "str359"\i0 } {\cf1\b while\b0 } {\cf4 52531} {\cf1\b if\b0 } \par}
+{{\cf5     }{\cf5 )} {\cf2 widget349} {\cf1\b return\b0 } {\cf5 =} \par}
+{{\cf5         }{\cf4 6895} {\cf1\b static\b0 } {\cf1\b else\b0 } {\cf2 context497} {\cf4 54287} {\cf2 stream116} {\cf2 value290} {\cf4 77743} \par}
+{{\cf5             }{\cf2 index46} {\cf1\b static\b0 } {\cf1\b for\b0 } {\cf2 result785} {\cf1\b return\b0 } {\cf2 value7} {\cf2 context179} \par}
+{{\cf5                 }{\cf2 result512} {\cf4 87562} {\cf5 (} {\cf2 counter446} {\cf1\b else\b0 } \par}
+{{\cf5 }{\cf4 75156} {\cf2 context296} {\cf1\b if\b0 } {\cf3\i "str175"\i0 } {\cf5 ;} {\cf2 handler90} \par}
+{{\cf5     }{\cf5 )} {\cf2 context536} {\cf1\b return\b0 } {\cf5 )} {\cf2 buffer78} {\cf2 value543} {\cf2 handler359} \par}
+{{\cf5         }{\cf3\i "str660"\i0 } {\cf5 )} {\cf1\b return\b0 } {\cf1\b static\b0 } {\cf1\b else\b0 } {\cf1\b int\b0 } {\cf2 config778} {\cf4 89277} {\cf3\i "str578"\i0 } \par}
+{{\cf5             }{\cf4 81857} {\cf2 handler154} {\cf2 widget452} {\cf4 36002} {\cf4 46129} {\cf2 index472} {\cf2 counter377} {\cf5 (} {\cf4 11835} \par}
+{{\cf5                 }{\cf4 50394} {\cf2 stream977} {\cf5 (} {\cf2 config667} {\cf1\b static\b0 } {\cf2 buffer980} {\cf1\b else\b0 } {\cf5 =} \par}
+{{\cf5 }{\cf3\i "str86"\i0 } {\cf2 buffer40} {\cf1\b int\b0 } {\cf3\i "str536"\i0 } {\cf2 buffer372} {\cf2 index396} \par}
+{{\cf5     }{\cf5 ,} {\cf4 82691} {\cf4 8639} {\cf2 stream694} {\cf2 index741} {\cf3\i "str987"\i0 } {\cf3\i "str894"\i0 } \par}
+{{\cf5         }{\cf2 config679} {\cf1\b class\b0 } {\cf2 context132} {\cf4 11104} {\cf2 context658} \par}
+{{\cf5             }{\cf5 ,} {\cf5 ,} {\cf3\i "str934"\i0 } {\cf2 context520} {\cf2 handler316} {\cf1\b for\b0 } \par}
+{{\cf5                 }{\cf3\i "str497"\i0 } {\cf1\b while\b0 } {\cf1\b return\b0 } {\cf5 (} {\cf2 stream855} {\cf5 ;} \par}
+}
diff --git a/autotests/reference/rtf_for_test.rtf.ref b/autotests/reference/rtf_for_test.rtf.ref
new file mode 100644
index 000000000..feaa8c789
--- /dev/null
+++ b/autotests/reference/rtf_for_test.rtf.ref
@@ -0,0 +1,102 @@
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
[suppressed due to size limit]
+<Braces>}</Braces><br/>
diff --git a/data/syntax/rtf.xml b/data/syntax/rtf.xml
index bfe7c87f0..1f6422133 100644
--- a/data/syntax/rtf.xml
+++ b/data/syntax/rtf.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE language [ <!ENTITY number "([-]?\d+)"> ] >
-<language name="Rich Text Format" version="3" kateversion="2.4" section="Markup" extensions="*.rtf" mimetype="text/rtf;application/rtf" author="Lukas Sommer" license="LGPL version 2.1, or version 3 or later versions approved by the membership of KDE e.V.; or any other license appoved by the emembership of KDE e.V.">
+<language name="Rich Text Format" version="4" kateversion="2.4" section="Markup" extensions="*.rtf" mimetype="text/rtf;application/rtf" author="Lukas Sommer" license="LGPL version 2.1, or version 3 or later versions approved by the membership of KDE e.V.; or any other license appoved by the emembership of KDE e.V.">
 
   <highlighting>
     
@@ -12,7 +12,7 @@
         <DetectChar char="\" lookAhead="true" context="context_process_backslash" />
       </context>
 
-      <context lineEndContext="context_normal" fallthrough="true" fallthroughContext="context_normal" attribute="Numeric parameter" name="context_process_backslash">
+      <context lineEndContext="#pop" fallthrough="true" fallthroughContext="#pop" attribute="Numeric parameter" name="context_process_backslash">
         <Detect2Chars char="\" char1="|" attribute="Control words" />
         <Detect2Chars char="\" char1="~" attribute="Character" />
         <Detect2Chars char="\" char1="-" attribute="Character" />
@@ -27,8 +27,8 @@
         <DetectChar char="\" attribute="Error" />
       </context>
 
-      <context attribute="Control words" lineEndContext="context_normal" fallthrough="true" fallthroughContext="context_normal" name="context_functionparameter">
-        <RegExpr String="[-]?\d+" attribute="Numeric parameter" context="context_normal" />
+      <context attribute="Control words" lineEndContext="#pop#pop" fallthrough="true" fallthroughContext="#pop#pop" name="context_functionparameter">
+        <RegExpr String="[-]?\d+" attribute="Numeric parameter" context="#pop#pop" />
         <DetectChar char="-" attribute="Error" />
       </context>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.