Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 20 additions & 6 deletions src/rules.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
const noopTest = { exec: () => null } as unknown as RegExp;

function cachedIndentRegex(createRegex: (indent: number) => RegExp) {
const cache: RegExp[] = [];
return (indent: number) => {
const cappedIndent = Math.min(3, indent - 1);
const cacheIndex = cappedIndent + 1;
Comment on lines +6 to +7
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

While indent is expected to be at least 1 in the current implementation of Tokenizer.ts, calculating cappedIndent as Math.min(3, indent - 1) can result in a negative value if indent is 0. This would cause createRegex(-1) to be called, which leads to a SyntaxError when constructing the RegExp (e.g., new RegExp("^ {0,-1}")).

Additionally, using Math.max(0, ...) ensures that cacheIndex is always a non-negative integer, making the array access more predictable.

Suggested change
const cappedIndent = Math.min(3, indent - 1);
const cacheIndex = cappedIndent + 1;
const cappedIndent = Math.max(0, Math.min(3, indent - 1));
const cacheIndex = cappedIndent;

Comment on lines +6 to +7
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current calculation of cappedIndent can result in a negative value if indent is 0 (e.g., Math.min(3, -1) returns -1). This would cause createRegex to attempt to construct a RegExp with an invalid quantifier (e.g., ^ {0,-1}), which throws a SyntaxError in JavaScript.

While the current tokenizer implementation might ensure indent >= 1, adding a Math.max(0, ...) check makes this helper more robust against future changes or external usage of the exported other rules. This also allows for a simpler cacheIndex mapping.

Suggested change
const cappedIndent = Math.min(3, indent - 1);
const cacheIndex = cappedIndent + 1;
const cappedIndent = Math.max(0, Math.min(3, indent - 1));
const cacheIndex = cappedIndent;

let regex = cache[cacheIndex];
if (!regex) {
regex = createRegex(cappedIndent);
cache[cacheIndex] = regex;
}
return regex;
};
}

function edit(regex: string | RegExp, opt = '') {
let source = typeof regex === 'string' ? regex : regex.source;
const obj = {
Expand Down Expand Up @@ -78,12 +92,12 @@ export const other = {
notSpaceStart: /^\S*/,
endingNewline: /\n$/,
listItemRegex: (bull: string) => new RegExp(`^( {0,3}${bull})((?:[\t ][^\\n]*)?(?:\\n|$))`),
nextBulletRegex: (indent: number) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ \t][^\\n]*)?(?:\\n|$))`),
hrRegex: (indent: number) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`),
fencesBeginRegex: (indent: number) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:\`\`\`|~~~)`),
headingBeginRegex: (indent: number) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}#`),
htmlBeginRegex: (indent: number) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}<(?:[a-z].*>|!--)`, 'i'),
blockquoteBeginRegex: (indent: number) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}>`),
nextBulletRegex: cachedIndentRegex((indent: number) => new RegExp(`^ {0,${indent}}(?:[*+-]|\\d{1,9}[.)])((?:[ \t][^\\n]*)?(?:\\n|$))`)),
hrRegex: cachedIndentRegex((indent: number) => new RegExp(`^ {0,${indent}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`)),
fencesBeginRegex: cachedIndentRegex((indent: number) => new RegExp(`^ {0,${indent}}(?:\`\`\`|~~~)`)),
headingBeginRegex: cachedIndentRegex((indent: number) => new RegExp(`^ {0,${indent}}#`)),
htmlBeginRegex: cachedIndentRegex((indent: number) => new RegExp(`^ {0,${indent}}<(?:[a-z].*>|!--)`, 'i')),
blockquoteBeginRegex: cachedIndentRegex((indent: number) => new RegExp(`^ {0,${indent}}>`)),
};

/**
Expand Down