diff --git a/lib/resolve/resolvers/UrlResolver.js b/lib/resolve/resolvers/UrlResolver.js index c5ba635f..4730cfac 100644 --- a/lib/resolve/resolvers/UrlResolver.js +++ b/lib/resolve/resolvers/UrlResolver.js @@ -141,8 +141,13 @@ UrlResolver.prototype._parseHeaders = function (file, response) { return Q.resolve([file, response]); } - // If so, extract the filename - matches = disposition.match(/filename="?(.+?)"?/i); + // If so, extract the filename from it + // Since there's various security issues with parsing this header, + // we only interpret word chars plus dots, dashes and spaces + // Also the filename can't start with a space and end with a + // dot or a space (this is known to cause issues in Windows) + // See: http://superuser.com/questions/230385/dots-at-end-of-file-name + matches = disposition.match(/filename="?([\w\.\-](?:[\w\.\- ]*[\w\-]))"?/i); if (!matches) { return Q.resolve([file, response]); } diff --git a/test/resolve/resolvers/urlResolver.js b/test/resolve/resolvers/urlResolver.js index 1f0a4801..205f9ddb 100644 --- a/test/resolve/resolvers/urlResolver.js +++ b/test/resolve/resolvers/urlResolver.js @@ -145,6 +145,8 @@ describe('UrlResolver', function () { }) .done(); }); + + it.skip('should resolve to true if server responds with 304 (ETag mechanism)'); }); describe('.resolve', function () { @@ -263,8 +265,56 @@ describe('UrlResolver', function () { .done(); }); - it.skip('should extract if response content-type is an archive'); - it.skip('should extract if response content-disposition filename is an archive'); + it('should extract if response content-type is an archive', function (next) { + var resolver; + + nock('http://bower.io') + .get('/package-zip') + .replyWithFile(200, path.resolve(__dirname, '../../assets/package-zip.zip'), { + 'Content-Type': 'application/zip' + }); + + resolver = new UrlResolver('http://bower.io/package-zip'); + + resolver.resolve() + .then(function (dir) { + expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'package-zip'))).to.be(false); + next(); + }) + .done(); + }); + + it('should extract if response content-disposition filename is an archive', function (next) { + var resolver; + + nock('http://bower.io') + .get('/package-zip') + .replyWithFile(200, path.resolve(__dirname, '../../assets/package-zip.zip'), { + 'Content-Disposition': 'attachment; filename="package-zip.zip"' + }); + + resolver = new UrlResolver('http://bower.io/package-zip'); + + resolver.resolve() + .then(function (dir) { + expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'package-zip'))).to.be(false); + next(); + }) + .done(); + }); + + describe('content-disposition', function () { + it.skip('should work with and without quotes'); + it.skip('should not work with partial quotes'); + it.skip('should not work if the filename contain chars other than alphanumerical, dashes, spaces and dots'); + it.skip('should not work if the filename start with a space'); + it.skip('should not work if the filename ends with a space'); + it.skip('should not work if the filename ends with a dot'); + }); // TODO: copy other tests related with extraction from the FsResolver tests }); diff --git a/test/test.js b/test/test.js index f9b5a58f..ed6b2e5d 100644 --- a/test/test.js +++ b/test/test.js @@ -5,11 +5,11 @@ require('../lib/resolve/Resolver'); process.removeAllListeners('uncaughtException'); -//require('./resolve/resolver'); +require('./resolve/resolver'); require('./resolve/resolvers/urlResolver'); require('./resolve/resolvers/fsResolver'); -//require('./resolve/resolvers/gitResolver'); -//require('./resolve/resolvers/gitFsResolver'); -//require('./resolve/resolvers/gitRemoteResolver'); -//require('./resolve/worker'); +require('./resolve/resolvers/gitResolver'); +require('./resolve/resolvers/gitFsResolver'); +require('./resolve/resolvers/gitRemoteResolver'); +require('./resolve/worker'); //require('./resolve/resolverFactory');