diff --git a/lib/image-stream/handlers.js b/lib/image-stream/handlers.js index 1f209bae..3e19827f 100644 --- a/lib/image-stream/handlers.js +++ b/lib/image-stream/handlers.js @@ -27,6 +27,8 @@ const udif = Bluebird.promisifyAll(require('udif')); const archive = require('./archive'); const zipArchiveHooks = require('./archive-hooks/zip'); const fileExtensions = require('../shared/file-extensions'); +const path = require('path'); +const errors = require('../shared/errors'); /** * @summary Image handlers @@ -161,6 +163,16 @@ module.exports = { }, transform: new PassThroughStream() }; + }).catch((error) => { + if (/invalid footer/i.test(error.message)) { + throw errors.createUserError({ + title: 'Invalid image', + description: `There was an error reading "${path.basename(file)}". ` + + 'The image does not appear to be a valid Apple Disk Image (dmg), or may have the wrong filename extension.\n\n' + + `Error: ${error.description || error.message}` + }); + } + throw error; }); }, diff --git a/tests/image-stream/data/unrecognized/invalid.dmg b/tests/image-stream/data/unrecognized/invalid.dmg new file mode 100644 index 00000000..bc70eab5 Binary files /dev/null and b/tests/image-stream/data/unrecognized/invalid.dmg differ diff --git a/tests/image-stream/dmg.spec.js b/tests/image-stream/dmg.spec.js index e0c30123..938f3008 100644 --- a/tests/image-stream/dmg.spec.js +++ b/tests/image-stream/dmg.spec.js @@ -105,4 +105,14 @@ describe('ImageStream: DMG', function() { }); + context('invalid', function() { + + describe('given an invalid dmg file', function() { + tester.expectError( + path.join(DATA_PATH, 'unrecognized', 'invalid.dmg'), + 'Invalid image', 'Invalid footer'); + }); + + }); + }); diff --git a/tests/image-stream/tester.js b/tests/image-stream/tester.js index d8f2949e..dd654273 100644 --- a/tests/image-stream/tester.js +++ b/tests/image-stream/tester.js @@ -43,11 +43,14 @@ const deleteIfExists = (file) => { }); }; -exports.expectError = function(file, errorMessage) { +exports.expectError = function(file, errorMessage, errorDetail) { it('should be rejected with an error', function() { return imageStream.getFromFilePath(file).catch((error) => { m.chai.expect(error).to.be.an.instanceof(Error); m.chai.expect(error.message).to.equal(errorMessage); + if (errorDetail) { + m.chai.expect(error.description).to.contain(errorDetail); + } m.chai.expect(error.description).to.be.a.string; m.chai.expect(error.description.length > 0).to.be.true; });