]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-20161 Fix broken rule description
authorJeremy Davis <jeremy.davis@sonarsource.com>
Tue, 15 Aug 2023 13:52:42 +0000 (15:52 +0200)
committersonartech <sonartech@sonarsource.com>
Wed, 16 Aug 2023 20:02:43 +0000 (20:02 +0000)
server/sonar-web/design-system/src/components/CodeSyntaxHighlighter.tsx
server/sonar-web/design-system/src/components/__tests__/CodeSyntaxHighlighter-test.tsx

index 9ae139c9f8d75452f7051d2d137e4a89c84d1e58..f6fda7072a1fa6564b425dc164bf6a8e38c67f6f 100644 (file)
@@ -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}>`
     );
   });
 
index a55e079b88576fc783bd5d523ff229d1b2bfc9a7..5728f784a4ddb39b793172e738c7639e2009e93a 100644 (file)
@@ -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);
+});