Fix ampersand in jsx href and src (#1056)

* Add exceptions for html escape usage in href and src attributes.

* Add new test cases.

* Remove useless spaces.

* Do not escape if the parser does not do so.

* Implement a different heuristic for keeping along with the parser.

* Update tests.

* Forgot passing options as param.

* Experimental alternative implementation.

* Remove other function.

* Push test after merge.

* Update getJsXRawValue in order to return the unprocessed raw value.

Latest Babylon version includes a fix that allow us to directly
inject the unprocessed raw value available in the `extra.rawValue`
property of the node. A last transformation is applied by replacing
double quotes to `"` entities.

* Drop unused htmlEscapeInsideDoubleQuote function.

* Move getJSXRawValue function logic to the its only call, drop it.

A simple check is performed to determine if the parser is babylon or
flow via `n.value.extra`. Thus, the corresponding raw value is
extracted. If we are converting a string from single quotes to
double quotes, we need to make sure that double quotes are converted
to ".

* Remove ambiguous comment.

* Add Babylon parser.

* Update test cases accordingly, revert regression introduced previously.
master
Davy Duperron 2017-04-08 16:55:50 +02:00 committed by Christopher Chedeau
parent dc93bdc983
commit d1191adce6
6 changed files with 22 additions and 16 deletions

View File

@ -1200,7 +1200,10 @@ function genericPrintNoParens(path, options, print) {
(n.value.type === "StringLiteral" || n.value.type === "Literal") &&
typeof n.value.value === "string"
) {
res = '"' + util.htmlEscapeInsideDoubleQuote(n.value.value) + '"';
const value = n.value.extra ? n.value.extra.raw : n.value.raw;
res = '"' +
value.slice(1, value.length - 1).replace(/"/g, """) +
'"';
} else {
res = path.call(print, "value");
}

View File

@ -265,16 +265,6 @@ function setLocEnd(node, index) {
}
}
// http://stackoverflow.com/a/7124052
function htmlEscapeInsideDoubleQuote(str) {
return str.replace(/&/g, "&").replace(/"/g, """);
// Intentionally disable the following since it is safe inside of a
// double quote context
// .replace(/'/g, ''')
// .replace(/</g, '&lt;')
// .replace(/>/g, '&gt;');
}
// http://stackoverflow.com/a/7124052
function htmlEscapeInsideAngleBracket(str) {
return str.replace(/</g, "&lt;").replace(/>/g, "&gt;");
@ -328,6 +318,5 @@ module.exports = {
locEnd,
setLocStart,
setLocEnd,
htmlEscapeInsideDoubleQuote,
htmlEscapeInsideAngleBracket
};

View File

@ -139,6 +139,17 @@ exports[`expression.js 1`] = `
"
`;
exports[`html_escape.js 1`] = `
"export default () => <a href=\\"https://foo.bar?q1=foo&q2=bar\\" />;
() => <img src=\\"https://bar.foo?param1=1&param2=2\\" />;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
export default () => <a href=\\"https://foo.bar?q1=foo&q2=bar\\" />;
() => <img src=\\"https://bar.foo?param1=1&param2=2\\" />;
"
`;
exports[`hug.js 1`] = `
"<div>
{__DEV__
@ -279,7 +290,7 @@ exports[`parens.js 1`] = `
<path
key='1'
d='M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,'
/>,
/>,
];
<div {...((foo || foo === null) ? {foo} : null)} />
@ -305,7 +316,7 @@ exports[`quotes.js 1`] = `
<div id={'\\\\'\\"&quot;<>&amp;quot;'} />;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<div id=\\"&quot;'<>&amp;quot;\\" />;
<div id=\\"&quot;'<>&amp;quot;\\" />;
<div id=\\"&quot;&#39;<>&amp;quot;\\" />;
<div id={\\"'\\\\\\"&quot;<>&amp;quot;\\"} />;
"
`;

3
tests/jsx/html_escape.js Normal file
View File

@ -0,0 +1,3 @@
export default () => <a href="https://foo.bar?q1=foo&q2=bar" />;
() => <img src="https://bar.foo?param1=1&param2=2" />;

View File

@ -1 +1 @@
run_spec(__dirname, null, ["typescript"]);
run_spec(__dirname, null, ["babylon", "typescript"]);

View File

@ -6,7 +6,7 @@ a = [
<path
key='1'
d='M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,M13.6,10.6l,4-2.8L9.5,'
/>,
/>,
];
<div {...((foo || foo === null) ? {foo} : null)} />