diff --git a/.github/workflows/tester.yml b/.github/workflows/tester.yml index dd848c87..55f32f45 100644 --- a/.github/workflows/tester.yml +++ b/.github/workflows/tester.yml @@ -8,7 +8,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] - node-version: ['12.x', '14.x'] + node-version: ['14.x', '16.x', '18.x'] fail-fast: false steps: - uses: actions/checkout@v2 diff --git a/lib/escape_html.ts b/lib/escape_html.ts index 387a08a6..404cf530 100644 --- a/lib/escape_html.ts +++ b/lib/escape_html.ts @@ -1,6 +1,6 @@ -import unescapeHTML from './unescape_html'; - -const htmlEntityMap = { +const escapeTestNoEncode = /[<>"'`/=]|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/; +const escapeReplaceNoEncode = new RegExp(escapeTestNoEncode.source, 'g'); +const escapeReplacements = { '&': '&', '<': '<', '>': '>', @@ -10,14 +10,16 @@ const htmlEntityMap = { '/': '/', '=': '=' }; +const getEscapeReplacement = (ch: string) => escapeReplacements[ch]; function escapeHTML(str: string) { if (typeof str !== 'string') throw new TypeError('str must be a string!'); - str = unescapeHTML(str); - - // http://stackoverflow.com/a/12034334 - return str.replace(/[&<>"'`/=]/g, a => htmlEntityMap[a]); + // https://github.com/markedjs/marked/blob/master/src/helpers.js + if (escapeTestNoEncode.test(str)) { + return str.replace(escapeReplaceNoEncode, getEscapeReplacement); + } + return str; } export = escapeHTML; diff --git a/lib/is_external_link.ts b/lib/is_external_link.ts index e3903dc9..6a526634 100644 --- a/lib/is_external_link.ts +++ b/lib/is_external_link.ts @@ -10,7 +10,7 @@ const cache = new Cache(); * @returns {Boolean} True if the link doesn't have protocol or link has same host with config.url */ -function isExternalLink(input: string, sitehost: string, exclude: string[]): boolean { +function isExternalLink(input: string, sitehost: string, exclude?: string[]): boolean { return cache.apply(`${input}-${sitehost}-${exclude}`, () => { // Return false early for internal link if (!/^(\/\/|http(s)?:)/.test(input)) return false; diff --git a/package.json b/package.json index 1ceceea9..40d121dd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hexo-util", - "version": "3.0.1", + "version": "3.1.0", "description": "Utilities for Hexo.", "main": "dist/index", "types": "./dist/index.d.ts", @@ -59,7 +59,7 @@ "cross-spawn": "^7.0.3", "deepmerge": "^4.2.2", "highlight.js": "^11.6.0", - "htmlparser2": "^8.0.1", + "htmlparser2": "^9.0.0", "prismjs": "^1.29.0", "strip-indent": "^3.0.0" }, diff --git a/test/escape_html.spec.js b/test/escape_html.spec.js index c48d5063..cf2835cc 100644 --- a/test/escape_html.spec.js +++ b/test/escape_html.spec.js @@ -16,4 +16,8 @@ describe('escapeHTML', () => { it('avoid double escape', () => { escapeHTML('<foo>bar { + escapeHTML('   ').should.eql('   '); + }); });