From 3bacbca325d23cff015f98ccaf95560b0009a26f Mon Sep 17 00:00:00 2001 From: Asher Date: Wed, 27 Feb 2019 14:40:57 -0600 Subject: [PATCH] Fix images not appearing (iconv encoding issue) Fixed by returning the original buffer from `fs.read` and then just using whatever encoding was passed in to iconv, so this should all work exactly the same now as it does on native Node. --- packages/ide/src/fill/fs.ts | 7 ++- packages/protocol/src/common/util.ts | 66 ++++++++++++++------------ packages/protocol/src/node/evaluate.ts | 12 +++++ packages/vscode/src/fill/iconv-lite.ts | 2 +- 4 files changed, 51 insertions(+), 36 deletions(-) diff --git a/packages/ide/src/fill/fs.ts b/packages/ide/src/fill/fs.ts index e191422f..07f2788c 100644 --- a/packages/ide/src/fill/fs.ts +++ b/packages/ide/src/fill/fs.ts @@ -407,13 +407,12 @@ class FS { return util.promisify(fs.read)(fd, buffer, 0, length, position).then((resp) => { return { bytesRead: resp.bytesRead, - content: (resp.bytesRead < buffer.length ? buffer.slice(0, resp.bytesRead) : buffer).toString("utf8"), + content: resp.bytesRead < buffer.length ? buffer.slice(0, resp.bytesRead) : buffer, }; }); }, fd, length, position).then((resp) => { - const newBuf = Buffer.from(resp.content, "utf8"); - buffer.set(newBuf, offset); - callback(undefined!, resp.bytesRead, newBuf as TBuffer); + buffer.set(resp.content, offset); + callback(undefined!, resp.bytesRead, resp.content as TBuffer); }).catch((ex) => { callback(ex, undefined!, undefined!); }); diff --git a/packages/protocol/src/common/util.ts b/packages/protocol/src/common/util.ts index 9a2998b6..45ff225a 100644 --- a/packages/protocol/src/common/util.ts +++ b/packages/protocol/src/common/util.ts @@ -57,39 +57,43 @@ export const stringify = (arg: any, isError?: boolean): string => { // tslint:di * Parse an event argument. */ export const parse = (arg: string): any => { // tslint:disable-line no-any - if (!arg) { - return arg; - } - - const result = JSON.parse(arg); - - if (result && result.data && result.type) { - switch (result.type) { - // JSON.stringify turns a Buffer into an object but JSON.parse doesn't - // turn it back, it just remains an object. - case "Buffer": - if (Array.isArray(result.data)) { - return Buffer.from(result); - } - break; - // Errors apparently can't be stringified, so we do something similar to - // what happens to buffers and stringify them as regular objects. - case "Error": - if (result.data.message) { - const error = new Error(result.data.message); - // TODO: Can we set the stack? Doing so seems to make it into an - // "invalid object". - if (typeof result.data.code !== "undefined") { - (error as NodeJS.ErrnoException).code = result.data.code; + const convert = (value: any): any => { // tslint:disable-line no-any + if (value && value.data && value.type) { + switch (value.type) { + // JSON.stringify turns a Buffer into an object but JSON.parse doesn't + // turn it back, it just remains an object. + case "Buffer": + if (Array.isArray(value.data)) { + return Buffer.from(value); } - // tslint:disable-next-line no-any - (error as any).originalStack = result.data.stack; + break; + // Errors apparently can't be stringified, so we do something similar to + // what happens to buffers and stringify them as regular objects. + case "Error": + if (value.data.message) { + const error = new Error(value.data.message); + // TODO: Can we set the stack? Doing so seems to make it into an + // "invalid object". + if (typeof value.data.code !== "undefined") { + (error as NodeJS.ErrnoException).code = value.data.code; + } + // tslint:disable-next-line no-any + (error as any).originalStack = value.data.stack; - return error; - } - break; + return error; + } + break; + } } - } - return result; + if (value && typeof value === "object") { + Object.keys(value).forEach((key) => { + value[key] = convert(value[key]); + }); + } + + return value; + }; + + return arg ? convert(JSON.parse(arg)) : arg; }; diff --git a/packages/protocol/src/node/evaluate.ts b/packages/protocol/src/node/evaluate.ts index 58f07baf..562e71d8 100644 --- a/packages/protocol/src/node/evaluate.ts +++ b/packages/protocol/src/node/evaluate.ts @@ -19,6 +19,12 @@ export const evaluate = (connection: SendableConnection, message: NewEvalMessage */ // tslint:disable-next-line no-any const sendResp = (resp: any): void => { + logger.trace(() => [ + "resolve", + field("id", message.getId()), + field("response", stringify(resp)), + ]); + const evalDone = new EvalDoneMessage(); evalDone.setId(message.getId()); evalDone.setResponse(stringify(resp)); @@ -34,6 +40,12 @@ export const evaluate = (connection: SendableConnection, message: NewEvalMessage * Send an exception and call onDispose. */ const sendException = (error: Error): void => { + logger.trace(() => [ + "reject", + field("id", message.getId()), + field("response", stringify(error, true)), + ]); + const evalFailed = new EvalFailedMessage(); evalFailed.setId(message.getId()); evalFailed.setResponse(stringify(error, true)); diff --git a/packages/vscode/src/fill/iconv-lite.ts b/packages/vscode/src/fill/iconv-lite.ts index 92d03690..ac1fcc22 100644 --- a/packages/vscode/src/fill/iconv-lite.ts +++ b/packages/vscode/src/fill/iconv-lite.ts @@ -10,7 +10,7 @@ class IconvLiteDecoderStream extends Transform { super(options); // tslint:disable-next-line no-any this.conv = (iconv as any).getDecoder(options.encoding, undefined); - options.encoding = this.encoding = "utf8"; + this.encoding = options.encoding; } // tslint:disable-next-line no-any