Skip to content

Commit

Permalink
Merge pull request #3704 from dailyrandomphoto/fix-post_link-title
Browse files Browse the repository at this point in the history
fix: escape_html in post_link & asset_link helpers
  • Loading branch information
curbengh authored Sep 21, 2019
2 parents 6f6d04e + f6318c3 commit 53ebe22
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 8 deletions.
16 changes: 13 additions & 3 deletions lib/plugins/tag/asset_link.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
'use strict';

const url = require('url');
const { escapeHTML } = require('hexo-util');

/**
* Asset link tag
*
* Syntax:
* {% asset_link slug [title] %}
* {% asset_link slug [title] [escape] %}
*/
module.exports = ctx => {
const PostAsset = ctx.model('PostAsset');
Expand All @@ -18,8 +19,17 @@ module.exports = ctx => {
const asset = PostAsset.findOne({post: this._id, slug});
if (!asset) return;

const title = args.length ? args.join(' ') : asset.slug;
let escape = args[args.length - 1];
if (escape === 'true' || escape === 'false') {
args.pop();
} else {
escape = 'true';
}

return `<a href="${url.resolve(ctx.config.root, asset.path)}" title="${title}">${title}</a>`;
let title = args.length ? args.join(' ') : asset.slug;
const attrTitle = escapeHTML(title);
if (escape === 'true') title = attrTitle;

return `<a href="${url.resolve(ctx.config.root, asset.path)}" title="${attrTitle}">${title}</a>`;
};
};
17 changes: 14 additions & 3 deletions lib/plugins/tag/post_link.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
'use strict';

const { escapeHTML } = require('hexo-util');

/**
* Post link tag
*
* Syntax:
* {% post_link slug [title] %}
* {% post_link slug [title] [escape] %}
*/
module.exports = ctx => {
const Post = ctx.model('Post');
Expand All @@ -13,11 +15,20 @@ module.exports = ctx => {
const slug = args.shift();
if (!slug) return;

let escape = args[args.length - 1];
if (escape === 'true' || escape === 'false') {
args.pop();
} else {
escape = 'true';
}

const post = Post.findOne({slug});
if (!post) return;

const title = args.length ? args.join(' ') : post.title;
let title = args.length ? args.join(' ') : post.title;
const attrTitle = escapeHTML(title);
if (escape === 'true') title = attrTitle;

return `<a href="${ctx.config.root}${post.path}" title="${title}">${title}</a>`;
return `<a href="${ctx.config.root}${post.path}" title="${attrTitle}">${title}</a>`;
};
};
12 changes: 12 additions & 0 deletions test/scripts/tags/asset_link.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@ describe('asset_link', () => {
assetLink('bar Hello world').should.eql('<a href="/foo/bar" title="Hello world">Hello world</a>');
});

it('should escape tag in title by default', () => {
assetLink('bar "Hello" <world>').should.eql('<a href="/foo/bar" title="&quot;Hello&quot; &lt;world&gt;">&quot;Hello&quot; &lt;world&gt;</a>');
});

it('should escape tag in title', () => {
assetLink('bar "Hello" <world> true').should.eql('<a href="/foo/bar" title="&quot;Hello&quot; &lt;world&gt;">&quot;Hello&quot; &lt;world&gt;</a>');
});

it('should not escape tag in title', () => {
assetLink('bar "Hello" <b>world</b> false').should.eql('<a href="/foo/bar" title="&quot;Hello&quot; &lt;b&gt;world&lt;&#x2F;b&gt;">"Hello" <b>world</b></a>');
});

it('with space', () => {
// {% asset_link "spaced asset" "spaced title" %}
assetLinkTag.call(post, ['spaced asset', 'spaced title'])
Expand Down
30 changes: 28 additions & 2 deletions test/scripts/tags/post_link.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,16 @@ describe('post_link', () => {

hexo.config.permalink = ':title/';

before(() => hexo.init().then(() => Post.insert({
before(() => hexo.init().then(() => Post.insert([{
source: 'foo',
slug: 'foo',
title: 'Hello world'
})));
},
{
source: 'title-with-tag',
slug: 'title-with-tag',
title: '"Hello" <new world>!'
}])));

it('default', () => {
postLink(['foo']).should.eql('<a href="/foo/" title="Hello world">Hello world</a>');
Expand All @@ -22,6 +27,27 @@ describe('post_link', () => {
postLink(['foo', 'test']).should.eql('<a href="/foo/" title="test">test</a>');
});

it('should escape tag in title by default', () => {
postLink(['title-with-tag']).should.eql('<a href="/title-with-tag/" title="&quot;Hello&quot; &lt;new world&gt;!">&quot;Hello&quot; &lt;new world&gt;!</a>');
});

it('should escape tag in title', () => {
postLink(['title-with-tag', 'true']).should.eql('<a href="/title-with-tag/" title="&quot;Hello&quot; &lt;new world&gt;!">&quot;Hello&quot; &lt;new world&gt;!</a>');
});

it('should escape tag in custom title', () => {
postLink(['title-with-tag', '<test>', 'title', 'true']).should.eql('<a href="/title-with-tag/" title="&lt;test&gt; title">&lt;test&gt; title</a>');
});

it('should not escape tag in title', () => {
postLink(['title-with-tag', 'false']).should.eql('<a href="/title-with-tag/" title="&quot;Hello&quot; &lt;new world&gt;!">"Hello" <new world>!</a>');
});

it('should not escape tag in custom title', () => {
postLink(['title-with-tag', 'This is a <b>Bold</b> "statement"', 'false'])
.should.eql('<a href="/title-with-tag/" title="This is a &lt;b&gt;Bold&lt;&#x2F;b&gt; &quot;statement&quot;">This is a <b>Bold</b> "statement"</a>');
});

it('no slug', () => {
should.not.exist(postLink([]));
});
Expand Down

0 comments on commit 53ebe22

Please sign in to comment.