Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: prevent embedding any (.) in charClass #86

Merged
merged 1 commit into from
Apr 29, 2024
Merged
Show file tree
Hide file tree
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
8 changes: 2 additions & 6 deletions src/constructs/__tests__/character-class.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,22 +90,18 @@ test('`charClass` throws on negated arguments', () => {
});

test('`charClass` joins character escapes', () => {
expect(charClass(any)).toEqualRegex(/./);
expect(charClass(word)).toEqualRegex(/\w/);
expect(charClass(digit)).toEqualRegex(/\d/);
expect(charClass(whitespace)).toEqualRegex(/\s/);
expect(charClass(nonWord)).toEqualRegex(/\W/);
expect(charClass(nonDigit)).toEqualRegex(/\D/);
expect(charClass(nonWhitespace)).toEqualRegex(/\S/);

expect(charClass(any, whitespace)).toEqualRegex(/[.\s]/);
expect(charClass(any, nonWhitespace)).toEqualRegex(/[.\S]/);
expect(charClass(whitespace, nonWhitespace)).toEqualRegex(/[\s\S]/);

expect(charClass(word, whitespace)).toEqualRegex(/[\w\s]/);
expect(charClass(any, word, digit)).toEqualRegex(/[.\w\d]/);

expect(charClass(word, digit, whitespace)).toEqualRegex(/[\w\d\s]/);
expect(charClass(any, word, digit, whitespace)).toEqualRegex(/[.\w\d\s]/);
expect(charClass(word, nonDigit)).toEqualRegex(/[\w\D]/);
});

test('`charRange` pattern', () => {
Expand Down
14 changes: 7 additions & 7 deletions src/constructs/character-class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ export interface CharacterRange {
end: string;
}

export const any: CharacterClass = {
type: 'characterClass',
escape: '.',
chars: [],
ranges: [],
isNegated: false,
encode: encodeCharacterClass,
/**
* Matches any single character.
* Cannot be used as a part of character class.
*/
export const any: EncodeResult = {
precedence: 'atom',
pattern: '.',
};

export const digit: CharacterClass = {
Expand Down
6 changes: 5 additions & 1 deletion src/encoder/encoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ function encodeNode(element: RegexElement): EncodeResult {
return encodeRegExp(element);
}

if (typeof element.encode !== 'function') {
if (typeof element === 'object' && 'pattern' in element) {
return element;
}

if (typeof element === 'object' && typeof element.encode !== 'function') {
throw new Error(`\`encodeNode\`: unknown element type ${element.type}`);
}

Expand Down
2 changes: 1 addition & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export type RegexSequence = RegexElement[] | RegexElement;
/**
* Fundamental building block of a regular expression, defined as either a regex construct or a string.
*/
export type RegexElement = RegexConstruct | string | RegExp;
export type RegexElement = RegexConstruct | EncodeResult | string | RegExp;

/**
* Common interface for all regex constructs like character classes, quantifiers, and anchors.
Expand Down
Loading