From 125d1db0873cfb10ffca45ffa7c134575a1779b1 Mon Sep 17 00:00:00 2001 From: Thomas Weber Date: Sat, 28 Aug 2021 21:35:29 -0500 Subject: [PATCH 1/6] Rename Dropper to DropArea --- src/scaffolding/{dropper.js => drop-area.js} | 4 ++-- src/scaffolding/monitor.js | 4 ++-- src/scaffolding/question.js | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) rename src/scaffolding/{dropper.js => drop-area.js} (95%) diff --git a/src/scaffolding/dropper.js b/src/scaffolding/drop-area.js similarity index 95% rename from src/scaffolding/dropper.js rename to src/scaffolding/drop-area.js index 0f23dae..b537f85 100644 --- a/src/scaffolding/dropper.js +++ b/src/scaffolding/drop-area.js @@ -1,7 +1,7 @@ import styles from './style.css'; import {readAsText} from '../common/readers'; -class Dropper { +class DropArea { constructor (el, callback) { this.el = el; this.callback = callback; @@ -32,4 +32,4 @@ class Dropper { } } -export default Dropper; +export default DropArea; diff --git a/src/scaffolding/monitor.js b/src/scaffolding/monitor.js index d47de67..27aca4b 100644 --- a/src/scaffolding/monitor.js +++ b/src/scaffolding/monitor.js @@ -1,5 +1,5 @@ import ContextMenu from './context-menu'; -import Dropper from './dropper'; +import DropArea from './drop-area'; import styles from './style.css'; import {readAsText} from '../common/readers'; @@ -269,7 +269,7 @@ class ListMonitor extends Monitor { this.root.appendChild(this.rowsOuter); this.root.appendChild(this.footer); - this.dropper = new Dropper(this.rowsOuter, this.dropperCallback.bind(this)); + this.dropper = new DropArea(this.rowsOuter, this.dropperCallback.bind(this)); this.handleImport = this.handleImport.bind(this); this.handleExport = this.handleExport.bind(this); diff --git a/src/scaffolding/question.js b/src/scaffolding/question.js index 0512ad7..05bb3c3 100644 --- a/src/scaffolding/question.js +++ b/src/scaffolding/question.js @@ -1,4 +1,4 @@ -import Dropper from './dropper'; +import DropArea from './drop-area'; import styles from './style.css'; class Question { @@ -25,7 +25,7 @@ class Question { this.input.className = styles.questionInput; this.input.addEventListener('keypress', this.onkeypress.bind(this)); - this.dropper = new Dropper(this.input, this.dropperCallback.bind(this)); + this.dropper = new DropArea(this.input, this.dropperCallback.bind(this)); this.submitButton = document.createElement('button'); this.submitButton.className = styles.questionSubmitButton; From 29e6955499e52846f66ff34826decd410a30b141 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 28 Aug 2021 21:52:30 -0500 Subject: [PATCH 2/6] Bump svelte from 3.42.3 to 3.42.4 (#139) Bumps [svelte](https://github.com/sveltejs/svelte) from 3.42.3 to 3.42.4. - [Release notes](https://github.com/sveltejs/svelte/releases) - [Changelog](https://github.com/sveltejs/svelte/blob/master/CHANGELOG.md) - [Commits](https://github.com/sveltejs/svelte/compare/v3.42.3...v3.42.4) --- updated-dependencies: - dependency-name: svelte dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index de70d98..8f9e5ee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10592,9 +10592,9 @@ } }, "svelte": { - "version": "3.42.3", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.42.3.tgz", - "integrity": "sha512-pbdtdNZEx2GBqSM6XEgPoHbwtvWBwFLt/1bRmzsyXZO+i424wFnPe7O5B3GOJDPFSxPRztumAW3mL5LPzecWUg==" + "version": "3.42.4", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.42.4.tgz", + "integrity": "sha512-DqC0AmDdBrrbIA+Kzl3yhBb6qCn4vZOAfxye2pTnIpinLegyagC5sLI8Pe9GPlXu9VpHBXIwpDDedpMfu++epA==" }, "svelte-dev-helper": { "version": "1.1.9", diff --git a/package.json b/package.json index 3ce04cc..07ca9ed 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "scratch-svg-renderer": "git://github.com/TurboWarp/scratch-svg-renderer.git#develop", "scratch-vm": "git://github.com/TurboWarp/scratch-vm.git#develop", "sha.js": "^2.4.11", - "svelte": "^3.42.3" + "svelte": "^3.42.4" }, "devDependencies": { "@babel/core": "^7.15.0", From f33bf02f7b49dfd860f52b190c7364c032659be4 Mon Sep 17 00:00:00 2001 From: Thomas Weber Date: Sat, 28 Aug 2021 22:01:02 -0500 Subject: [PATCH 3/6] Fix right click list > import --- src/scaffolding/monitor.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/scaffolding/monitor.js b/src/scaffolding/monitor.js index 27aca4b..35a0c15 100644 --- a/src/scaffolding/monitor.js +++ b/src/scaffolding/monitor.js @@ -315,9 +315,7 @@ class ListMonitor extends Monitor { const files = e.target.files; if (files.length === 0) return; const file = files[0]; - readAsText(file).then((text) => { - this.import(reader.result); - }); + readAsText(file).then((text) => this.import(text)); }); fileSelector.click(); } From ed44ca7353b2650adce0540b562909ac0b83d6f2 Mon Sep 17 00:00:00 2001 From: Thomas Weber Date: Sat, 28 Aug 2021 22:06:01 -0500 Subject: [PATCH 4/6] Don't accept non-sb[2|3] dropped projects --- src/p4/SelectProject.svelte | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/p4/SelectProject.svelte b/src/p4/SelectProject.svelte index 22d2123..9379a7f 100644 --- a/src/p4/SelectProject.svelte +++ b/src/p4/SelectProject.svelte @@ -134,9 +134,12 @@ e.target.select(); }; const handleDrop = ({detail: dataTransfer}) => { - $type = 'file'; - files = dataTransfer.files; - fileInputElement.files = files; + const name = dataTransfer.files[0].name; + if (name.endsWith('.sb') || name.endsWith('.sb2') || name.endsWith('.sb3')) { + $type = 'file'; + files = dataTransfer.files; + fileInputElement.files = files; + } }; From 1904ebf83022a33be01d533272fcd8828ddb986b Mon Sep 17 00:00:00 2001 From: Thomas Weber Date: Sat, 28 Aug 2021 22:22:52 -0500 Subject: [PATCH 5/6] Make sure invalid projects throw an error as soon as possible --- src/packager/download-project.js | 24 ++++++++++++++---------- test/packager/download-project.test.js | 9 +++++++++ test/packager/projects/invalid.txt | 1 + 3 files changed, 24 insertions(+), 10 deletions(-) create mode 100644 test/packager/projects/invalid.txt diff --git a/src/packager/download-project.js b/src/packager/download-project.js index da873a8..394147e 100644 --- a/src/packager/download-project.js +++ b/src/packager/download-project.js @@ -12,6 +12,16 @@ const identifyProjectType = (projectData) => { return null; }; +const isScratch1Project = (uint8array) => { + const MAGIC = 'ScratchV'; + for (let i = 0; i < MAGIC.length; i++) { + if (uint8array[i] !== MAGIC.charCodeAt(i)) { + return false; + } + } + return true; +}; + const unknownAnalysis = () => ({ stageVariables: {}, usesMusic: true @@ -270,15 +280,11 @@ const downloadProject = async (data, progressCallback) => { }); analysis = downloaded.analysis; } else { - // It's a binary blob blob = new Blob([data]); - let zip; - try { - zip = await JSZip.loadAsync(data); - } catch (e) { - // It's a Scratch 1 project, probably - } - if (zip) { + if (isScratch1Project(bufferView)) { + analysis = unknownAnalysis(); + } else { + const zip = await JSZip.loadAsync(data); const projectDataFile = zip.file('project.json'); const projectDataText = await projectDataFile.async('text'); const projectData = JSON.parse(projectDataText); @@ -288,8 +294,6 @@ const downloadProject = async (data, progressCallback) => { } else { analysis = analyzeScratch2(projectData); } - } else { - analysis = unknownAnalysis(); } } diff --git a/test/packager/download-project.test.js b/test/packager/download-project.test.js index 859524c..fa08b36 100644 --- a/test/packager/download-project.test.js +++ b/test/packager/download-project.test.js @@ -60,3 +60,12 @@ test('sb', async () => { expect(project.blob.size).toBe(554); expect(project.type).toBe('blob'); }); + +test('invalid project', async () => { + try { + await downloadProject(readTestProject('invalid.txt'), () => {}); + } catch (e) { + return; + } + throw new Error('Expected error, got success'); +}); diff --git a/test/packager/projects/invalid.txt b/test/packager/projects/invalid.txt new file mode 100644 index 0000000..590847a --- /dev/null +++ b/test/packager/projects/invalid.txt @@ -0,0 +1 @@ +I am not a valid project From 0cf8608c396f46f18abc16c92a35a075b6e5b119 Mon Sep 17 00:00:00 2001 From: Thomas Weber Date: Sat, 28 Aug 2021 22:23:52 -0500 Subject: [PATCH 6/6] Don't expose jszip error message to users --- src/packager/download-project.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/packager/download-project.js b/src/packager/download-project.js index 394147e..0495e97 100644 --- a/src/packager/download-project.js +++ b/src/packager/download-project.js @@ -284,7 +284,13 @@ const downloadProject = async (data, progressCallback) => { if (isScratch1Project(bufferView)) { analysis = unknownAnalysis(); } else { - const zip = await JSZip.loadAsync(data); + let zip; + try { + zip = await JSZip.loadAsync(data); + } catch (e) { + console.warn(e); + throw new Error('Cannot parse project'); + } const projectDataFile = zip.file('project.json'); const projectDataText = await projectDataFile.async('text'); const projectData = JSON.parse(projectDataText);