summaryrefslogtreecommitdiff
path: root/app/assets
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-12-04 16:51:40 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-12-04 16:51:40 +0000
commitaefe6486cf0d193067112b90145083d73b96bfef (patch)
tree02dbf7d022069b183f34b63e99eb359d7e001ddb /app/assets
parent66ebf02c05dc69a65731d61baf28ef3335db2bbf (diff)
downloadgitlab-ce-aefe6486cf0d193067112b90145083d73b96bfef.tar.gz
Add latest changes from gitlab-org/security/gitlab@13-6-stable-ee
Diffstat (limited to 'app/assets')
-rw-r--r--app/assets/javascripts/behaviors/markdown/render_mermaid.js32
1 files changed, 26 insertions, 6 deletions
diff --git a/app/assets/javascripts/behaviors/markdown/render_mermaid.js b/app/assets/javascripts/behaviors/markdown/render_mermaid.js
index 233c5f84340..602f156dbf0 100644
--- a/app/assets/javascripts/behaviors/markdown/render_mermaid.js
+++ b/app/assets/javascripts/behaviors/markdown/render_mermaid.js
@@ -18,7 +18,13 @@ import { __, sprintf } from '~/locale';
//
// This is an arbitrary number; Can be iterated upon when suitable.
-const MAX_CHAR_LIMIT = 5000;
+const MAX_CHAR_LIMIT = 2000;
+// Max # of mermaid blocks that can be rendered in a page.
+const MAX_MERMAID_BLOCK_LIMIT = 50;
+// Keep a map of mermaid blocks we've already rendered.
+const elsProcessingMap = new WeakMap();
+let renderedMermaidBlocks = 0;
+
let mermaidModule = {};
function importMermaidModule() {
@@ -110,13 +116,22 @@ function renderMermaids($els) {
let renderedChars = 0;
$els.each((i, el) => {
+ // Skipping all the elements which we've already queued in requestIdleCallback
+ if (elsProcessingMap.has(el)) {
+ return;
+ }
+
const { source } = fixElementSource(el);
/**
- * Restrict the rendering to a certain amount of character to
- * prevent mermaidjs from hanging up the entire thread and
- * causing a DoS.
+ * Restrict the rendering to a certain amount of character
+ * and mermaid blocks to prevent mermaidjs from hanging
+ * up the entire thread and causing a DoS.
*/
- if ((source && source.length > MAX_CHAR_LIMIT) || renderedChars > MAX_CHAR_LIMIT) {
+ if (
+ (source && source.length > MAX_CHAR_LIMIT) ||
+ renderedChars > MAX_CHAR_LIMIT ||
+ renderedMermaidBlocks >= MAX_MERMAID_BLOCK_LIMIT
+ ) {
const html = `
<div class="alert gl-alert gl-alert-warning alert-dismissible lazy-render-mermaid-container js-lazy-render-mermaid-container fade show" role="alert">
<div>
@@ -146,8 +161,13 @@ function renderMermaids($els) {
}
renderedChars += source.length;
+ renderedMermaidBlocks += 1;
+
+ const requestId = window.requestIdleCallback(() => {
+ renderMermaidEl(el);
+ });
- renderMermaidEl(el);
+ elsProcessingMap.set(el, requestId);
});
})
.catch(err => {