Skip to content

Commit

Permalink
[parser] fix merged HTML attribute quoting (#2235)
Browse files Browse the repository at this point in the history
  • Loading branch information
joshgoebel committed Oct 30, 2019
1 parent 7d436cd commit b7866d8
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 14 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ New styles:
none.

Improvements:
- fix(parser): Fix merger HTML attribute quoting (#2235) [Josh Goebel][]
- fix(parser): Look-ahead regex now work for end matches also (#2237) [Josh Goebel][]
- fix(parser): Better errors when a language is missing (#2236) [Josh Goebel][]

Expand Down
4 changes: 3 additions & 1 deletion src/highlight.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,9 @@ https://highlightjs.org/
}

function open(node) {
function attr_str(a) {return ' ' + a.nodeName + '="' + escape(a.value).replace('"', '"') + '"';}
function attr_str(a) {
return ' ' + a.nodeName + '="' + escape(a.value).replace(/"/g, '"') + '"';
}
result += '<' + tag(node) + ArrayProto.map.call(node.attributes, attr_str).join('') + '>';
}

Expand Down
41 changes: 28 additions & 13 deletions test/browser/plain.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,35 @@ const {promisify} = require('util');
const glob = promisify(require('glob'));
const fs = require('fs');

describe('plain browser', function() {
before(function() {
// Will match both `highlight.pack.js` and `highlight.min.js`
const filepath = utility.buildPath('..', 'build', 'highlight.*.js');

return glob(filepath)
.then(hljsPath => hljsPath.map(path => fs.readFileSync(path, 'utf8')))
.then(hljsFiles => hljsFiles.map(file => `<script>${file}</script>`).join(""))
.then(hljsScript => new JSDOM(hljsScript + this.html, { runScripts: "dangerously" }))
.then(({ window }) => {
this.block = window.document.querySelector('pre code');
this.hljs = window.hljs;
});
const buildFakeDOM = async function() {
// Will match both `highlight.pack.js` and `highlight.min.js`
const filePath = utility.buildPath('..', 'build', 'highlight.*.js');
const hljsPath = await glob(filePath)
const hljsFiles = await hljsPath.map(path => fs.readFileSync(path, 'utf8'))
const hljsScript = await hljsFiles.map(file => `<script>${file}</script>`).join("")
const { window} = await new JSDOM(hljsScript + this.html, { runScripts: "dangerously" })

this.block = window.document.querySelector('pre code');
this.hljs = window.hljs;
};

describe('browser with html with quotes in attributes', function() {
it('should property escape all quotes', async function() {
this.text = "const oops = pick(employee, <span data-title=\" Type '&quot;height&quot;' is not assignable to type '&quot;name&quot; | &quot;age'&quot; | &quot;profession&quot;'.\">['name', 'height']</span>)\n"
this.html = `<pre><code class="javascript">${this.text}</code></pre>`;

// can't use before because we need to do setup first
await buildFakeDOM.bind(this)();

this.hljs.highlightBlock(this.block);
const actual = this.block.innerHTML;
actual.should.equal(
`<span class="hljs-keyword">const</span> oops = pick(employee, <span data-title=" Type '&quot;height&quot;' is not assignable to type '&quot;name&quot; | &quot;age'&quot; | &quot;profession&quot;'.">[<span class="hljs-string">'name'</span>, <span class="hljs-string">'height'</span>]</span>)\n`);
});
})

describe('plain browser', function() {
before(async function() { await buildFakeDOM.bind(this)(); });

it('should return relevance key', function() {
var out = this.hljs.highlight("javascript","");
Expand Down

0 comments on commit b7866d8

Please sign in to comment.