Skip to content

Commit 7721350

Browse files
Akos Kittakittaakos
Akos Kitta
authored andcommitted
fix: encoding when reading a cloud sketch
Closes #449 Closes #634 Signed-off-by: Akos Kitta <a.kitta@arduino.cc>
1 parent bfec85c commit 7721350

File tree

3 files changed

+16
-46
lines changed

3 files changed

+16
-46
lines changed

arduino-ide-extension/src/browser/create/create-api.ts

+3-45
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { MaybePromise } from '@theia/core/lib/common/types';
22
import { inject, injectable } from '@theia/core/shared/inversify';
33
import { fetch } from 'cross-fetch';
44
import { SketchesService } from '../../common/protocol';
5+
import { unit8ArrayToString } from '../../common/utils';
56
import { ArduinoPreferences } from '../arduino-preferences';
67
import { AuthenticationClientService } from '../auth/authentication-client-service';
78
import { SketchCache } from '../widgets/cloud-sketchbook/cloud-sketch-cache';
@@ -19,49 +20,6 @@ export namespace ResponseResultProvider {
1920
export const JSON: ResponseResultProvider = (response) => response.json();
2021
}
2122

22-
// TODO: check if this is still needed: https://github.com/electron/electron/issues/18733
23-
// The original issue was reported for Electron 5.x and 6.x. Theia uses 15.x
24-
export function Utf8ArrayToStr(array: Uint8Array): string {
25-
let out, i, c;
26-
let char2, char3;
27-
28-
out = '';
29-
const len = array.length;
30-
i = 0;
31-
while (i < len) {
32-
c = array[i++];
33-
switch (c >> 4) {
34-
case 0:
35-
case 1:
36-
case 2:
37-
case 3:
38-
case 4:
39-
case 5:
40-
case 6:
41-
case 7:
42-
// 0xxxxxxx
43-
out += String.fromCharCode(c);
44-
break;
45-
case 12:
46-
case 13:
47-
// 110x xxxx 10xx xxxx
48-
char2 = array[i++];
49-
out += String.fromCharCode(((c & 0x1f) << 6) | (char2 & 0x3f));
50-
break;
51-
case 14:
52-
// 1110 xxxx 10xx xxxx 10xx xxxx
53-
char2 = array[i++];
54-
char3 = array[i++];
55-
out += String.fromCharCode(
56-
((c & 0x0f) << 12) | ((char2 & 0x3f) << 6) | ((char3 & 0x3f) << 0)
57-
);
58-
break;
59-
}
60-
}
61-
62-
return out;
63-
}
64-
6523
type ResourceType = 'f' | 'd';
6624

6725
@injectable()
@@ -333,7 +291,7 @@ export class CreateApi {
333291

334292
// parse the secret file
335293
const secrets = (
336-
typeof content === 'string' ? content : Utf8ArrayToStr(content)
294+
typeof content === 'string' ? content : unit8ArrayToString(content)
337295
)
338296
.split(/\r?\n/)
339297
.reduce((prev, curr) => {
@@ -397,7 +355,7 @@ export class CreateApi {
397355
const headers = await this.headers();
398356

399357
let data: string =
400-
typeof content === 'string' ? content : Utf8ArrayToStr(content);
358+
typeof content === 'string' ? content : unit8ArrayToString(content);
401359
data = await this.toggleSecretsInclude(posixPath, data, 'remove');
402360

403361
const payload = { data: btoa(data) };

arduino-ide-extension/src/browser/create/create-fs-provider.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import { CreateUri } from './create-uri';
2929
import { SketchesService } from '../../common/protocol';
3030
import { ArduinoPreferences } from '../arduino-preferences';
3131
import { Create } from './typings';
32+
import { stringToUint8Array } from '../../common/utils';
3233

3334
@injectable()
3435
export class CreateFsProvider
@@ -154,7 +155,7 @@ export class CreateFsProvider
154155

155156
async readFile(uri: URI): Promise<Uint8Array> {
156157
const content = await this.getCreateApi.readFile(uri.path.toString());
157-
return new TextEncoder().encode(content);
158+
return stringToUint8Array(content);
158159
}
159160

160161
async writeFile(

arduino-ide-extension/src/common/utils.ts

+11
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,14 @@ export function startsWithUpperCase(what: string): boolean {
2020
export function isNullOrUndefined(what: unknown): what is undefined | null {
2121
return what === undefined || what === null;
2222
}
23+
24+
// Text encoder can crash in electron browser: https://github.com/arduino/arduino-ide/issues/634#issuecomment-1440039171
25+
export function unit8ArrayToString(uint8Array: Uint8Array): string {
26+
return uint8Array.reduce(
27+
(text, byte) => text + String.fromCharCode(byte),
28+
''
29+
);
30+
}
31+
export function stringToUint8Array(text: string): Uint8Array {
32+
return Uint8Array.from(text, (char) => char.charCodeAt(0));
33+
}

0 commit comments

Comments
 (0)