Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions lib/unpack.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ var unzip = require('./unzip');

/**
* If input a buffer, transforms buffer into a UTF-8 string.
* If input is encoded in zip or gzip format, the input will be extracted and decoded.
* If input is encoded in zip format, the input will be extracted and decoded.
* If input is a string, passes that string along to the given callback.
* @param {Buffer | string} input Project data
* @param {boolean} isSprite Whether the input should be treated as
Expand Down Expand Up @@ -34,19 +34,17 @@ module.exports = function (input, isSprite, callback) {
var signature = input.slice(0, 3).join(' ');
var isLegacy = false;
var isZip = false;
var isGZip = false;

if (signature.indexOf('83 99 114') === 0) isLegacy = true;
if (signature.indexOf('80 75') === 0) isZip = true;
if (signature.indexOf('31 139') === 0) isGZip = true;

// If not legacy, zip, or gzip, convert buffer to UTF-8 string and return
if (!isZip && !isLegacy && !isGZip) {
// If not legacy or zip, convert buffer to UTF-8 string and return
if (!isZip && !isLegacy) {
return callback(null, [input.toString('utf-8'), null]);
}

// Return error if legacy encoding detected
if (isLegacy) return callback('Parser only supports Scratch 2.X and above');

unzip(input, isGZip, isSprite, callback);
unzip(input, isSprite, callback);
};
20 changes: 5 additions & 15 deletions lib/unzip.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,16 @@
var JSZip = require('jszip');
var GZip = require('gzip-js');

/**
* Unpacks a zip or gzip file.
* @param {string} input Zip file provided as a string
* @param {boolean} isGZip Whether the input is a GZip file, otherwise treat as zip
* Unpacks a zip file.
* @param {string} input Zip file provided as a string
* @param {boolean} isSprite Whether the input should be treated as
* a sprite (true) or whole project (false)
* @param {array} callback Array including both the project and zip archive
* @param {array} callback Array including both the project and zip archive
* @return {void}
*/
module.exports = function (input, isGZip, isSprite, callback) {
module.exports = function (input, isSprite, callback) {
var msg = 'Failed to unzip and extract project.json, with error: ';
if (isGZip) {
var unpackedProject = null;
try {
unpackedProject = GZip.unzip(input);
} catch (e) {
return callback(msg + e);
}
return callback(null, [(new Buffer(unpackedProject)).toString('utf-8'), null]);
}

return JSZip.loadAsync(input)
.then(function (zip) {
// look for json in the list of files, or in a subdirectory
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
},
"dependencies": {
"ajv": "6.3.0",
"gzip-js": "0.3.2",
"jszip": "3.1.5",
"pify": "4.0.1"
},
Expand Down
7 changes: 1 addition & 6 deletions test/fixtures/data.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,25 @@ var sprite2 = glob.sync(path.resolve(__dirname, './data/*.sprite2'));
// so that they don't get caught here but can still be used by the
// validate unit tests
var json = glob.sync(path.resolve(__dirname, './data/*.json'));
var gzipJson = glob.sync(path.resolve(__dirname, './data/*.json.gz'));

// Read files and convert to buffers
for (var a in sb) sb[a] = fs.readFileSync(sb[a]);
for (var b in sb2) sb2[b] = fs.readFileSync(sb2[b]);
for (var c in sb3) sb3[c] = fs.readFileSync(sb3[c]);
for (var d in json) json[d] = fs.readFileSync(json[d]);
for (var e in gzipJson) gzipJson[e] = fs.readFileSync(gzipJson[e]);
for (var f in sprite2) sprite2[f] = fs.readFileSync(sprite2[f]);

// Return listings
module.exports = {
empty: {
sb: fs.readFileSync(path.resolve(__dirname, './data/_empty.sb')),
sb2: fs.readFileSync(path.resolve(__dirname, './data/_empty.sb2')),
json: fs.readFileSync(path.resolve(__dirname, './data/_empty.json')),
gzipJson: fs.readFileSync(path.resolve(__dirname, './data/_empty.json.gz'))
json: fs.readFileSync(path.resolve(__dirname, './data/_empty.json'))
},
example: {
sb: fs.readFileSync(path.resolve(__dirname, './data/_example.sb')),
sb2: fs.readFileSync(path.resolve(__dirname, './data/_example.sb2')),
json: fs.readFileSync(path.resolve(__dirname, './data/_example.json')),
gzipJson: fs.readFileSync(path.resolve(__dirname, './data/_example.json.gz')),
invalidEmpty: fs.readFileSync(path.resolve(__dirname, './data/invalid/_invalidEmpty.sb2'))
},
sprites: {
Expand All @@ -52,7 +48,6 @@ module.exports = {
sb2: sb2,
sb3: sb3,
json: json,
gzipJson: gzipJson,
sprite2: sprite2,
layerOrderSB3Json: fs.readFileSync(path.resolve(__dirname, './data/_layer_ordering.json')),
invalidStageLayerSB3Json: fs.readFileSync(path.resolve(__dirname, './data/invalid/_invalid_stage_layer.json')),
Expand Down
Binary file removed test/fixtures/data/_empty.json.gz
Binary file not shown.
Binary file removed test/fixtures/data/_example.json.gz
Binary file not shown.
13 changes: 0 additions & 13 deletions test/integration/empty.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,3 @@ test('json string', function (t) {
t.end();
});
});

test('gzipped json', function (t) {
parser(data.empty.gzipJson, false, function (err, result) {
t.equal(err, null);
t.equal(Array.isArray(result), true);
var res = result[0];
var possibleZip = result[1];
t.type(res, 'object');
t.type(res.info, 'object');
t.equal(possibleZip, null);
t.end();
});
});
13 changes: 0 additions & 13 deletions test/integration/example.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,6 @@ test('json string', function (t) {
});
});

test('gzipped json', function (t) {
parser(data.example.gzipJson, false, function (err, result) {
t.equal(err, null);
t.equal(Array.isArray(result), true);
var res = result[0];
var possibleZip = result[1];
t.type(res, 'object');
t.type(res.info, 'object');
t.equal(possibleZip, null);
t.end();
});
});

test('invalid empty project archive', function (t) {
var msg = 'Failed to unzip and extract project.json, with error: ';
parser(data.example.invalidEmpty, false, function (err, result) {
Expand Down
103 changes: 12 additions & 91 deletions test/unit/unzip.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ var unzip = require('../../lib/unzip');
var fixtures = {
sb: path.resolve(__dirname, '../fixtures/data/_example.sb'),
sb2: path.resolve(__dirname, '../fixtures/data/_example.sb2'),
gzipJSON: path.resolve(__dirname, '../fixtures/data/_example.json.gz'),
zipFakeProjectJSON:
path.resolve(__dirname, '../fixtures/data/_zipFakeProjectJson.zip'),
zipNoProjectJSON:
Expand All @@ -28,7 +27,7 @@ test('spec', function (t) {

test('sb', function (t) {
var buffer = new Buffer(fixtures.sb);
unzip(buffer, false, false, function (err, res) {
unzip(buffer, false, function (err, res) {
t.type(err, 'string');
t.equal(err.startsWith(errorMessage), true);
t.type(res, 'undefined');
Expand All @@ -38,7 +37,7 @@ test('sb', function (t) {

test('sb2', function (t) {
var buffer = new Buffer(fixtures.sb2);
unzip(buffer, false, false, function (err, res) {
unzip(buffer, false, function (err, res) {
t.equal(err, null);
t.equal(Array.isArray(res), true);
t.type(res[0], 'string');
Expand All @@ -50,23 +49,9 @@ test('sb2', function (t) {
});
});

test('gzipped JSON', function (t) {
var buffer = new Buffer(fixtures.gzipJSON);
unzip(buffer, true, false, function (err, res) {
t.equal(err, null);
t.equal(Array.isArray(res), true);
t.type(res[0], 'string');
t.doesNotThrow(function () {
JSON.parse(res[0]);
});
t.equal(res[1], null);
t.end();
});
});

test('sb2 with nested folder', function (t) {
var buffer = new Buffer(fixtures.sb2Nested);
unzip(buffer, false, false, function (err, res) {
unzip(buffer, false, function (err, res) {
t.equal(err, null);
t.equal(Array.isArray(res), true);
t.type(res[0], 'string');
Expand All @@ -80,7 +65,7 @@ test('sb2 with nested folder', function (t) {

test('zip without project json', function (t) {
var buffer = new Buffer(fixtures.zipNoProjectJSON);
unzip(buffer, false, false, function (err, res) {
unzip(buffer, false, function (err, res) {
t.type(err, 'string');
t.equal(err.startsWith(errorMessage), true);
t.type(res, 'undefined');
Expand All @@ -90,7 +75,7 @@ test('zip without project json', function (t) {

test('zip with fake project json', function (t) {
var buffer = new Buffer(fixtures.zipFakeProjectJSON);
unzip(buffer, false, false, function (err, res) {
unzip(buffer, false, function (err, res) {
t.equal(err, null);
t.equal(Array.isArray(res), true);
t.type(res[0], 'string');
Expand All @@ -106,7 +91,7 @@ test('zip with fake project json', function (t) {
var randomString = 'this is not a zip';

test('random string instead of zip, whole project', function (t) {
unzip(randomString, false, false, function (err, res) {
unzip(randomString, false, function (err, res) {
t.type(err, 'string');
t.equal(err.startsWith(errorMessage), true);
t.type(res, 'undefined');
Expand All @@ -115,25 +100,7 @@ test('random string instead of zip, whole project', function (t) {
});

test('random string instead of zip, sprite', function (t) {
unzip(randomString, false, true, function (err, res) {
t.type(err, 'string');
t.equal(err.startsWith(errorMessage), true);
t.type(res, 'undefined');
t.end();
});
});

test('random string instead of gzip, whole project ', function (t) {
unzip(randomString, true, false, function (err, res) {
t.type(err, 'string');
t.equal(err.startsWith(errorMessage), true);
t.type(res, 'undefined');
t.end();
});
});

test('random string instead of gzip, sprite', function (t) {
unzip(randomString, true, true, function (err, res) {
unzip(randomString, true, function (err, res) {
t.type(err, 'string');
t.equal(err.startsWith(errorMessage), true);
t.type(res, 'undefined');
Expand All @@ -143,17 +110,7 @@ test('random string instead of gzip, sprite', function (t) {

test('undefined', function (t) {
var foo;
unzip(foo, false, false, function (err, obj) {
t.type(err, 'string');
t.equal(err.startsWith(errorMessage), true);
t.type(obj, 'undefined');
t.end();
});
});

test('undefined isGZip', function (t) {
var foo;
unzip(foo, true, false, function (err, obj) {
unzip(foo, false, function (err, obj) {
t.type(err, 'string');
t.equal(err.startsWith(errorMessage), true);
t.type(obj, 'undefined');
Expand All @@ -162,7 +119,7 @@ test('undefined isGZip', function (t) {
});

test('null instead of zip, whole project', function (t) {
unzip(null, false, false, function (err, obj) {
unzip(null, false, function (err, obj) {
t.type(err, 'string');
t.equal(err.startsWith(errorMessage), true);
t.type(obj, 'undefined');
Expand All @@ -171,25 +128,7 @@ test('null instead of zip, whole project', function (t) {
});

test('null instead of zip, sprite', function (t) {
unzip(null, false, true, function (err, obj) {
t.type(err, 'string');
t.equal(err.startsWith(errorMessage), true);
t.type(obj, 'undefined');
t.end();
});
});

test('null instead of gzip, whole project', function (t) {
unzip(null, true, false, function (err, obj) {
t.type(err, 'string');
t.equal(err.startsWith(errorMessage), true);
t.type(obj, 'undefined');
t.end();
});
});

test('null instead of gzip, sprite', function (t) {
unzip(null, true, true, function (err, obj) {
unzip(null, true, function (err, obj) {
t.type(err, 'string');
t.equal(err.startsWith(errorMessage), true);
t.type(obj, 'undefined');
Expand All @@ -198,7 +137,7 @@ test('null instead of gzip, sprite', function (t) {
});

test('object instead of zip, whole project', function (t) {
unzip({}, false, false, function (err, obj) {
unzip({}, false, function (err, obj) {
t.type(err, 'string');
t.equal(err.startsWith(errorMessage), true);
t.type(obj, 'undefined');
Expand All @@ -207,25 +146,7 @@ test('object instead of zip, whole project', function (t) {
});

test('object instead of zip, sprite', function (t) {
unzip({}, false, true, function (err, obj) {
t.type(err, 'string');
t.equal(err.startsWith(errorMessage), true);
t.type(obj, 'undefined');
t.end();
});
});

test('object instead of gzip, whole project', function (t) {
unzip({}, true, false, function (err, obj) {
t.type(err, 'string');
t.equal(err.startsWith(errorMessage), true);
t.type(obj, 'undefined');
t.end();
});
});

test('object instead of gzip, sprite', function (t) {
unzip({}, true, false, function (err, obj) {
unzip({}, true, function (err, obj) {
t.type(err, 'string');
t.equal(err.startsWith(errorMessage), true);
t.type(obj, 'undefined');
Expand Down