From a6e527986cfc228c3bf8666043a071e06b6a78b2 Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Mon, 20 Jul 2026 00:06:43 -0700 Subject: [PATCH 1/4] CST1229/zip.js -- Use correct MIME type when reading file Data.URIs --- extensions/CST1229/zip.js | 42 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/extensions/CST1229/zip.js b/extensions/CST1229/zip.js index 5fa3d59f1b..49fac3efb4 100644 --- a/extensions/CST1229/zip.js +++ b/extensions/CST1229/zip.js @@ -4,12 +4,39 @@ // By: CST1229 // License: MIT AND MPL-2.0 -(function (Scratch) { +(async function (Scratch) { "use strict"; // @ts-expect-error - not typed yet const JSZip = Scratch.vm.exports.JSZip; + /*! + (The MIT License) + + Copyright (c) 2014 Jonathan Ong + Copyright (c) 2015 Douglas Christopher Wilson + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + 'Software'), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + const MimeTypes = await Scratch.external.importModule("https://cdn.jsdelivr.net/npm/mime-types@2.1.35/+esm"); + const extIcon = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMCAzMCI+PHJlY3Qgd2lkdGg9IjIzIiBoZWlnaHQ9IjIwIiB4PSI2IiB5PSIzIiBmaWxsPSIjZDhkODZjIiBzdHJva2U9IiM3ZDdkMjMiIHN0cm9rZS13aWR0aD0iMiIgcGFpbnQtb3JkZXI9InN0cm9rZSBtYXJrZXJzIGZpbGwiIHJ4PSI0IiByeT0iNCIgc3R5bGU9ImZvbnQtdmFyaWF0aW9uLXNldHRpbmdzOm5vcm1hbCIvPjxyZWN0IHdpZHRoPSIyOCIgaGVpZ2h0PSIyMCIgeD0iMSIgeT0iOCIgZmlsbD0iI2Q4ZDg2YyIgc3Ryb2tlPSIjN2Q3ZDIzIiBzdHJva2Utd2lkdGg9IjIiIHBhaW50LW9yZGVyPSJzdHJva2UgbWFya2VycyBmaWxsIiByeD0iNCIgcnk9IjQiIHN0eWxlPSJmb250LXZhcmlhdGlvbi1zZXR0aW5nczpub3JtYWwiLz48cGF0aCBmaWxsPSIjN2Q3ZDIzIiBkPSJNNSAxMlY3LjU1bDQtLjAyNlYxMlptMyA0di00aDR2NHptLTMgNHYtNGg0djR6bTMgNHYtNGg0djR6bS0zIDQuMTgxVjI0aDR2NC4xNzV6IiBzdHlsZT0ibWl4LWJsZW5kLW1vZGU6bm9ybWFsIi8+PHBhdGggZmlsbD0iIzdkN2QyMyIgc3Ryb2tlPSIjN2Q3ZDIzIiBzdHJva2Utd2lkdGg9Ii4xIiBkPSJNMTAgNy4xMjNWNWgydjIuMTM2Wk0xMSA1VjIuNTYybDItLjE2MlY1WiIgc3R5bGU9Im1peC1ibGVuZC1tb2RlOm5vcm1hbCIvPjxwYXRoIGZpbGw9IiNmZmYiIHN0cm9rZT0iIzdkN2QyMyIgc3Ryb2tlLXdpZHRoPSIyIiBkPSJNMTUuNDg3IDI0Ljh2LTEuNzY1bDUuNjczLTguNTJoLTUuNDkzVjEyLjRoOC40NTN2MS44OTdsLTUuNzExIDguMzg3aDUuNzg3VjI0Ljh6IiBhcmlhLWxhYmVsPSJaIiBmb250LWZhbWlseT0iQ29uc29sYXMiIGZvbnQtc2l6ZT0iMTkuNDMiIGZvbnQtd2VpZ2h0PSI3MDAiIHBhaW50LW9yZGVyPSJzdHJva2UgbWFya2VycyBmaWxsIiBzdHlsZT0iLWlua3NjYXBlLWZvbnQtc3BlY2lmaWNhdGlvbjomcXVvdDtDb25zb2xhcywgQm9sZCZxdW90OyIgdHJhbnNmb3JtPSJzY2FsZSgxLjAzMyAuOTY4KSIvPjwvc3ZnPg=="; @@ -719,6 +746,12 @@ if (this.zipPaths[zip] === "") this.zipPaths[zip] = "/"; } + _tryGetMIMEType(fileName) { + // Try getting the MIME based on the file name using the mime-types library. + // JSZip doesnt store this anywhere, so we have to detect this ourselves. + return MimeTypes.lookup(fileName) || "application/octet-stream"; + } + /// Blocks createEmptyAs({ NAME }) { @@ -910,8 +943,11 @@ case "base64": case "data: URL": { let data = await obj.async("base64"); - if (TYPE === "data: URL") - data = "data:application/octet-stream;base64," + data; + if (TYPE === "data: URL") { + const mime = this._tryGetMIMEType(obj.name); + data = `data:${mime};base64,${data}`; + } + return data; } case "hex": { From 48baced7375eb55cc41086b5583c92f99c99051a Mon Sep 17 00:00:00 2001 From: "DangoCat[bot]" Date: Mon, 20 Jul 2026 07:10:36 +0000 Subject: [PATCH 2/4] [Automated] Format code --- extensions/CST1229/zip.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/extensions/CST1229/zip.js b/extensions/CST1229/zip.js index 49fac3efb4..1b32f8dc60 100644 --- a/extensions/CST1229/zip.js +++ b/extensions/CST1229/zip.js @@ -35,7 +35,9 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - const MimeTypes = await Scratch.external.importModule("https://cdn.jsdelivr.net/npm/mime-types@2.1.35/+esm"); + const MimeTypes = await Scratch.external.importModule( + "https://cdn.jsdelivr.net/npm/mime-types@2.1.35/+esm" + ); const extIcon = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMCAzMCI+PHJlY3Qgd2lkdGg9IjIzIiBoZWlnaHQ9IjIwIiB4PSI2IiB5PSIzIiBmaWxsPSIjZDhkODZjIiBzdHJva2U9IiM3ZDdkMjMiIHN0cm9rZS13aWR0aD0iMiIgcGFpbnQtb3JkZXI9InN0cm9rZSBtYXJrZXJzIGZpbGwiIHJ4PSI0IiByeT0iNCIgc3R5bGU9ImZvbnQtdmFyaWF0aW9uLXNldHRpbmdzOm5vcm1hbCIvPjxyZWN0IHdpZHRoPSIyOCIgaGVpZ2h0PSIyMCIgeD0iMSIgeT0iOCIgZmlsbD0iI2Q4ZDg2YyIgc3Ryb2tlPSIjN2Q3ZDIzIiBzdHJva2Utd2lkdGg9IjIiIHBhaW50LW9yZGVyPSJzdHJva2UgbWFya2VycyBmaWxsIiByeD0iNCIgcnk9IjQiIHN0eWxlPSJmb250LXZhcmlhdGlvbi1zZXR0aW5nczpub3JtYWwiLz48cGF0aCBmaWxsPSIjN2Q3ZDIzIiBkPSJNNSAxMlY3LjU1bDQtLjAyNlYxMlptMyA0di00aDR2NHptLTMgNHYtNGg0djR6bTMgNHYtNGg0djR6bS0zIDQuMTgxVjI0aDR2NC4xNzV6IiBzdHlsZT0ibWl4LWJsZW5kLW1vZGU6bm9ybWFsIi8+PHBhdGggZmlsbD0iIzdkN2QyMyIgc3Ryb2tlPSIjN2Q3ZDIzIiBzdHJva2Utd2lkdGg9Ii4xIiBkPSJNMTAgNy4xMjNWNWgydjIuMTM2Wk0xMSA1VjIuNTYybDItLjE2MlY1WiIgc3R5bGU9Im1peC1ibGVuZC1tb2RlOm5vcm1hbCIvPjxwYXRoIGZpbGw9IiNmZmYiIHN0cm9rZT0iIzdkN2QyMyIgc3Ryb2tlLXdpZHRoPSIyIiBkPSJNMTUuNDg3IDI0Ljh2LTEuNzY1bDUuNjczLTguNTJoLTUuNDkzVjEyLjRoOC40NTN2MS44OTdsLTUuNzExIDguMzg3aDUuNzg3VjI0Ljh6IiBhcmlhLWxhYmVsPSJaIiBmb250LWZhbWlseT0iQ29uc29sYXMiIGZvbnQtc2l6ZT0iMTkuNDMiIGZvbnQtd2VpZ2h0PSI3MDAiIHBhaW50LW9yZGVyPSJzdHJva2UgbWFya2VycyBmaWxsIiBzdHlsZT0iLWlua3NjYXBlLWZvbnQtc3BlY2lmaWNhdGlvbjomcXVvdDtDb25zb2xhcywgQm9sZCZxdW90OyIgdHJhbnNmb3JtPSJzY2FsZSgxLjAzMyAuOTY4KSIvPjwvc3ZnPg=="; From be4a69bdbb7219e040f3dfb360aac59f85d2cdd7 Mon Sep 17 00:00:00 2001 From: SharkPool <139097378+SharkPool-SP@users.noreply.github.com> Date: Sat, 25 Jul 2026 17:42:44 -0700 Subject: [PATCH 3/4] Fix dependency import --- extension-dependencies.json | 4 ++++ extensions/CST1229/zip.js | 31 ++++++++++++++++++++++++++----- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/extension-dependencies.json b/extension-dependencies.json index 74796240cd..12ed768058 100644 --- a/extension-dependencies.json +++ b/extension-dependencies.json @@ -51,6 +51,10 @@ "https://raw.githubusercontent.com/dectalk/tw-dectalk/b387df5a1133dd08a8f3af94d7899dec3f507fd8/dtc.js": { "sha256": "de29c298d3e260d348e9f8eed74e644258e8222fdf741a55665400d560876e8b", "contentType": "application/octet-stream" + }, + "https://cdn.jsdelivr.net/npm/mime-db@1.52.0/db.json": { + "sha256": "85c8e1ba609079947c8df83c092900ab0226e1d7b60e5e7105fb7dd701833263", + "contentType": "application/json; charset=utf-8" } } } \ No newline at end of file diff --git a/extensions/CST1229/zip.js b/extensions/CST1229/zip.js index 1b32f8dc60..b0f7efb487 100644 --- a/extensions/CST1229/zip.js +++ b/extensions/CST1229/zip.js @@ -14,7 +14,7 @@ (The MIT License) Copyright (c) 2014 Jonathan Ong - Copyright (c) 2015 Douglas Christopher Wilson + Copyright (c) 2015-2022 Douglas Christopher Wilson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -35,9 +35,24 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - const MimeTypes = await Scratch.external.importModule( - "https://cdn.jsdelivr.net/npm/mime-types@2.1.35/+esm" - ); + const MimeTypes = await (async function() { + try { + const dbResponse = await Scratch.external.fetch( + "https://cdn.jsdelivr.net/npm/mime-db@1.52.0/db.json" + ); + if (!dbResponse.ok) return []; + + // We need to convert this table to a lookup array with + // mime types with applicable file type extensions. + const mimeTable = await dbResponse.json(); + return Object.entries(mimeTable) + .filter((m) => m[1].extensions !== undefined) + .map((m) => [m[0], m[1].extensions]); + } catch { + console.warn("Couldnt not retrieve data from Mime DB!"); + return []; + } + })(); const extIcon = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMCAzMCI+PHJlY3Qgd2lkdGg9IjIzIiBoZWlnaHQ9IjIwIiB4PSI2IiB5PSIzIiBmaWxsPSIjZDhkODZjIiBzdHJva2U9IiM3ZDdkMjMiIHN0cm9rZS13aWR0aD0iMiIgcGFpbnQtb3JkZXI9InN0cm9rZSBtYXJrZXJzIGZpbGwiIHJ4PSI0IiByeT0iNCIgc3R5bGU9ImZvbnQtdmFyaWF0aW9uLXNldHRpbmdzOm5vcm1hbCIvPjxyZWN0IHdpZHRoPSIyOCIgaGVpZ2h0PSIyMCIgeD0iMSIgeT0iOCIgZmlsbD0iI2Q4ZDg2YyIgc3Ryb2tlPSIjN2Q3ZDIzIiBzdHJva2Utd2lkdGg9IjIiIHBhaW50LW9yZGVyPSJzdHJva2UgbWFya2VycyBmaWxsIiByeD0iNCIgcnk9IjQiIHN0eWxlPSJmb250LXZhcmlhdGlvbi1zZXR0aW5nczpub3JtYWwiLz48cGF0aCBmaWxsPSIjN2Q3ZDIzIiBkPSJNNSAxMlY3LjU1bDQtLjAyNlYxMlptMyA0di00aDR2NHptLTMgNHYtNGg0djR6bTMgNHYtNGg0djR6bS0zIDQuMTgxVjI0aDR2NC4xNzV6IiBzdHlsZT0ibWl4LWJsZW5kLW1vZGU6bm9ybWFsIi8+PHBhdGggZmlsbD0iIzdkN2QyMyIgc3Ryb2tlPSIjN2Q3ZDIzIiBzdHJva2Utd2lkdGg9Ii4xIiBkPSJNMTAgNy4xMjNWNWgydjIuMTM2Wk0xMSA1VjIuNTYybDItLjE2MlY1WiIgc3R5bGU9Im1peC1ibGVuZC1tb2RlOm5vcm1hbCIvPjxwYXRoIGZpbGw9IiNmZmYiIHN0cm9rZT0iIzdkN2QyMyIgc3Ryb2tlLXdpZHRoPSIyIiBkPSJNMTUuNDg3IDI0Ljh2LTEuNzY1bDUuNjczLTguNTJoLTUuNDkzVjEyLjRoOC40NTN2MS44OTdsLTUuNzExIDguMzg3aDUuNzg3VjI0Ljh6IiBhcmlhLWxhYmVsPSJaIiBmb250LWZhbWlseT0iQ29uc29sYXMiIGZvbnQtc2l6ZT0iMTkuNDMiIGZvbnQtd2VpZ2h0PSI3MDAiIHBhaW50LW9yZGVyPSJzdHJva2UgbWFya2VycyBmaWxsIiBzdHlsZT0iLWlua3NjYXBlLWZvbnQtc3BlY2lmaWNhdGlvbjomcXVvdDtDb25zb2xhcywgQm9sZCZxdW90OyIgdHJhbnNmb3JtPSJzY2FsZSgxLjAzMyAuOTY4KSIvPjwvc3ZnPg=="; @@ -751,7 +766,13 @@ _tryGetMIMEType(fileName) { // Try getting the MIME based on the file name using the mime-types library. // JSZip doesnt store this anywhere, so we have to detect this ourselves. - return MimeTypes.lookup(fileName) || "application/octet-stream"; + const FALLBACK_MIME = "application/octet-stream"; + + const fileType = fileName.split(".").pop().toLowerCase(); + if (!fileType) return FALLBACK_MIME; // shouldnt happen + + const foundEntry = MimeTypes.find((m) => m[1].includes(fileType)); + return foundEntry ? foundEntry[0] : FALLBACK_MIME; } /// Blocks From 3a0179f29f1a9ecfb5ee5a97eb1297da9d4d0a3a Mon Sep 17 00:00:00 2001 From: "DangoCat[bot]" Date: Sun, 26 Jul 2026 00:43:56 +0000 Subject: [PATCH 4/4] [Automated] Format code --- extensions/CST1229/zip.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/CST1229/zip.js b/extensions/CST1229/zip.js index b0f7efb487..3fe8337cc6 100644 --- a/extensions/CST1229/zip.js +++ b/extensions/CST1229/zip.js @@ -35,7 +35,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - const MimeTypes = await (async function() { + const MimeTypes = await (async function () { try { const dbResponse = await Scratch.external.fetch( "https://cdn.jsdelivr.net/npm/mime-db@1.52.0/db.json"