Skip to content

Commit

Permalink
fix: unsafe regular expression
Browse files Browse the repository at this point in the history
  • Loading branch information
kabeep committed May 4, 2024
1 parent c9b5ffd commit ac8a893
Show file tree
Hide file tree
Showing 19 changed files with 144 additions and 116 deletions.
1 change: 1 addition & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
npm test
1 change: 1 addition & 0 deletions .xo-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"es2021"
],
"rules": {
"unicorn/better-regex": "off",
"unicorn/filename-case": "off",
"unicorn/prefer-string-replace-all": "off",
"@typescript-eslint/consistent-type-definitions": "off",
Expand Down
111 changes: 57 additions & 54 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,56 +1,59 @@
{
"name": "@kabeep/exception",
"version": "1.2.2",
"type": "module",
"description": "Exception is a custom error library for Node.js that provides a more flexible and customizable way of handling errors.",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"files": [
"dist"
],
"scripts": {
"docs": "jsdoc -c jsdoc.config.json",
"lint": "xo src/**/*.ts --fix",
"test": "vitest run",
"coverage": "vitest run --coverage",
"watch": "tsup --watch",
"watch:test": "vitest",
"build": "tsup --dts --treeshake smallest"
},
"devDependencies": {
"@swc/core": "^1.5.0",
"@types/chalk": "^2.2.0",
"@types/chalk-pipe": "^2.0.4",
"@types/node": "^20.12.7",
"@vitest/coverage-istanbul": "^1.5.1",
"docdash": "^2.0.2",
"jsdoc": "^4.0.2",
"ts-node": "^10.9.2",
"tsup": "^8.0.2",
"typescript": "^5.4.5",
"vitest": "^1.5.1",
"xo": "^0.58.0"
},
"dependencies": {
"chalk": "^5.3.0",
"chalk-pipe": "^6.0.0"
},
"author": "Zhang Zixin (kabeep)",
"homepage": "https://github.com/kabeep/exception#readme",
"repository": "git@github.com:kabeep/exception.git",
"bugs": "https://github.com/kabeep/exception/issue",
"keywords": [
"nodejs",
"error",
"pretty error",
"beauty error",
"custom error",
"unexpected",
"exception",
"expectation"
],
"engines": {
"node": ">=14"
},
"license": "MIT"
"name": "@kabeep/exception",
"version": "1.2.2",
"type": "module",
"description": "Exception is a custom error library for Node.js that provides a more flexible and customizable way of handling errors.",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"files": [
"dist"
],
"scripts": {
"docs": "jsdoc -c jsdoc.config.json",
"lint": "xo src/**/*.ts --fix",
"pretest": "npm run lint",
"test": "vitest run",
"coverage": "vitest run --coverage",
"watch": "tsup --watch",
"watch:test": "vitest",
"build": "tsup --dts --treeshake smallest",
"prepare": "husky"
},
"devDependencies": {
"@swc/core": "^1.5.0",
"@types/chalk": "^2.2.0",
"@types/chalk-pipe": "^2.0.4",
"@types/node": "^20.12.7",
"@vitest/coverage-istanbul": "^1.5.1",
"docdash": "^2.0.2",
"husky": "^9.0.11",
"jsdoc": "^4.0.2",
"ts-node": "^10.9.2",
"tsup": "^8.0.2",
"typescript": "^5.4.5",
"vitest": "^1.5.1",
"xo": "^0.58.0"
},
"dependencies": {
"chalk": "^5.3.0",
"chalk-pipe": "^6.0.0"
},
"author": "Zhang Zixin (kabeep)",
"homepage": "https://github.com/kabeep/exception#readme",
"repository": "git@github.com:kabeep/exception.git",
"bugs": "https://github.com/kabeep/exception/issue",
"keywords": [
"nodejs",
"error",
"pretty error",
"beauty error",
"custom error",
"unexpected",
"exception",
"expectation"
],
"engines": {
"node": ">=14"
},
"license": "MIT"
}
6 changes: 3 additions & 3 deletions src/core/TraceError.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { basename, dirname } from 'node:path';
import { normalizeNumber, normalizePath, normalizeTrack } from '../helpers/index.js';
import { getAddress, normalizeNumber, normalizePath, normalizeTrack } from '../helpers/index.js';
import type { TraceOption } from '../shared/index.js';
import PaletteError from './PaletteError.js';

Expand Down Expand Up @@ -71,9 +71,9 @@ export default class TraceError extends PaletteError {
let col: number | undefined;
let packageName = '[current]';

const addressMatch = /\(([^)<>]+)\)(?:,\s<anonymous>:\d+:\d+\))?$/.exec(text);
const addressMatch = getAddress(text);
if (addressMatch) {
address = addressMatch[1].trim();
address = addressMatch.trim();
name = isEval ? 'eval' : text.slice(0, Math.max(0, text.length - address.length - 2)).trim();
} else {
address = text;
Expand Down
25 changes: 25 additions & 0 deletions src/helpers/get-address.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
function getAddress(text: string) {
let index = 0;
let start = -1;
let end = -1;

while (index >= 0) {
const nextIndex = text.slice(Math.max(0, index)).indexOf('(');
index = nextIndex > 0 ? nextIndex + index + 1 : -1;

if (nextIndex > 0) {
start = index;
}
}

if (start === -1) return '';

index = text.slice(Math.max(0, start)).indexOf(')');
if (index === -1) return '';

end = index + start;

return text.slice(start, end);
}

export default getAddress;
2 changes: 1 addition & 1 deletion src/helpers/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export { default as getAddress } from './get-address.js';
export { default as isBgRgb } from './is-bg-rgb.js';
export { default as isNil } from './is-nil.js';
export { default as isRgb } from './is-rgb.js';
export { default as isString } from './is-string.js';
export { default as normalizeNumber } from './normalize-number.js';
Expand Down
12 changes: 4 additions & 8 deletions src/helpers/is-bg-rgb.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import isRgb from './is-rgb.js';

function isBgRgb(value: string): value is string {
if (!value.startsWith('bg')) return false;

const rgbRegular = /^bg\((?:\d{1,3},){2}\d{1,3}\)$/;
const numberRegular = /\d{1,3}/g;

const numberMatch = value.match(numberRegular);
const validNumber = Boolean(numberMatch?.every((item) => Number(item) <= 255));

const validRgb = rgbRegular.test(value.replace(/\s/g, ''));
return validNumber && validRgb;
const rgbValue = value.slice(2).replace(/\s/g, '');
return isRgb(rgbValue);
}

export default isBgRgb;
6 changes: 0 additions & 6 deletions src/helpers/is-nil.ts

This file was deleted.

10 changes: 5 additions & 5 deletions src/helpers/is-rgb.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
function isRgb(value: string): value is string {
const rgbRegular = /^\((?:\d{1,3},){2}\d{1,3}\)$/;
const numberRegular = /\d{1,3}/g;
const rgbRegular = /^\(\d{1,3},\d{1,3},\d{1,3}\)$/;
const validRgb = rgbRegular.test(value.replace(/\s/g, ''));
if (!validRgb) return false;

const numberRegular = /\d{1,3}/g;
const numberMatch = value.match(numberRegular);
const validNumber = Boolean(numberMatch?.every((item) => Number(item) <= 255));

const validRgb = rgbRegular.test(value.replace(/\s/g, ''));
return validNumber && validRgb;
return Boolean(numberMatch?.every((item) => Number(item) <= 255));
}

export default isRgb;
3 changes: 2 additions & 1 deletion src/helpers/normalize-rgb.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
function normalizeRgb(color: string, prefix = ''): [number, number, number] {
const rgb = color.replace(/[\s()]/g, '').replace(new RegExp(`^${prefix}`), '');
const length = color.startsWith(prefix) ? prefix.length : 0;
const rgb = color.replace(/[\s()]/g, '').slice(Math.max(0, length));

const [r, g, b] = rgb.split(',').map(Number);

Expand Down
45 changes: 45 additions & 0 deletions test/helpers/get-address.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { expect, test } from 'vitest';
import getAddress from '../../src/helpers/get-address';

test('getAddress - should return empty string for invalid input', () => {
const text = '';
const result = getAddress(text);
const expected = '';
expect(result).toBe(expected);
});

test('getAddress - should return empty string if no parentheses are found', () => {
const text = 'This is a test string without parentheses';
const result = getAddress(text);
const expected = '';
expect(result).toBe(expected);
});

test('getAddress - should return empty string if parentheses are not closed', () => {
const text = 'This is a test string with an open parenthesis ( but no closing parenthesis';
const result = getAddress(text);
const expected = '';
expect(result).toBe(expected);
});

test('getAddress - should return the content within the parentheses', () => {
const text = 'This is a test string with (some content) within parentheses';
const result = getAddress(text);
const expected = 'some content';
expect(result).toBe(expected);
});

test('getAddress - should return the content within the last set of parentheses', () => {
const text =
'This is a test string with (multiple sets of parentheses) but should return the content within the last one';
const result = getAddress(text);
const expected = 'multiple sets of parentheses';
expect(result).toBe(expected);
});

test('getAddress - should handle nested parentheses and return the content within the outermost set', () => {
const text = 'This is a test string with (nested (parentheses) within parentheses)';
const result = getAddress(text);
const expected = 'parentheses';
expect(result).toBe(expected);
});
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
38 changes: 0 additions & 38 deletions test/utils/is-nil.spec.ts

This file was deleted.

0 comments on commit ac8a893

Please sign in to comment.