From a5d1b2c6a4ac05a6cd9f01c6a00fc5f3c5aa42ef Mon Sep 17 00:00:00 2001 From: Ferit Date: Thu, 8 Oct 2026 04:46:58 +0300 Subject: [PATCH] fix: bound unclosed comment source positions to input --- lib/safe-parser.js | 11 ++++++----- test/parse.test.js | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/lib/safe-parser.js b/lib/safe-parser.js index d43b633..4a26c24 100644 --- a/lib/safe-parser.js +++ b/lib/safe-parser.js @@ -8,13 +8,12 @@ class SafeParser extends Parser { comment(token) { let node = new Comment() this.init(node, token[2]) - let pos = - this.input.fromOffset(token[3]) || - this.input.fromOffset(this.input.css.length - 1) + let end = Math.min(token[3], this.input.css.length - 1) + let pos = this.input.fromOffset(end) node.source.end = { column: pos.col, line: pos.line, - offset: token[3] + 1 + offset: end + 1 } let text = token[1].slice(2) @@ -54,7 +53,9 @@ class SafeParser extends Parser { this.current = this.current.parent this.current.raws.after = '' } - this.root.source.end = this.getPosition(this.tokenizer.position()) + this.root.source.end = this.getPosition( + Math.min(this.tokenizer.position(), this.input.css.length) + ) } precheckMissedSemicolon(tokens) { diff --git a/test/parse.test.js b/test/parse.test.js index b1d86ea..6e0acbb 100644 --- a/test/parse.test.js +++ b/test/parse.test.js @@ -34,6 +34,26 @@ test('fixes unclosed comment in safe mode', () => { equal(root.first.first.text, 'b') }) +test('keeps unclosed comment source positions inside the original input', () => { + let css = 'a {\n /* unfinished' + let root = parse(css) + let comment = root.first.first + deepStrictEqual(comment.source.end, { + column: 15, + line: 2, + offset: css.length + }) + deepStrictEqual(root.source.end, { + column: 16, + line: 2, + offset: css.length + }) + equal(comment.source.input.css.slice( + comment.source.start.offset, + comment.source.end.offset + ), '/* unfinished') +}) + test('fixes column and semicolumn case', () => { equal(parse('a{:;}').toString(), 'a{}') })