diff --git a/package-lock.json b/package-lock.json index d04c41a..e1b0325 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1570,6 +1570,12 @@ "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", "dev": true }, + "node_modules/@types/safe-regex": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@types/safe-regex/-/safe-regex-1.1.6.tgz", + "integrity": "sha512-CQ/uPB9fLOPKwDsrTeVbNIkwfUthTWOx0l6uIGwVFjZxv7e68pCW5gtTYFzdJi3EBJp8h8zYhJbTasAbX7gEMQ==", + "dev": true + }, "node_modules/@types/semver": { "version": "7.5.8", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", @@ -6070,6 +6076,14 @@ "node": ">=8.10.0" } }, + "node_modules/regexp-tree": { + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", + "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==", + "bin": { + "regexp-tree": "bin/regexp-tree" + } + }, "node_modules/request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", @@ -6274,6 +6288,14 @@ } ] }, + "node_modules/safe-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", + "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==", + "dependencies": { + "regexp-tree": "~0.1.1" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -7452,12 +7474,14 @@ "license": "MIT", "dependencies": { "comment-parser": "1.4.1", + "safe-regex": "2.1.1", "super-regex": "1.0.0" }, "devDependencies": { "@eslint/js": "9.0.0", "@types/jest": "29.5.12", "@types/node": "20.12.7", + "@types/safe-regex": "1.1.6", "@typescript-eslint/eslint-plugin": "7.6.0", "@typescript-eslint/parser": "7.6.0", "eslint": "9.0.0", diff --git a/packages/doxdox-parser-custom/package.json b/packages/doxdox-parser-custom/package.json index 1046d58..487c173 100644 --- a/packages/doxdox-parser-custom/package.json +++ b/packages/doxdox-parser-custom/package.json @@ -10,6 +10,7 @@ }, "dependencies": { "comment-parser": "1.4.1", + "safe-regex": "2.1.1", "super-regex": "1.0.0" }, "peerDependencies": { @@ -24,6 +25,7 @@ "@eslint/js": "9.0.0", "@types/jest": "29.5.12", "@types/node": "20.12.7", + "@types/safe-regex": "1.1.6", "@typescript-eslint/eslint-plugin": "7.6.0", "@typescript-eslint/parser": "7.6.0", "eslint": "9.0.0", diff --git a/packages/doxdox-parser-custom/src/index.test.ts b/packages/doxdox-parser-custom/src/index.test.ts index eceb586..7a1b9d2 100644 --- a/packages/doxdox-parser-custom/src/index.test.ts +++ b/packages/doxdox-parser-custom/src/index.test.ts @@ -1,4 +1,6 @@ -import parse from './index'; +import safe from 'safe-regex'; + +import parse, { JSDOC_PATTERN, IDENTIFIER_PATTERNS } from './index'; describe('custom parser', () => { describe('parse', () => { @@ -35,6 +37,17 @@ describe('custom parser', () => { }); }); + describe('check regular expressions', () => { + it('jsdoc pattern is safe', () => { + expect(safe(JSDOC_PATTERN)).toBeTruthy(); + }); + it('identifier patterns are safe', () => { + for (let i = 0; i < IDENTIFIER_PATTERNS.length; i += 1) { + expect(safe(IDENTIFIER_PATTERNS[i])).toBeTruthy(); + } + }); + }); + describe('parse example from JSDoc documentation https://jsdoc.app/', () => { // JSDoc Example from https://jsdoc.app/ it('parse amd-module', async () => { diff --git a/packages/doxdox-parser-custom/src/index.ts b/packages/doxdox-parser-custom/src/index.ts index 449978a..15864cd 100644 --- a/packages/doxdox-parser-custom/src/index.ts +++ b/packages/doxdox-parser-custom/src/index.ts @@ -10,9 +10,10 @@ import { firstMatch, matches } from 'super-regex'; const REGEX_TIMEOUT = 1000; -const JSDOC_PATTERN = /(^|[ \t]+)\/\*\*\s*\n?(?:[^*]*(?:\*[^/])?)*\*\//gms; +export const JSDOC_PATTERN = + /(^|[ \t]+)\/\*\*\s*\n?(?:[^*]*(?:\*[^/])?)*\*\//gms; -const IDENTIFIER_PATTERNS = [ +export const IDENTIFIER_PATTERNS = [ /(?:class|function|var|let|const)[ ]+([a-z0-9_]+)[ ]*(?:[={(])?/i, /((?:[a-z0-9_.]+)(\.prototype)?\.(?:[a-z0-9_]+))/i, /[a-z0-9_]+[ ]*as[ ]*([a-z0-9_]+)/i,