From 10e2f0f37b24e59c20e18b4067e0f7efb6033621 Mon Sep 17 00:00:00 2001 From: Yarchik Date: Wed, 17 Jun 2026 14:53:49 +0100 Subject: [PATCH] fix: do not reuse the opening `*` when closing a comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `indexOf("*/", pos)` started searching at the opening `/`, so the `*` of the opening `/*` could be matched as the `*` of a closing `*/`. As a result `/*/` was parsed as a closed, empty comment instead of an unclosed comment whose content is `/`, and stringifying it produced `/**/` — breaking the lossless round-trip (`/*/` is also a known CSS comment hack). Start the search past the opening delimiter (`pos + 2`). --- lib/parse.js | 2 +- test/index.js | 3 +++ test/parse.js | 13 +++++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/parse.js b/lib/parse.js index 7d343ca..48d2981 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -103,7 +103,7 @@ module.exports = function (input) { // Comments } else if (code === slash && value.charCodeAt(pos + 1) === star) { - next = value.indexOf("*/", pos); + next = value.indexOf("*/", pos + 2); token = { type: "comment", diff --git a/test/index.js b/test/index.js index 2131248..91c10b3 100644 --- a/test/index.js +++ b/test/index.js @@ -7,6 +7,9 @@ describe("ValueParser", () => { const tests = [ " rgba( 34 , 45 , 54, .5 ) ", "w1 w2 w6 \n f(4) ( ) () \t \"s't\" 'st\\\"2'", + "/*/", + "a /*/ b", + "/*/ comment hack /**/", ]; tests.forEach((item) => { diff --git a/test/parse.js b/test/parse.js index 22aa393..1ac8a39 100644 --- a/test/parse.js +++ b/test/parse.js @@ -1683,6 +1683,19 @@ const tests = [ { type: "word", sourceIndex: 0, sourceEndIndex: 3, value: "U+Z" }, ], }, + { + message: "should not reuse the opening star to close a comment", + fixture: "/*/", + expected: [ + { + type: "comment", + sourceIndex: 0, + sourceEndIndex: 3, + value: "/", + unclosed: true, + }, + ], + }, ]; describe("Parse", () => {