aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorJeremy Davis <jeremy.davis@sonarsource.com>2023-08-15 15:52:42 +0200
committersonartech <sonartech@sonarsource.com>2023-08-16 20:02:43 +0000
commita5d5ed7f81a071675f0f20ff614f439faf525af6 (patch)
treeb98badac8cbed0d81ee6fa8f0148fd81c82ad94f /server
parentefc3937676e14ac5b5e756f8439a9c4916f844c8 (diff)
downloadsonarqube-a5d5ed7f81a071675f0f20ff614f439faf525af6.tar.gz
sonarqube-a5d5ed7f81a071675f0f20ff614f439faf525af6.zip
SONAR-20161 Fix broken rule description
Diffstat (limited to 'server')
-rw-r--r--server/sonar-web/design-system/src/components/CodeSyntaxHighlighter.tsx8
-rw-r--r--server/sonar-web/design-system/src/components/__tests__/CodeSyntaxHighlighter-test.tsx15
2 files changed, 20 insertions, 3 deletions
diff --git a/server/sonar-web/design-system/src/components/CodeSyntaxHighlighter.tsx b/server/sonar-web/design-system/src/components/CodeSyntaxHighlighter.tsx
index 9ae139c9f8d..f6fda7072a1 100644
--- a/server/sonar-web/design-system/src/components/CodeSyntaxHighlighter.tsx
+++ b/server/sonar-web/design-system/src/components/CodeSyntaxHighlighter.tsx
@@ -20,7 +20,7 @@
import styled from '@emotion/styled';
import classNames from 'classnames';
-import hljs from 'highlight.js';
+import hljs, { HighlightResult } from 'highlight.js';
import apex from 'highlightjs-apex';
import abap from 'highlightjs-sap-abap';
import tw from 'twin.macro';
@@ -64,7 +64,7 @@ export function CodeSyntaxHighlighter(props: Props) {
const unescapedCode = htmlDecode(code);
- let highlightedCode;
+ let highlightedCode: HighlightResult;
try {
highlightedCode = hljs.highlight(unescapedCode, {
@@ -80,7 +80,9 @@ export function CodeSyntaxHighlighter(props: Props) {
highlightedHtmlAsString = highlightedHtmlAsString.replace(
codeBlock,
- `<${tag}${attributes}>${highlightedCode.value}</${tag}>`
+ // Use a function to avoid triggering special replacement patterns
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_the_replacement
+ () => `<${tag}${attributes}>${highlightedCode.value}</${tag}>`
);
});
diff --git a/server/sonar-web/design-system/src/components/__tests__/CodeSyntaxHighlighter-test.tsx b/server/sonar-web/design-system/src/components/__tests__/CodeSyntaxHighlighter-test.tsx
index a55e079b885..5728f784a4d 100644
--- a/server/sonar-web/design-system/src/components/__tests__/CodeSyntaxHighlighter-test.tsx
+++ b/server/sonar-web/design-system/src/components/__tests__/CodeSyntaxHighlighter-test.tsx
@@ -51,3 +51,18 @@ it('renders correctly with code', () => {
// eslint-disable-next-line testing-library/no-node-access
expect(container.getElementsByClassName('hljs-string').length).toBe(1);
});
+
+/*
+ * This test reproduces a breaking case for https://sonarsource.atlassian.net/browse/SONAR-20161
+ */
+it('handles html code snippets', () => {
+ const { container } = render(
+ <CodeSyntaxHighlighter
+ htmlAsString={
+ '\u003ch4\u003eNoncompliant code example\u003c/h4\u003e\n\u003cpre data-diff-id\u003d"1" data-diff-type\u003d"noncompliant"\u003e\npublic void Method(MyObject myObject)\n{\n if (myObject is null)\n {\n new MyObject(); // Noncompliant\n }\n\n if (myObject.IsCorrupted)\n {\n new ArgumentException($"{nameof(myObject)} is corrupted"); // Noncompliant\n }\n\n // ...\n}\n\u003c/pre\u003e\n\u003ch4\u003eCompliant solution\u003c/h4\u003e\n\u003cpre data-diff-id\u003d"1" data-diff-type\u003d"compliant"\u003e\npublic void Method(MyObject myObject)\n{\n if (myObject is null)\n {\n myObject \u003d new MyObject(); // Compliant\n }\n\n if (myObject.IsCorrupted)\n {\n throw new ArgumentException($"{nameof(myObject)} is corrupted"); // Compliant\n }\n\n // ...\n}\n\u003c/pre\u003e'
+ }
+ />
+ );
+
+ expect(container.querySelectorAll('pre')).toHaveLength(2);
+});