Skip to content

Fix Input#origin() returning incorrect position#2036

Merged
ai merged 3 commits into
postcss:mainfrom
mizdra:fix-column-with-source-map
Jun 28, 2026
Merged

Fix Input#origin() returning incorrect position#2036
ai merged 3 commits into
postcss:mainfrom
mizdra:fix-column-with-source-map

Conversation

@mizdra

@mizdra mizdra commented Mar 24, 2025

Copy link
Copy Markdown
Contributor

fix: #2035

Comment thread lib/input.js
let consumer = this.map.consumer()

let from = consumer.originalPositionFor({ column, line })
let from = consumer.originalPositionFor({ column: column - 1, line })

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The column argument of originalPositionFor is 0-based.

https://github.com/7rulnik/source-map-js?tab=readme-ov-file#sourcemapconsumerprototypeoriginalpositionforgeneratedposition

It is not clear from jsdoc whether the column argument of Input#origin is 1-based or 0-based.

* @param column Column for inclusive start position in input CSS.

However, postcss uses 1-based columns in many APIs. It should be a 1-based column here too.

To convert a 1-based column to a 0-based column, subtract 1.

Comment thread lib/input.js
column: from.column,
endColumn: to && to.column,
column: from.column + 1,
endColumn: to && to.column + 1,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return value column of originalPositionFor is 0-based.

https://github.com/7rulnik/source-map-js?tab=readme-ov-file#sourcemapconsumerprototypeoriginalpositionforgeneratedposition

To convert a 0-based column to a 1-based column, add 1.

Comment thread test/input.test.ts

test('origin() returns source position with source map', () => {
// @ts-expect-error source-map-js accepts null, but it's not in the types (ref: https://github.com/7rulnik/source-map-js/blob/428d49f6b1e1614f082b7706fa879a3d9c64f728/test/test-source-node.js#L20)
let node = new SourceNode(null, null, null, [

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original columns generated by concat-with-sourcemaps are rough. So I used source-map-js.

6a2199b

@mizdra mizdra marked this pull request as ready for review March 24, 2025 15:40
@ai ai merged commit 46e4510 into postcss:main Jun 28, 2026
@ai

ai commented Jun 28, 2026

Copy link
Copy Markdown
Member

Thanks!

@ai

ai commented Jun 28, 2026

Copy link
Copy Markdown
Member

Released in 8.5.16.

@mizdra mizdra deleted the fix-column-with-source-map branch June 29, 2026 04:29
ai pushed a commit that referenced this pull request Jun 30, 2026
…ion (#2106)

When the requested end position has no mapping in the source map,
originalPositionFor() returns an object with line/column set to null
rather than omitting them. endLine picked that null up correctly, but
endColumn was computed as `to && to.column + 1`, which due to operator
precedence is `to && (to.column + 1)`, turning null into 1. So callers
could get back { endColumn: 1, endLine: null }, which doesn't match
how every other unmapped case in this function behaves (undefined for
both). Looks like the +1 fix in #2036 covered the mapped case but not
this one.

Guard `to` the same way `from` already is, so an unmapped end position
just stays undefined.
chida09 added a commit to chida09/happy-css-modules that referenced this pull request Jul 2, 2026
postcss 8.5.16 (postcss/postcss#2036) fixed `Input#origin()` to
correctly accept 1-based columns. The `- 1` workaround in
`getOriginalLocationOfClassSelector` is no longer needed and causes
double subtraction, resulting in `column = -1` which crashes
`source-map-js`.

Fixes mizdra#320
mizdra added a commit to chida09/happy-css-modules that referenced this pull request Jul 2, 2026
…alue

postcss 8.5.16 (postcss/postcss#2036) changed `Input#origin()` to
return 1-based columns as well as accept them. The `+ 1` conversion
in `getOriginalLocationOfClassSelector` is no longer needed and
shifted original locations by one column.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

In CSS with source map, input.origin().column and error.column have wrong values

2 participants