From 90b9da45f4084958535338d1c4d71a22d6136aab Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford <7019101+cwillisf@users.noreply.github.com> Date: Mon, 15 Jun 2020 17:41:35 -0700 Subject: [PATCH] sanitize extension ID in getExtensionIdForOpcode --- docs/extensions.md | 1 + src/serialization/sb3.js | 8 ++++++-- test/unit/serialization_sb3.js | 3 +++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/docs/extensions.md b/docs/extensions.md index 350c0204f..44638107a 100644 --- a/docs/extensions.md +++ b/docs/extensions.md @@ -310,6 +310,7 @@ class SomeBlocks { return { // Required: the machine-readable name of this extension. // Will be used as the extension's namespace. + // Allowed characters are those matching the regular expression [\w-]: A-Z, a-z, 0-9, and hyphen ("-"). id: 'someBlocks', // Core extensions only: override the default extension block colors. diff --git a/src/serialization/sb3.js b/src/serialization/sb3.js index d49365671..bb82390a1 100644 --- a/src/serialization/sb3.js +++ b/src/serialization/sb3.js @@ -273,13 +273,17 @@ const compressInputTree = function (block, blocks) { }; /** - * Get non-core extension ID for a given sb3 opcode. + * Get sanitized non-core extension ID for a given sb3 opcode. + * Note that this should never return a URL. If in the future the SB3 loader supports loading extensions by URL, this + * ID should be used to (for example) look up the extension's full URL from a table in the SB3's JSON. * @param {!string} opcode The opcode to examine for extension. * @return {?string} The extension ID, if it exists and is not a core extension. */ const getExtensionIdForOpcode = function (opcode) { + // Allowed ID characters are those matching the regular expression [\w-]: A-Z, a-z, 0-9, and hyphen ("-"). const index = opcode.indexOf('_'); - const prefix = opcode.substring(0, index); + const forbiddenSymbols = /[^\w-]/g; + const prefix = opcode.substring(0, index).replace(forbiddenSymbols, '-'); if (CORE_EXTENSIONS.indexOf(prefix) === -1) { if (prefix !== '') return prefix; } diff --git a/test/unit/serialization_sb3.js b/test/unit/serialization_sb3.js index 5ef1ac80d..baeb23543 100644 --- a/test/unit/serialization_sb3.js +++ b/test/unit/serialization_sb3.js @@ -290,6 +290,9 @@ test('getExtensionIdForOpcode', t => { // does not return anything for opcodes with no extension t.false(sb3.getExtensionIdForOpcode('hello')); + // forbidden characters must be replaced with '-' + t.equal(sb3.getExtensionIdForOpcode('hi:there/happy_people'), 'hi-there-happy'); + t.end(); });