Skip to content

Commit 2496d1f

Browse files
authored
Merge pull request #183 from SukkaW/fix-is-external-filter
fix(is_external_link): handle invalid url
2 parents 771f8ba + 2a9a5ba commit 2496d1f

File tree

4 files changed

+20
-8
lines changed

4 files changed

+20
-8
lines changed

lib/full_url_for.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ function fullUrlForHelper(path = '/') {
1616

1717
// cacheId is designed to works across different hexo.config & options
1818
return cache.apply(`${config.url}-${prettyUrlsOptions.trailing_index}-${prettyUrlsOptions.trailing_html}-${path}`, () => {
19-
const pathRegex = /^(\/\/|http(s)?:)/;
20-
if (pathRegex.test(path)) return path;
19+
if (/^(\/\/|http(s)?:)/.test(path)) return path;
2120

2221
const sitehost = parse(config.url).hostname || config.url;
2322
const data = new URL(path, `http://${sitehost}`);

lib/is_external_link.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,21 @@ const cache = new Cache();
1313

1414
function isExternalLink(input, sitehost, exclude) {
1515
return cache.apply(`${input}-${sitehost}-${exclude}`, () => {
16+
// Return false early for internal link
17+
if (!/^(\/\/|http(s)?:)/.test(input)) return false;
18+
1619
sitehost = parse(sitehost).hostname || sitehost;
1720

1821
if (!sitehost) return false;
19-
// handle relative url
20-
const data = new URL(input, `http://${sitehost}`);
22+
23+
// handle relative url and invalid url
24+
let data;
25+
try {
26+
data = new URL(input, `http://${sitehost}`);
27+
} catch (e) { }
28+
29+
// if input is invalid url, data should be undefined
30+
if (typeof data !== 'object') return false;
2131

2232
// handle mailto: javascript: vbscript: and so on
2333
if (data.origin === 'null') return false;

lib/url_for.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,7 @@ function urlForHelper(path = '/', options) {
2828

2929
// cacheId is designed to works across different hexo.config & options
3030
return cache.apply(`${config.url}-${root}-${prettyUrlsOptions.trailing_index}-${prettyUrlsOptions.trailing_html}-${path}`, () => {
31-
const pathRegex = /^(#|\/\/|http(s)?:)/;
32-
if (pathRegex.test(path)) {
33-
return path;
34-
}
31+
if (/^(#|\/\/|http(s)?:)/.test(path)) return path;
3532

3633
const sitehost = parse(config.url).hostname || config.url;
3734
const data = new URL(path, `http://${sitehost}`);

test/is_external_link.spec.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,21 @@ describe('isExternalLink', () => {
99

1010
const isExternalLink = require('../lib/is_external_link');
1111

12+
it('invalid url', () => {
13+
isExternalLink('https://localhost:4000你好', ctx.config.url).should.eql(false);
14+
});
15+
1216
it('external link', () => {
1317
isExternalLink('https://hexo.io/', ctx.config.url).should.eql(true);
18+
isExternalLink('//hexo.io/', ctx.config.url).should.eql(true);
1419
});
1520

1621
it('internal link', () => {
1722
isExternalLink('https://example.com', ctx.config.url).should.eql(false);
1823
isExternalLink('//example.com', ctx.config.url).should.eql(false);
1924
isExternalLink('//example.com/archives/foo.html', ctx.config.url).should.eql(false);
2025
isExternalLink('/archives/foo.html', ctx.config.url).should.eql(false);
26+
isExternalLink('/archives//hexo.io', ctx.config.url).should.eql(false);
2127
});
2228

2329
it('hash, mailto, javascript', () => {

0 commit comments

Comments
 (0)