diff --git a/core/frontend/helpers/url.js b/core/frontend/helpers/url.js index 86b151bd38..76ba31ff4f 100644 --- a/core/frontend/helpers/url.js +++ b/core/frontend/helpers/url.js @@ -6,6 +6,9 @@ const {metaData} = require('../services/proxy'); const {SafeString} = require('../services/rendering'); +const logging = require('@tryghost/logging'); +const sentry = require('../../shared/sentry'); +const errors = require('@tryghost/errors'); const {getMetaDataUrl} = metaData; @@ -13,7 +16,21 @@ module.exports = function url(options) { const absolute = options && options.hash.absolute && options.hash.absolute !== 'false'; let outputUrl = getMetaDataUrl(this, absolute); - outputUrl = encodeURI(decodeURI(outputUrl)); + try { + outputUrl = encodeURI(decodeURI(outputUrl)); + } catch (err) { + // Happens when the outputURL contains an invalid URI character like "%%" or "%80" + + // Send the error not to be blind to these + const error = new errors.IncorrectUsageError({ + message: `The url "${outputUrl}" couldn't be escaped correctly`, + err: err + }); + sentry.captureException(error); + logging.error(error); + + return new SafeString(''); + } return new SafeString(outputUrl); }; diff --git a/test/unit/frontend/helpers/url.test.js b/test/unit/frontend/helpers/url.test.js index 98536fd96c..1d63d00b9a 100644 --- a/test/unit/frontend/helpers/url.test.js +++ b/test/unit/frontend/helpers/url.test.js @@ -9,7 +9,7 @@ const url = require('../../../../core/frontend/helpers/url'); const urlService = require('../../../../core/server/services/url'); const api = require('../../../../core/server/api'); -describe('{{url}} helper', function () { +describe.only('{{url}} helper', function () { let rendered; beforeEach(function () { @@ -267,6 +267,12 @@ describe('{{url}} helper', function () { should.exist(rendered); rendered.string.should.equal('/?foo=space%20bar'); }); + + it('should an empty string when we can\'t parse a string', function () { + rendered = url.call({url: '/?foo=space%%bar', label: 'Baz', slug: 'baz', current: true}); + should.exist(rendered); + rendered.string.should.equal(''); + }); }); describe('with subdir', function () {