Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F32210033
D5033.1765129239.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D5033.1765129239.diff
View Options
diff --git a/lib/shared/markdown.js b/lib/shared/markdown.js
--- a/lib/shared/markdown.js
+++ b/lib/shared/markdown.js
@@ -85,9 +85,6 @@
const codeBlockRegex: RegExp = /^(?: {4}[^\n]*\n*?)+(?!\n* {4}[^\n])(?:\n|$)/;
const codeBlockStripTrailingNewlineRegex: RegExp = /^((?: {4}[^\n]*\n*?)+)(?!\n* {4}[^\n])(?:\n|$)/;
-const blockQuoteRegex: RegExp = /^( *>[^\n]+(?:\n[^\n]+)*)(?:\n|$)/;
-const blockQuoteStripFollowingNewlineRegex: RegExp = /^( *>[^\n]+(?:\n[^\n]+)*)(?:\n|$){2}/;
-
const urlRegex: RegExp = /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/i;
const mentionRegex = new RegExp(`^(@(${oldValidUsernameRegexString}))\\b`);
@@ -219,6 +216,40 @@
return match;
}
+const blockQuoteRegex: RegExp = /^( *>[^\n]+(?:\n[^\n]+)*)(?:\n|$)/;
+const blockQuoteStripFollowingNewlineRegex: RegExp = /^( *>[^\n]+(?:\n[^\n]+)*)(?:\n|$){2}/;
+const maxNestedQuotations = 5;
+
+// Custom match and parse functions implementation for block quotes
+// to allow us to specify quotes parsing depth
+// to avoid too many recursive calls and e.g. app crash
+function matchBlockQuote(quoteRegex: RegExp): MatchFunction {
+ return (source: string, state: State) => {
+ if (
+ state.inline ||
+ (state?.quotationsDepth && state.quotationsDepth >= maxNestedQuotations)
+ ) {
+ return null;
+ }
+ return quoteRegex.exec(source);
+ };
+}
+
+function parseBlockQuote(
+ capture: Capture,
+ parse: Parser,
+ state: State,
+): UnTypedASTNode {
+ const content = capture[1].replace(/^ *> ?/gm, '');
+ const currentQuotationsDepth = state?.quotationsDepth ?? 0;
+ return {
+ content: parse(content, {
+ ...state,
+ quotationsDepth: currentQuotationsDepth + 1,
+ }),
+ };
+}
+
export {
paragraphRegex,
paragraphStripTrailingNewlineRegex,
@@ -231,6 +262,8 @@
codeBlockStripTrailingNewlineRegex,
fenceRegex,
fenceStripTrailingNewlineRegex,
+ matchBlockQuote,
+ parseBlockQuote,
jsonMatch,
jsonPrint,
matchList,
diff --git a/native/markdown/rules.react.js b/native/markdown/rules.react.js
--- a/native/markdown/rules.react.js
+++ b/native/markdown/rules.react.js
@@ -215,19 +215,10 @@
blockQuote: {
...SimpleMarkdown.defaultRules.blockQuote,
// match end of blockQuote by either \n\n or end of string
- match: SimpleMarkdown.blockRegex(
+ match: SharedMarkdown.matchBlockQuote(
SharedMarkdown.blockQuoteStripFollowingNewlineRegex,
),
- parse(
- capture: SharedMarkdown.Capture,
- parse: SharedMarkdown.Parser,
- state: SharedMarkdown.State,
- ) {
- const content = capture[1].replace(/^ *> ?/gm, '');
- return {
- content: parse(content, state),
- };
- },
+ parse: SharedMarkdown.parseBlockQuote,
// eslint-disable-next-line react/display-name
react: (
node: SharedMarkdown.SingleASTNode,
diff --git a/web/markdown/rules.react.js b/web/markdown/rules.react.js
--- a/web/markdown/rules.react.js
+++ b/web/markdown/rules.react.js
@@ -78,17 +78,8 @@
blockQuote: {
...SimpleMarkdown.defaultRules.blockQuote,
// match end of blockQuote by either \n\n or end of string
- match: SimpleMarkdown.blockRegex(SharedMarkdown.blockQuoteRegex),
- parse(
- capture: SharedMarkdown.Capture,
- parse: SharedMarkdown.Parser,
- state: SharedMarkdown.State,
- ) {
- const content = capture[1].replace(/^ *> ?/gm, '');
- return {
- content: parse(content, state),
- };
- },
+ match: SharedMarkdown.matchBlockQuote(SharedMarkdown.blockQuoteRegex),
+ parse: SharedMarkdown.parseBlockQuote,
},
inlineCode: SimpleMarkdown.defaultRules.inlineCode,
em: SimpleMarkdown.defaultRules.em,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Dec 7, 5:40 PM (19 h, 43 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5845244
Default Alt Text
D5033.1765129239.diff (3 KB)
Attached To
Mode
D5033: [web/native] nested quotation display limit
Attached
Detach File
Event Timeline
Log In to Comment