Skip to content

Commit

Permalink
Safer handling for GetLineAndColumnForLocation (#940)
Browse files Browse the repository at this point in the history
* fix(#936): safer handling for GetLineAndColumnForLocation

* chore: add changeset
  • Loading branch information
natemoo-re committed Jan 12, 2024
1 parent 3909ab4 commit 9938bc1
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/kind-cheetahs-listen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@astrojs/compiler': patch
---

Fixes a sourcemap-related crash when using multibyte characters
7 changes: 5 additions & 2 deletions internal/sourcemap/sourcemap.go
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@ func (b *ChunkBuilder) GetLineAndColumnForLocation(location loc.Loc) []int {
for count > 0 {
step := count / 2
i := originalLine + step
if lineOffsetTables[i].byteOffsetToStartOfLine <= location.Start {
if len(lineOffsetTables) > i && lineOffsetTables[i].byteOffsetToStartOfLine <= location.Start {
originalLine = i + 1
count = count - step - 1
} else {
Expand All @@ -629,7 +629,10 @@ func (b *ChunkBuilder) GetLineAndColumnForLocation(location loc.Loc) []int {
line := &lineOffsetTables[originalLine]
originalColumn := int(location.Start - line.byteOffsetToStartOfLine)
if line.columnsForNonASCII != nil && originalColumn >= int(line.byteOffsetToFirstNonASCII) {
originalColumn = int(line.columnsForNonASCII[originalColumn-int(line.byteOffsetToFirstNonASCII)])
newColumn := originalColumn - int(line.byteOffsetToFirstNonASCII)
if len(line.columnsForNonASCII) > newColumn {
originalColumn = int(line.columnsForNonASCII[newColumn])
}
}

// 1-based line, 1-based column
Expand Down
21 changes: 21 additions & 0 deletions packages/compiler/test/parse/multibyte-characters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { test } from 'uvu';
import * as assert from 'uvu/assert';
import { parse } from '@astrojs/compiler';

const FIXTURE = `{foo},`;

test('does not crash', async () => {
const result = await parse(FIXTURE);
assert.ok(result.ast, 'does not crash');
});

test('properly maps the position', async () => {
const {
ast: { children },
} = await parse(FIXTURE);
const text = children[1];
assert.equal(text.position.start.offset, 5, 'properly maps the text start position');
assert.equal(text.position.end.offset, 8, 'properly maps the text end position');
});

test.run();

0 comments on commit 9938bc1

Please sign in to comment.