From 5679a4b455dcb8e584daaf92d37e1dbab43da53d Mon Sep 17 00:00:00 2001
From: junderw <junderwood@bitcoinbank.co.jp>
Date: Wed, 15 Jan 2020 14:14:02 +0900
Subject: [PATCH] Check write/read Slice out of bounds

---
 src/bufferutils.js       | 9 ++++++++-
 test/bufferutils.spec.ts | 6 ++++++
 ts_src/bufferutils.ts    | 9 ++++++++-
 3 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/src/bufferutils.js b/src/bufferutils.js
index 98adbfb..103ca5e 100644
--- a/src/bufferutils.js
+++ b/src/bufferutils.js
@@ -67,6 +67,9 @@ class BufferWriter {
     this.offset += varuint.encode.bytes;
   }
   writeSlice(slice) {
+    if (this.buffer.length < this.offset + slice.length) {
+      throw new Error('Cannot write slice out of bounds');
+    }
     this.offset += slice.copy(this.buffer, this.offset);
   }
   writeVarSlice(slice) {
@@ -114,8 +117,12 @@ class BufferReader {
     return vi;
   }
   readSlice(n) {
+    if (this.buffer.length < this.offset + n) {
+      throw new Error('Cannot read slice out of bounds');
+    }
+    const result = this.buffer.slice(this.offset, this.offset + n);
     this.offset += n;
-    return this.buffer.slice(this.offset - n, this.offset);
+    return result;
   }
   readVarSlice() {
     return this.readSlice(this.readVarInt());
diff --git a/test/bufferutils.spec.ts b/test/bufferutils.spec.ts
index 2ed80e6..b8f86ab 100644
--- a/test/bufferutils.spec.ts
+++ b/test/bufferutils.spec.ts
@@ -209,6 +209,9 @@ describe('bufferutils', () => {
         testBuffer(bufferWriter, expectedBuffer, expectedOffset);
       });
       testBuffer(bufferWriter, expectedBuffer);
+      assert.throws(() => {
+        bufferWriter.writeSlice(Buffer.from([0, 0]));
+      }, /^Error: Cannot write slice out of bounds$/);
     });
 
     it('writeVarSlice', () => {
@@ -421,6 +424,9 @@ describe('bufferutils', () => {
         const val = bufferReader.readSlice(v.length);
         testValue(bufferReader, val, Buffer.from(v), expectedOffset);
       });
+      assert.throws(() => {
+        bufferReader.readSlice(2);
+      }, /^Error: Cannot read slice out of bounds$/);
     });
 
     it('readVarSlice', () => {
diff --git a/ts_src/bufferutils.ts b/ts_src/bufferutils.ts
index 502745d..23e1c0d 100644
--- a/ts_src/bufferutils.ts
+++ b/ts_src/bufferutils.ts
@@ -78,6 +78,9 @@ export class BufferWriter {
   }
 
   writeSlice(slice: Buffer): void {
+    if (this.buffer.length < this.offset + slice.length) {
+      throw new Error('Cannot write slice out of bounds');
+    }
     this.offset += slice.copy(this.buffer, this.offset);
   }
 
@@ -131,8 +134,12 @@ export class BufferReader {
   }
 
   readSlice(n: number): Buffer {
+    if (this.buffer.length < this.offset + n) {
+      throw new Error('Cannot read slice out of bounds');
+    }
+    const result = this.buffer.slice(this.offset, this.offset + n);
     this.offset += n;
-    return this.buffer.slice(this.offset - n, this.offset);
+    return result;
   }
 
   readVarSlice(): Buffer {