From ed5467689acf519ca160ade6a3cbe3b1f7692535 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 9 Oct 2018 08:35:49 -0700 Subject: [PATCH 1/2] Fix infinite loop See Microsoft/vscode#60291 --- src/InputHandler.test.ts | 7 +++++++ src/InputHandler.ts | 6 ++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/InputHandler.test.ts b/src/InputHandler.test.ts index bdd9ccc6..e4314330 100644 --- a/src/InputHandler.test.ts +++ b/src/InputHandler.test.ts @@ -469,4 +469,11 @@ describe('InputHandler', () => { } expect(s).equals('World '); }); + describe('print', () => { + it('should not cause an infinite loop (regression test)', () => { + const term = new Terminal(); + const inputHandler = new InputHandler(term); + inputHandler.print(String.fromCharCode(0x200B), 0, 1); + }); + }); }); diff --git a/src/InputHandler.ts b/src/InputHandler.ts index 400e9b93..ddb20527 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -452,8 +452,10 @@ export class InputHandler extends Disposable implements IInputHandler { // fullwidth char - also set next cell to placeholder stub and advance cursor // for graphemes bigger than fullwidth we can simply loop to zero // we already made sure above, that buffer.x + chWidth will not overflow right - while (--chWidth) { - bufferRow.set(buffer.x++, [curAttr, '', 0, undefined]); + if (chWidth > 0) { + while (--chWidth) { + bufferRow.set(buffer.x++, [curAttr, '', 0, undefined]); + } } } this._terminal.updateRange(buffer.y); From 3877e96d7fe235043c904771c36e82411d65dd09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Tue, 9 Oct 2018 18:56:48 +0200 Subject: [PATCH 2/2] fix BufferLine resize --- src/BufferLine.test.ts | 27 +++++++++++++++++++++++++++ src/BufferLine.ts | 6 +++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/BufferLine.test.ts b/src/BufferLine.test.ts index a1a8e0ff..2db69176 100644 --- a/src/BufferLine.test.ts +++ b/src/BufferLine.test.ts @@ -133,4 +133,31 @@ describe('BufferLine', function(): void { const line3 = line.clone(); chai.expect(TestBufferLine.prototype.toArray.apply(line3)).eql(line.toArray()); }); + it('resize enlarge', function(): void { + const line = new TestBufferLine(5, [1, 'a', 0, 'a'.charCodeAt(0)], false); + line.resize(10, [1, 'a', 0, 'a'.charCodeAt(0)]); + chai.expect(line.toArray()).eql(Array(10).fill([1, 'a', 0, 'a'.charCodeAt(0)])); + }); + it('resize shrink(true)', function(): void { + const line = new TestBufferLine(10, [1, 'a', 0, 'a'.charCodeAt(0)], false); + line.resize(5, [1, 'a', 0, 'a'.charCodeAt(0)], true); + chai.expect(line.toArray()).eql(Array(5).fill([1, 'a', 0, 'a'.charCodeAt(0)])); + }); + it('resize shrink(false)', function(): void { + const line = new TestBufferLine(10, [1, 'a', 0, 'a'.charCodeAt(0)], false); + line.resize(5, [1, 'a', 0, 'a'.charCodeAt(0)], false); + chai.expect(line.toArray()).eql(Array(5).fill([1, 'a', 0, 'a'.charCodeAt(0)])); + }); + it('resize shrink(false) + shrink(false)', function(): void { + const line = new TestBufferLine(20, [1, 'a', 0, 'a'.charCodeAt(0)], false); + line.resize(10, [1, 'a', 0, 'a'.charCodeAt(0)], false); + line.resize(5, [1, 'a', 0, 'a'.charCodeAt(0)], false); + chai.expect(line.toArray()).eql(Array(5).fill([1, 'a', 0, 'a'.charCodeAt(0)])); + }); + it('resize shrink(false) + enlarge', function(): void { + const line = new TestBufferLine(20, [1, 'a', 0, 'a'.charCodeAt(0)], false); + line.resize(10, [1, 'a', 0, 'a'.charCodeAt(0)], false); + line.resize(15, [1, 'a', 0, 'a'.charCodeAt(0)]); + chai.expect(line.toArray()).eql(Array(15).fill([1, 'a', 0, 'a'.charCodeAt(0)])); + }); }); diff --git a/src/BufferLine.ts b/src/BufferLine.ts index 4fdceee1..53f5d4d4 100644 --- a/src/BufferLine.ts +++ b/src/BufferLine.ts @@ -218,7 +218,11 @@ export class BufferLineTypedArray implements IBufferLine { if (cols > this.length) { const data = new Uint32Array(cols * CELL_SIZE); if (this._data) { - data.set(this._data); + if (cols * CELL_SIZE < this._data.length) { + data.set(this._data.subarray(0, cols * CELL_SIZE)); + } else { + data.set(this._data); + } } this._data = data; for (let i = this.length; i < cols; ++i) {