Skip to content

Commit

Permalink
Fix false positive parsing error (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
scripthunter7 authored Feb 22, 2023
1 parent d08d03c commit 2dd9bfe
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 11 deletions.
26 changes: 15 additions & 11 deletions src/syntax/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,17 +90,21 @@ const numberOrSelector = {
* @see {@link https://github.com/csstree/csstree/blob/master/lib/syntax/pseudo/index.js}
*/
parse() {
return this.createSingleNodeList(
// If the next token is a number, parse it as a number,
// otherwise parse it as a selector as fallback
// * PLEASE NOTE: If the number parsing is failed, CSSTree
// * will throw an "internal error" via "onParsingError"
// * callback.
// * See: https://github.com/csstree/csstree/blob/master/docs/parsing.md#onparseerror
// * This not a breaking issue, because the parsing will
// * continue its work.
this.parseWithFallback(this.Number, this.Selector),
);
// Save the current token index
const startToken = this.tokenIndex;

// Don't use "parseWithFallback" here, because we don't want to
// throw parsing error, if just the number parsing fails.
try {
// Try to parse :upward()'s argument as a number, but if it fails,
// that's not a problem, because we can try to parse it as a selector.
return this.createSingleNodeList(this.Number.call(this));
} catch (error) {
// If the number parsing fails, then we try to parse a selector.
// If the selector parsing fails, then an error will be thrown,
// because the argument is invalid.
return this.createSingleNodeList(this.Selector.call(this, startToken));
}
},
};

Expand Down
20 changes: 20 additions & 0 deletions test/syntax/upward.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -220,4 +220,24 @@ describe(':upward()', () => {
'div:upward(.something+#another)',
);
});

test('no false positive parsing errors', () => {
// "Local" parser config for this test
const localParserConfig = {
...parserConfig,
onParseError: (error) => {
throw error;
},
};

expect(() => parse('div:upward(0)', localParserConfig)).not.toThrow();
expect(() => parse('div:upward(42)', localParserConfig)).not.toThrow();
expect(() => parse('div:upward(.something + #another)', localParserConfig)).not.toThrow();
expect(
() => parse(
'div:upward(div + :-abp-has(> a[href^="https://example.com/"]) + div)',
localParserConfig,
),
).not.toThrow();
});
});

0 comments on commit 2dd9bfe

Please sign in to comment.