From e43bec9f0739c4578097b1e4626f59ac460b0eb5 Mon Sep 17 00:00:00 2001 From: WebFreak001 Date: Tue, 6 Dec 2016 23:53:34 +0100 Subject: [PATCH] Unicode fix #77 --- src/backend/mi_parse.ts | 54 +++++++++++++++++++++++++++++++++++++++-- test/mi_parse.test.ts | 12 ++++++--- 2 files changed, 60 insertions(+), 6 deletions(-) diff --git a/src/backend/mi_parse.ts b/src/backend/mi_parse.ts index b306252..1169c5a 100644 --- a/src/backend/mi_parse.ts +++ b/src/backend/mi_parse.ts @@ -4,6 +4,57 @@ export interface MIInfo { resultRecords: { resultClass: string, results: [string, any][] }; } +var octalMatch = /^[0-7]{3}/; +function parseString(str: string): string { + var ret = new Buffer(str.length * 4); + var bufIndex = 0; + + if (str[0] != '"' || str[str.length - 1] != '"') + throw new Error("Not a valid string"); + str = str.slice(1, -1); + var escaped = false; + for (var i = 0; i < str.length; i++) { + if (escaped) { + var m; + if (str[i] == '\\') + bufIndex += ret.write('\\', bufIndex); + else if (str[i] == '"') + bufIndex += ret.write('"', bufIndex); + else if (str[i] == '\'') + bufIndex += ret.write('\'', bufIndex); + else if (str[i] == 'n') + bufIndex += ret.write('\n', bufIndex); + else if (str[i] == 'r') + bufIndex += ret.write('\r', bufIndex); + else if (str[i] == 't') + bufIndex += ret.write('\t', bufIndex); + else if (str[i] == 'b') + bufIndex += ret.write('\b', bufIndex); + else if (str[i] == 'f') + bufIndex += ret.write('\f', bufIndex); + else if (str[i] == 'v') + bufIndex += ret.write('\v', bufIndex); + else if (str[i] == '0') + bufIndex += ret.write('\0', bufIndex); + else if (m = octalMatch.exec(str.substr(i))) { + ret.writeUInt8(parseInt(m[0], 8), bufIndex++); + i += 2; + } + else + bufIndex += ret.write(str[i], bufIndex); + escaped = false; + } else { + if (str[i] == '\\') + escaped = true; + else if (str[i] == '"') + throw new Error("Not a valid string"); + else + bufIndex += ret.write(str[i], bufIndex); + } + } + return ret.slice(0, bufIndex).toString("utf8"); +} + export class MINode implements MIInfo { token: number; outOfBandRecord: { isStream: boolean, type: string, asyncClass: string, output: [string, any][], content: string }[]; @@ -135,10 +186,9 @@ export function parseMI(output: string): MINode { remaining = remaining.substr(1); stringEnd++; } - // hax let str; try { - str = JSON.parse(output.substr(0, stringEnd)); + str = parseString(output.substr(0, stringEnd)); } catch (e) { str = output.substr(0, stringEnd); diff --git a/test/mi_parse.test.ts b/test/mi_parse.test.ts index c37f618..69fc555 100644 --- a/test/mi_parse.test.ts +++ b/test/mi_parse.test.ts @@ -29,10 +29,14 @@ suite("MI Parse", () => { assert.equal(parsed.token, undefined); assert.equal(parsed.outOfBandRecord.length, 1); assert.equal(parsed.outOfBandRecord[0].isStream, true); - // Hack - assert.equal(parsed.outOfBandRecord[0].content, `"[Depuraci\\303\\263n de hilo usando libthread_db enabled]\\n"`); - // Better Goal: - //assert.equal(parsed.outOfBandRecord[0].content, "[Depuración de hilo usando libthread_db enabled]\n"); + assert.equal(parsed.outOfBandRecord[0].content, "[Depuración de hilo usando libthread_db enabled]\n"); + assert.equal(parsed.resultRecords, undefined); + parsed = parseMI(`~"4\\t std::cout << \\"\\345\\245\\275\\345\\245\\275\\345\\255\\246\\344\\271\\240\\357\\274\\214\\345\\244\\251\\345\\244\\251\\345\\220\\221\\344\\270\\212\\" << std::endl;\\n"`); + assert.ok(parsed); + assert.equal(parsed.token, undefined); + assert.equal(parsed.outOfBandRecord.length, 1); + assert.equal(parsed.outOfBandRecord[0].isStream, true); + assert.equal(parsed.outOfBandRecord[0].content, `4\t std::cout << "好好学习,天天向上" << std::endl;\n`); assert.equal(parsed.resultRecords, undefined); }); test("Empty line", () => {