From 79d77aec15a46c871534bc044ebf814b0f0e2b89 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Fri, 13 Jul 2018 16:38:59 -0700 Subject: [PATCH] Fix Buffer.from uses to handle node 5.4.1 bug --- src/compiler/sys.ts | 23 +++++++++++---------- src/harness/documents.ts | 2 +- src/harness/harness.ts | 5 +---- src/harness/vfs.ts | 4 ++-- src/testRunner/unittests/convertToBase64.ts | 2 +- src/tsserver/server.ts | 4 ++-- 6 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index 0fa06d9d2670f..4edba26333a40 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -503,6 +503,7 @@ namespace ts { /*@internal*/ setBlocking?(): void; base64decode?(input: string): string; base64encode?(input: string): string; + /*@internal*/ bufferFrom?(input: string, encoding?: string): Buffer; } export interface FileWatcher { @@ -558,7 +559,7 @@ namespace ts { getEnvironmentVariable?(name: string): string; }; - // TODO: this is used as if it's certainly defined in many places. + // TODO: GH#18217 this is used as if it's certainly defined in many places. export let sys: System = (() => { // NodeJS detects "\uFEFF" at the start of the string and *replaces* it with the actual // byte order mark from the specified encoding. Using any other byte order mark does @@ -675,19 +676,19 @@ namespace ts { process.stdout._handle.setBlocking(true); } }, - base64decode: Buffer.from ? input => { - return Buffer.from!(input, "base64").toString("utf8"); - } : input => { - return new Buffer(input, "base64").toString("utf8"); - }, - base64encode: Buffer.from ? input => { - return Buffer.from!(input).toString("base64"); - } : input => { - return new Buffer(input).toString("base64"); - } + bufferFrom, + base64decode: input => bufferFrom(input, "base64").toString("utf8"), + base64encode: input => bufferFrom(input).toString("base64"), }; return nodeSystem; + function bufferFrom(input: string, encoding?: string): Buffer { + // See https://github.com/Microsoft/TypeScript/issues/25652 + return Buffer.from && (Buffer.from as Function) !== Int8Array.from + ? Buffer.from(input, encoding) + : new Buffer(input, encoding); + } + function isFileSystemCaseSensitive(): boolean { // win32\win64 are case insensitive platforms if (platform === "win32" || platform === "win64") { diff --git a/src/harness/documents.ts b/src/harness/documents.ts index a1c75784f85ff..312339287e245 100644 --- a/src/harness/documents.ts +++ b/src/harness/documents.ts @@ -148,7 +148,7 @@ namespace documents { public static fromUrl(url: string) { const match = SourceMap._dataURLRegExp.exec(url); - return match ? new SourceMap(/*mapFile*/ undefined, (Buffer.from ? Buffer.from(match[1], "base64") : new Buffer(match[1], "base64")).toString("utf8")) : undefined; + return match ? new SourceMap(/*mapFile*/ undefined, ts.sys.base64decode!(match[1])) : undefined; } public static fromSource(text: string): SourceMap | undefined { diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 4afe48999d1b0..4ccc88b7df556 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -66,11 +66,8 @@ namespace Utils { export let currentExecutionEnvironment = getExecutionEnvironment(); - // Thanks to browserify, Buffer is always available nowadays - const Buffer: typeof global.Buffer = require("buffer").Buffer; - export function encodeString(s: string): string { - return Buffer.from(s).toString("utf8"); + return ts.sys.bufferFrom!(s).toString("utf8"); } export function byteLength(s: string, encoding?: string): number { diff --git a/src/harness/vfs.ts b/src/harness/vfs.ts index ae99187f5fade..ee9519f254c07 100644 --- a/src/harness/vfs.ts +++ b/src/harness/vfs.ts @@ -683,7 +683,7 @@ namespace vfs { if (isDirectory(node)) throw createIOError("EISDIR"); if (!isFile(node)) throw createIOError("EBADF"); - node.buffer = Buffer.isBuffer(data) ? data.slice() : Buffer.from("" + data, encoding || "utf8"); + node.buffer = Buffer.isBuffer(data) ? data.slice() : ts.sys.bufferFrom!("" + data, encoding || "utf8"); node.size = node.buffer.byteLength; node.mtimeMs = time; node.ctimeMs = time; @@ -1204,7 +1204,7 @@ namespace vfs { } }, readFileSync(path: string): Buffer { - return Buffer.from(host.readFile(path)!, "utf8"); // TODO: GH#18217 + return ts.sys.bufferFrom!(host.readFile(path)!, "utf8"); // TODO: GH#18217 } }; } diff --git a/src/testRunner/unittests/convertToBase64.ts b/src/testRunner/unittests/convertToBase64.ts index ecf55d9855b04..56c9562297784 100644 --- a/src/testRunner/unittests/convertToBase64.ts +++ b/src/testRunner/unittests/convertToBase64.ts @@ -2,7 +2,7 @@ namespace ts { describe("convertToBase64", () => { function runTest(input: string): void { const actual = convertToBase64(input); - const expected = (Buffer.from ? Buffer.from(input) : new Buffer(input)).toString("base64"); + const expected = sys.base64encode!(input); assert.equal(actual, expected, "Encoded string using convertToBase64 does not match buffer.toString('base64')"); } diff --git a/src/tsserver/server.ts b/src/tsserver/server.ts index 0a70fb3d83b4f..17f38c3c7ce66 100644 --- a/src/tsserver/server.ts +++ b/src/tsserver/server.ts @@ -199,7 +199,7 @@ namespace ts.server { private write(s: string) { if (this.fd >= 0) { - const buf = Buffer.from ? Buffer.from(s) : new Buffer(s); + const buf = sys.bufferFrom!(s); // tslint:disable-next-line no-null-keyword fs.writeSync(this.fd, buf, 0, buf.length, /*position*/ null!); // TODO: GH#18217 } @@ -869,7 +869,7 @@ namespace ts.server { } // Override sys.write because fs.writeSync is not reliable on Node 4 - sys.write = (s: string) => writeMessage(Buffer.from ? Buffer.from(s, "utf8") : new Buffer(s, "utf8")); + sys.write = (s: string) => writeMessage(sys.bufferFrom!(s, "utf8")); sys.watchFile = (fileName, callback) => { const watchedFile = pollingWatchedFileSet.addFile(fileName, callback); return {