From d33c066e8c5d837a690c58b688d23f9be8a835ce Mon Sep 17 00:00:00 2001 From: dom111 Date: Wed, 11 May 2022 20:40:36 +0100 Subject: [PATCH] Fix UTF-8 interoprtability. --- js/IO.ts | 1 - js/Inputs/Code.ts | 2 +- js/Renderers/Abstract.ts | 11 +++++++++-- js/Renderers/IFrame.ts | 14 ++++++++++++-- js/UI.ts | 8 ++++---- js/replaceBinaryBytes.ts | 2 +- 6 files changed, 27 insertions(+), 11 deletions(-) diff --git a/js/IO.ts b/js/IO.ts index 50a063f..79e4991 100644 --- a/js/IO.ts +++ b/js/IO.ts @@ -1,5 +1,4 @@ import { Editor } from 'codemirror'; -import { decoders } from './Decoders'; import Renderers from './Renderers'; export class IO { diff --git a/js/Inputs/Code.ts b/js/Inputs/Code.ts index 5f9616e..6063013 100644 --- a/js/Inputs/Code.ts +++ b/js/Inputs/Code.ts @@ -63,7 +63,7 @@ export class Code extends Abstract implements Input { } public readAsString(binaryReplacementChar: string | null = '.'): string { - const code = this.editor.getValue(); + const code = unescape(encodeURIComponent(this.editor.getValue())); if (binaryReplacementChar === null) { return code; diff --git a/js/Renderers/Abstract.ts b/js/Renderers/Abstract.ts index 91e8484..3f427cc 100644 --- a/js/Renderers/Abstract.ts +++ b/js/Renderers/Abstract.ts @@ -13,10 +13,17 @@ export abstract class Abstract implements Renderer { this.resize(); } - protected createElement(tag: string = 'div'): HTMLElement { + protected createElement(tag: 'div', hidden?: boolean): HTMLDivElement; + protected createElement(tag: 'iframe', hidden?: boolean): HTMLIFrameElement; + protected createElement( + tag: string = 'div', + hidden: boolean = true + ): HTMLElement { const element = document.createElement(tag); - element.setAttribute('hidden', ''); + if (hidden) { + element.setAttribute('hidden', ''); + } return element; } diff --git a/js/Renderers/IFrame.ts b/js/Renderers/IFrame.ts index 5e8ada2..ebd4076 100644 --- a/js/Renderers/IFrame.ts +++ b/js/Renderers/IFrame.ts @@ -9,7 +9,7 @@ export class IFrame extends Abstract implements Renderer { public constructor(parent: HTMLElement) { super(); - this.container = this.createElement('iframe') as HTMLIFrameElement; + this.container = this.createElement('iframe'); parent.append(this.container); @@ -43,7 +43,17 @@ export class IFrame extends Abstract implements Renderer { } private update(): void { - this.container.src = `data:${this.mimeType};base64,${btoa(this.buffer)}`; + // We need to destroy and recreate the IFrame so that we don't clobber the back button. + const container = this.createElement( + 'iframe', + this.container.hasAttribute('hidden') + ); + + container.src = `data:${this.mimeType};base64,${btoa(this.buffer)}`; + + this.container.replaceWith(container); + + this.container = container; } } diff --git a/js/UI.ts b/js/UI.ts index 47eaf15..2b9ca99 100644 --- a/js/UI.ts +++ b/js/UI.ts @@ -553,11 +553,11 @@ export class UI { } this.setLang(data.lang ?? this.getLangId()); - this.codeHeader.write(data.header ?? ''); - this.code.write(data.code ?? ''); - this.codeFooter.write(data.footer ?? ''); + this.codeHeader.write(decodeURIComponent(escape(data.header ?? ''))); + this.code.write(decodeURIComponent(escape(data.code ?? ''))); + this.codeFooter.write(decodeURIComponent(escape(data.footer ?? ''))); this.io.setArgs(data.args ?? ''); - this.io.setStdin(data.input ?? ''); + this.io.setStdin(decodeURIComponent(escape(data.input ?? ''))); if (data.mime) { this.setMimeType(data.mime); diff --git a/js/replaceBinaryBytes.ts b/js/replaceBinaryBytes.ts index fdc01da..7ebe0af 100644 --- a/js/replaceBinaryBytes.ts +++ b/js/replaceBinaryBytes.ts @@ -1,5 +1,5 @@ // Don't replace newlines export const replaceBinaryBytes = (code: string, replacement: string = '.') => - code.replace(/[\x00-\x09\x0b-\x1f\x7f-\xff]/g, replacement); + code.replace(/[^\x09\x0a\x20-\x7e]/g, replacement); export default replaceBinaryBytes;