Skip to content

Commit

Permalink
chore: detect circular aliases
Browse files Browse the repository at this point in the history
  • Loading branch information
P0lip committed Jun 28, 2021
1 parent fd4bb00 commit 7b7ddf0
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 1 deletion.
26 changes: 26 additions & 0 deletions packages/core/src/ruleset/__tests__/ruleset.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1011,6 +1011,32 @@ describe('Ruleset', () => {
).toThrowError(ReferenceError('Alias "PathItem-" does not exist'));
});

it('given circular alias, should throw', () => {
expect(
print.bind(
null,
new Ruleset({
aliases: {
Root: '#Info',
Info: '#Root.test',
Contact: '#Info',
Test: '#Contact.test',
},
rules: {
'valid-path': {
given: '#Test',
then: {
function: truthy,
},
},
},
}),
),
).toThrowError(
ReferenceError('Alias "Test" is circular. Resolution stack: Test -> Contact -> Info -> Root -> Info'),
);
});

it('should refuse to resolve externally defined aliases', () => {
expect(
print.bind(
Expand Down
11 changes: 10 additions & 1 deletion packages/core/src/ruleset/rule/rule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,22 @@ export class Rule implements IRule {
#resolveAlias(this: Rule, expr: string): string {
let resolvedExpr = expr;

const stack = new Set<string>();

while (resolvedExpr.startsWith('#')) {
const alias = ALIAS.exec(resolvedExpr)?.[1];

if (alias === void 0 || alias === null) {
throw new ReferenceError(`"${this.name}" references an invalid alias`);
throw new ReferenceError(`"${this.name}" rule references an invalid alias`);
}

if (stack.has(alias)) {
const _stack = [...stack, alias];
throw new ReferenceError(`Alias "${_stack[0]}" is circular. Resolution stack: ${_stack.join(' -> ')}`);
}

stack.add(alias);

if (this.owner.aliases === null || !(alias in this.owner.aliases)) {
throw new ReferenceError(`Alias "${alias}" does not exist`);
}
Expand Down

0 comments on commit 7b7ddf0

Please sign in to comment.