Skip to content

Commit

Permalink
fix: decoration fails when end.line < start.line #727
Browse files Browse the repository at this point in the history
  • Loading branch information
timothycohen committed Jul 25, 2024
1 parent 31e59d7 commit eb5f57e
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 2 deletions.
9 changes: 9 additions & 0 deletions packages/core/src/transformer-decorations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,21 @@ export function transformerDecorations(): ShikiTransformer {

function normalizePosition(p: OffsetOrPosition): ResolvedPosition {
if (typeof p === 'number') {
if (p < 0 || p > shiki.source.length)
throw new ShikiError(`Invalid decoration offset: ${p}. Code length: ${shiki.source.length}`)

return {
...converter.indexToPos(p),
offset: p,
}
}
else {
const line = converter.lines[p.line]
if (line === undefined)
throw new ShikiError(`Invalid decoration position ${JSON.stringify(p)}. Lines length: ${converter.lines.length}`)
if (p.character < 0 || p.character > line.length)
throw new ShikiError(`Invalid decoration position ${JSON.stringify(p)}. Line ${p.line} length: ${line.length}`)

return {
...p,
offset: converter.posToIndex(p.line, p.character),
Expand Down
38 changes: 36 additions & 2 deletions packages/shiki/test/decorations.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ describe('decorations errors', () => {
],
})
}).rejects
.toThrowErrorMatchingInlineSnapshot(`[TypeError: Cannot read properties of undefined (reading 'length')]`)
.toThrowErrorMatchingInlineSnapshot(`[ShikiError: Invalid decoration position {"line":100,"character":0}. Lines length: 12]`)
})

it('throws when chars overflow', async () => {
Expand All @@ -146,6 +146,40 @@ describe('decorations errors', () => {
],
})
}).rejects
.toThrowErrorMatchingInlineSnapshot(`[ShikiError: Failed to find end index for decoration {"line":0,"character":10,"offset":10}]`)
.toThrowErrorMatchingInlineSnapshot(`[ShikiError: Invalid decoration position {"line":0,"character":10}. Line 0 length: 4]`)

expect(async () => {
await codeToHtml(code, {
theme: 'vitesse-light',
lang: 'ts',
decorations: [
{
start: { line: 2, character: 1 },
end: { line: 1, character: 36 }, // actual position is { line: 2, character: 3, offset 40 }
},
],
})
}).rejects
.toThrowErrorMatchingInlineSnapshot(`[ShikiError: Invalid decoration position {"line":1,"character":36}. Line 1 length: 33]`)
})

it('throws when offset underflows/overflows', async () => {
expect(async () => {
await codeToHtml(code, {
theme: 'vitesse-light',
lang: 'ts',
decorations: [{ start: 1, end: 1000 }],
})
}).rejects
.toThrowErrorMatchingInlineSnapshot(`[ShikiError: Invalid decoration offset: 1000. Code length: 252]`)

expect(async () => {
await codeToHtml(code, {
theme: 'vitesse-light',
lang: 'ts',
decorations: [{ start: -3, end: 5 }],
})
}).rejects
.toThrowErrorMatchingInlineSnapshot(`[ShikiError: Invalid decoration offset: -3. Code length: 252]`)
})
})

0 comments on commit eb5f57e

Please sign in to comment.