Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

scratch-analysis

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

scratch-analysis - npm Package Compare versions

Comparing version 1.0.1 to 2.0.0

test/fixtures/sb2/cloud_complex.sb2

62

lib/sb2.js

@@ -96,2 +96,20 @@ const utility = require('./utility');

/**
* Determine if a argument is the name of a known cloud variable.
* @param {string} arg Argument (variable name)
* @return {boolean} Is cloud variable?
*/
const isArgCloudVar = function (arg) {
// Validate argument
// @note "Hacked" inputs here could be objects (arrays)
if (typeof arg !== 'string') return false;
// Iterate over global variables and check to see if arg matches
for (let i in project.variables) {
const variable = project.variables[i];
if (variable.name === arg && variable.isPersistent) return true;
}
return false;
};
/**
* Walk scripts array(s) and build block list.

@@ -112,7 +130,16 @@ * @param {array} stack Stack of blocks

// Get opcode and check variable manipulation for the presence of
// cloud variables
let opcode = stack[i][0];
if (opcode === 'setVar:to:' || opcode === 'changeVar:by:') {
if (isArgCloudVar(stack[i][1])) {
opcode += 'cloud:';
}
}
// Add to block list
result.push(stack[i][0]);
result.push(opcode);
// Don't pull in params from procedures
if (stack[i][0] === 'procDef') continue;
if (opcode === 'procDef') continue;

@@ -160,2 +187,31 @@ // Move to next item and walk

/**
* Extracts cloud variable information.
* @param {object} project Project object (SB2 format)
* @param {array} names Names of all variables in project
* @return {object} Cloud variable information
*/
const cloud = function (project, names) {
const obj = [];
// Extract "isPersistent" parameter from all variables in project
const cloudyness = extract(project, 'variables', 'isPersistent').id;
// Ensure that variable names and isPersistent parameter list are the same
// length
if (names.length !== cloudyness.length) return -1;
// Iterate over isPersistent values, and extract names of any that are true
for (let i in cloudyness) {
if (cloudyness[i]) {
obj.push(names[i]);
}
}
return {
count: obj.length,
id: obj
};
};
/**
* Analyzes a project and returns summary information about the project.

@@ -177,2 +233,4 @@ * @param {object} project Project object (SB2 format)

meta.cloud = cloud(project, meta.variables.id);
// Sprites

@@ -179,0 +237,0 @@ meta.sprites = sprites(project);

@@ -24,5 +24,10 @@ const utility = require('./utility');

// Cloud variables are a type of variable
const isCloud = (attribute === 'cloud');
if (isCloud) attribute = 'variables';
for (let t in targets) {
for (let a in targets[t][attribute]) {
const variable = targets[t][attribute][a];
if (isCloud && (variable.length !== 3 || !variable[2])) continue;
occurrences++;

@@ -71,6 +76,33 @@ idList.push(variable[0]);

/**
* Determine if a argument is the name of a known cloud variable.
* @param {string} arg Argument (variable name)
* @return {boolean} Is cloud variable?
*/
const isArgCloudVar = function (arg) {
// Validate argument
if (typeof arg !== 'string') return false;
// Check first target (stage) to determine if arg is a cloud variable id
const stage = targets[0];
if (typeof stage.variables[arg] !== 'undefined') {
return stage.variables[arg].length === 3 && stage.variables[arg][2];
}
};
// Iterate over all targets and push block opcodes to storage object
for (let t in targets) {
for (let a in targets[t].blocks) {
const block = targets[t].blocks[a];
if (!block.shadow) result.push(block.opcode);
// Get opcode and check variable manipulation for the presence of
// cloud variables
let opcode = block.opcode;
if (opcode === 'data_setvariableto' || opcode === 'data_changevariableby') {
if (isArgCloudVar(block.fields.VARIABLE[1])) {
opcode += '_cloud';
}
}
if (!block.shadow) result.push(opcode);
}

@@ -102,2 +134,3 @@ }

variables: variables(project.targets, 'variables'),
cloud: variables(project.targets, 'cloud'),
lists: variables(project.targets, 'lists'),

@@ -104,0 +137,0 @@ comments: extract(project.targets, 'comments'),

4

package.json
{
"name": "scratch-analysis",
"version": "1.0.1",
"version": "2.0.0",
"description": "Analysis tool for summarizing the structure, composition, and complexity of Scratch programs.",

@@ -20,3 +20,3 @@ "main": "lib/index.js",

"dependencies": {
"scratch-parser": "4.3.3"
"scratch-parser": "4.3.6"
},

@@ -23,0 +23,0 @@ "devDependencies": {

@@ -29,3 +29,4 @@ ## scratch-analysis

| `sprites` | `count` |
| `variables` | `count` |
| `variables` | `count`, `id` |
| `cloud` | `count`, `id` |
| `lists` | `count` |

@@ -32,0 +33,0 @@ | `costumes` | `count`, `list`, `hash` |

@@ -16,2 +16,6 @@ const fs = require('fs');

const extensionsBinary = fs.readFileSync(
path.resolve(__dirname, '../fixtures/sb3/extensions.sb3')
);
test('defalt (object)', t => {

@@ -262,1 +266,17 @@ analysis(defaultObject, (err, result) => {

});
test('extensions', t => {
analysis(extensionsBinary, (err, result) => {
t.true(typeof err === 'undefined' || err === null);
t.type(result, 'object');
t.type(result.extensions, 'object');
t.equal(result.extensions.count, 2);
t.deepEqual(result.extensions.id, [
'translate',
'text2speech'
]);
t.end();
});
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc