From 403a4bb911c8c36a1c7b7c605f57e3e8679e9532 Mon Sep 17 00:00:00 2001 From: atomiks Date: Fri, 8 Dec 2023 18:53:16 +1100 Subject: [PATCH] fix: prevent loop with overlapping chars (#130) --- src/chars/charsHighlighter.ts | 23 ++++----- src/chars/getElementsToHighlight.ts | 3 +- src/index.ts | 3 +- src/utils.ts | 9 +--- test/fixtures/highlightedCharsLoop.md | 8 ++++ test/results/highlightedCharsLoop.html | 64 ++++++++++++++++++++++++++ 6 files changed, 83 insertions(+), 27 deletions(-) create mode 100644 test/fixtures/highlightedCharsLoop.md create mode 100644 test/results/highlightedCharsLoop.html diff --git a/src/chars/charsHighlighter.ts b/src/chars/charsHighlighter.ts index 7c01f24..019db48 100644 --- a/src/chars/charsHighlighter.ts +++ b/src/chars/charsHighlighter.ts @@ -4,7 +4,7 @@ import type { CharsElement } from '../..'; import { getElementsToHighlight } from './getElementsToHighlight'; import { wrapHighlightedChars } from './wrapHighlightedChars'; import { toString } from 'hast-util-to-string'; -import { hasOwnProperty, isElement } from '../utils'; +import { isElement } from '../utils'; /** * Loops through the child nodes and finds the nodes that make up the chars. @@ -73,7 +73,7 @@ export function charsHighlighter( const props = isElement(childNode) ? childNode.properties : {}; if ( props && - !hasOwnProperty(props, 'rehype-pretty-code-visited') && + !Object.hasOwn(props, 'rehype-pretty-code-visited') && !Object.hasOwn(props, 'data-highlighted-chars-mark') ) { return toString(childNode); @@ -82,19 +82,12 @@ export function charsHighlighter( .join(''); } } + }); - element.children.forEach((childNode) => { - if (!isElement(childNode)) { - return; - } - - if ( - hasOwnProperty(childNode.properties ?? {}, 'rehype-pretty-code-visited') - ) { - if (childNode.properties) { - delete childNode.properties['rehype-pretty-code-visited']; - } - } - }); + element.children.forEach((childNode) => { + if (!isElement(childNode)) return; + if (Object.hasOwn(childNode.properties, 'rehype-pretty-code-visited')) { + delete childNode.properties['rehype-pretty-code-visited']; + } }); } diff --git a/src/chars/getElementsToHighlight.ts b/src/chars/getElementsToHighlight.ts index 0856d41..6ca6e01 100644 --- a/src/chars/getElementsToHighlight.ts +++ b/src/chars/getElementsToHighlight.ts @@ -5,7 +5,6 @@ import { getContent, nextElementMaybeContinuesChars, } from './utils'; -import { hasOwnProperty } from '../utils'; export function getElementsToHighlight( element: Element, @@ -32,7 +31,7 @@ export function getElementsToHighlight( !maybeElement || maybeElement.type !== 'element' || // ignore any previously matched chars within - hasOwnProperty( + Object.hasOwn( maybeElement.properties ?? {}, 'rehype-pretty-code-visited', ) diff --git a/src/index.ts b/src/index.ts index 91ad984..adcf4fb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -20,7 +20,6 @@ import { isInlineCode, getThemeNames, replaceLineClass, - hasOwnProperty, } from './utils'; interface ApplyProps { @@ -111,7 +110,7 @@ function apply( } } - if (hasOwnProperty(code.properties, 'data-line-numbers')) { + if (Object.hasOwn(code.properties, 'data-line-numbers')) { code.properties['data-line-numbers-max-digits'] = lineNumbersMaxDigits.toString().length; } diff --git a/src/utils.ts b/src/utils.ts index 4a67063..4fc2fe6 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -4,7 +4,7 @@ import type { Theme } from '..'; // eslint-disable-next-line @typescript-eslint/no-explicit-any export function isJSONTheme(value: any): value is ThemeRegistrationRaw { - return value ? hasOwnProperty(value, 'tokenColors') : false; + return value ? Object.hasOwn(value, 'tokenColors') : false; } export function isElement( @@ -17,13 +17,6 @@ export function isText(value: ElementContent | null): value is Text { return value ? value.type === 'text' : false; } -export function hasOwnProperty( - object: Record, - string: string, -) { - return {}.hasOwnProperty.call(object, string); -} - export function isInlineCode( element: Element, parent: Element | Root | undefined, diff --git a/test/fixtures/highlightedCharsLoop.md b/test/fixtures/highlightedCharsLoop.md new file mode 100644 index 0000000..604283c --- /dev/null +++ b/test/fixtures/highlightedCharsLoop.md @@ -0,0 +1,8 @@ +# Highlighted chars loop + +Overlapping chars should not cause infinite loop + +```js /carrot/ /car/ +const carrot = 'carrot'; +const car = 'car'; +``` diff --git a/test/results/highlightedCharsLoop.html b/test/results/highlightedCharsLoop.html new file mode 100644 index 0000000..826f2a0 --- /dev/null +++ b/test/results/highlightedCharsLoop.html @@ -0,0 +1,64 @@ + + +

Highlighted chars loop

+

Overlapping chars should not cause infinite loop

+
+
const carrot = 'carrot';
+const car = 'car';
+