Skip to content

Commit 7c0b663

Browse files
authored
fix: validate update() range and show indices in range errors (#318)
1 parent 15edb20 commit 7c0b663

2 files changed

Lines changed: 28 additions & 2 deletions

File tree

‎src/MagicString.ts‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -577,13 +577,17 @@ export default class MagicString {
577577
while (end < 0) end += this.original.length
578578
}
579579

580+
if (start < 0)
581+
throw new Error('Character is out of bounds')
580582
if (end > this.original.length)
581583
throw new Error('end is out of bounds')
582584
if (start === end) {
583585
throw new Error(
584586
'Cannot overwrite a zero-length range – use appendLeft or prependRight instead',
585587
)
586588
}
589+
if (start > end)
590+
throw new Error(`end must be greater than start (start: ${start}, end: ${end})`)
587591

588592
if (DEBUG)
589593
this.stats.time('overwrite')
@@ -729,7 +733,7 @@ export default class MagicString {
729733
if (start < 0 || end > this.original.length)
730734
throw new Error('Character is out of bounds')
731735
if (start > end)
732-
throw new Error('end must be greater than start')
736+
throw new Error(`end must be greater than start (start: ${start}, end: ${end})`)
733737

734738
if (DEBUG)
735739
this.stats.time('remove')
@@ -770,7 +774,7 @@ export default class MagicString {
770774
if (start < 0 || end > this.original.length)
771775
throw new Error('Character is out of bounds')
772776
if (start > end)
773-
throw new Error('end must be greater than start')
777+
throw new Error(`end must be greater than start (start: ${start}, end: ${end})`)
774778

775779
if (DEBUG)
776780
this.stats.time('reset')

‎test/MagicString.test.ts‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,6 +1164,22 @@ describe('magicString', () => {
11641164
assert.throws(() => s.update(0, 1, []), TypeError)
11651165
})
11661166

1167+
it('should throw when start is greater than end', () => {
1168+
const s = new MagicString('problems = 99')
1169+
assert.throws(() => s.update(9, 5, 'x'), /end must be greater than start \(start: 9, end: 5\)/)
1170+
})
1171+
1172+
it('should report the resolved indices when a negative start lands past end', () => {
1173+
const s = new MagicString('problems = 99')
1174+
// -1 resolves to 12, which is past `end`
1175+
assert.throws(() => s.update(-1, 5, 'x'), /end must be greater than start \(start: 12, end: 5\)/)
1176+
})
1177+
1178+
it('should throw error when using negative indices with empty string', () => {
1179+
const s = new MagicString('')
1180+
assert.throws(() => s.update(-2, -1, 'x'), /Character is out of bounds/)
1181+
})
1182+
11671183
it('replaces interior inserts with overwrite option', () => {
11681184
const s = new MagicString('abcdefghijkl')
11691185

@@ -1365,6 +1381,12 @@ describe('magicString', () => {
13651381
const s = new MagicString('')
13661382
assert.throws(() => s.remove(-2, -1), /Character is out of bounds/)
13671383
})
1384+
1385+
it('should report the resolved indices when a negative start lands past end', () => {
1386+
const s = new MagicString('problems = 99')
1387+
// -1 resolves to 12, which is past `end`
1388+
assert.throws(() => s.remove(-1, 5), /end must be greater than start \(start: 12, end: 5\)/)
1389+
})
13681390
})
13691391

13701392
describe('reset', () => {

0 commit comments

Comments
 (0)