Skip to content

Commit

Permalink
fix(es/minifier): Don't evaluate String.fromCharCode for non-ascii …
Browse files Browse the repository at this point in the history
…values (#6033)
  • Loading branch information
kdy1 authored Oct 4, 2022
1 parent 7746bfb commit 197c4e2
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 14 deletions.
3 changes: 3 additions & 0 deletions crates/swc_ecma_minifier/src/compress/optimize/evaluate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,9 @@ where
let v = char_code.floor() as u32;

if let Some(v) = char::from_u32(v) {
if !v.is_ascii() {
return;
}
self.changed = true;
report_change!(
"evaluate: Evaluated `String.charCodeAt({})` as `{}`",
Expand Down
2 changes: 2 additions & 0 deletions crates/swc_ecma_minifier/src/compress/pure/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,8 @@ impl Pure<'_> {
})
.unwrap_or_default();

report_change!("Optimized regex");

Some(Expr::Lit(Lit::Regex(Regex {
span: *span,
exp: pattern.into(),
Expand Down
20 changes: 20 additions & 0 deletions crates/swc_ecma_minifier/tests/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10110,3 +10110,23 @@ fn issue_5914() {

run_exec_test(src, config, false);
}

#[test]
fn feedback_regex_range() {
let src = r###"
const rtlRegEx = new RegExp(
/* eslint-disable prettier/prettier */
'[' +
String.fromCharCode(0x00591) + '-' + String.fromCharCode(0x008ff) +
String.fromCharCode(0x0fb1d) + '-' + String.fromCharCode(0x0fdff) +
String.fromCharCode(0x0fe70) + '-' + String.fromCharCode(0x0fefc) +
String.fromCharCode(0x10800) + '-' + String.fromCharCode(0x10fff) +
String.fromCharCode(0x1e800) + '-' + String.fromCharCode(0x1efff) +
']'
/* eslint-enable prettier/prettier */
);
console.log('PASS')
"###;

run_default_exec_test(src);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export const rtlRegEx = new RegExp(
/* eslint-disable prettier/prettier */
'[' +
String.fromCharCode(0x00591) + '-' + String.fromCharCode(0x008ff) +
String.fromCharCode(0x0fb1d) + '-' + String.fromCharCode(0x0fdff) +
String.fromCharCode(0x0fe70) + '-' + String.fromCharCode(0x0fefc) +
String.fromCharCode(0x10800) + '-' + String.fromCharCode(0x10fff) +
String.fromCharCode(0x1e800) + '-' + String.fromCharCode(0x1efff) +
']'
/* eslint-enable prettier/prettier */
);

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -1557,7 +1557,7 @@
for(var n = e[r], i = void 0, o = 0; i = eL.exec(n.string);){
var a = i.index, u = i[0], l = n.attributes.fontSize, s = n.string.slice(o, a + i[0].length);
eN[u] && eN[u].data ? t.push({
string: s.replace(i, ""),
string: s.replace(i, String.fromCharCode(0xfffc)),
attributes: U.default({}, n.attributes, {
attachment: {
width: l,
Expand Down Expand Up @@ -2233,7 +2233,7 @@
}, k = 0; k < r.children.length; k += 1){
var O, C, P, F = r.children[k];
F.type === T.Image ? o.push({
string: "",
string: String.fromCharCode(0xfffc),
attributes: U.default({}, A, {
attachment: {
width: F.style.width || h,
Expand Down Expand Up @@ -5422,15 +5422,19 @@
"use strict";
var n = r(5318).default;
t.__esModule = !0, t.default = void 0;
var i = r(4354), o = n(r(4573)), a = n(r(9845)), u = function(e) {
var t = (null === (n = (0, i.last)(e)) || void 0 === n ? void 0 : n.runs) || [], r = null === (u = (0, i.last)(t)) || void 0 === u ? void 0 : null === (l = u.attributes) || void 0 === l ? void 0 : l.font;
var i = r(4354), o = n(r(4573)), a = n(r(9845)), u = String.fromCharCode(8230), l = function(e) {
if (!e.encode) return 8230;
var t = e.encode(u)[0];
return parseInt(t[0], 16);
}, s = function(e) {
var t = (null === (n = (0, i.last)(e)) || void 0 === n ? void 0 : n.runs) || [], r = null === (u = (0, i.last)(t)) || void 0 === u ? void 0 : null === (s = u.attributes) || void 0 === s ? void 0 : s.font;
if (r) {
var n, u, l, s, c = e.length - 1, f = r.encode ? parseInt(r.encode("…")[0][0], 16) : 8230, d = r.glyphForCodePoint(f), p = (0, a.default)(d, (0, o.default)(e[c]));
return Object.assign([], e, ((s = {})[c] = p, s));
var n, u, s, c, f = e.length - 1, d = l(r), p = r.glyphForCodePoint(d), h = (0, a.default)(p, (0, o.default)(e[f]));
return Object.assign([], e, ((c = {})[f] = h, c));
}
return e;
};
t.default = u;
t.default = s;
},
7518: function(e, t) {
"use strict";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10793,7 +10793,7 @@
}), this.restrict(e), 'HTML' === this.editorMode && this.cleanList(e), 'HTML' === this.editorMode && (8 === e.which && 'Backspace' === e.code || 46 === e.which && 'Delete' === e.code)) {
var range = this.getRange(), startNode = '#text' === range.startContainer.nodeName ? range.startContainer.parentElement : range.startContainer;
if ((0, ej2_base.oq)(startNode, 'pre') && 8 === e.which && 8203 === range.startContainer.textContent.charCodeAt(range.startOffset - 1) || 46 === e.which && 8203 === range.startContainer.textContent.charCodeAt(range.startOffset)) {
var regEx = RegExp("​", 'g'), pointer = 8 === e.which ? range.startOffset - 1 : range.startOffset;
var regEx = RegExp(String.fromCharCode(8203), 'g'), pointer = 8 === e.which ? range.startOffset - 1 : range.startOffset;
range.startContainer.textContent = range.startContainer.textContent.replace(regEx, ''), this.formatter.editorManager.nodeSelection.setCursorPoint(this.contentModule.getDocument(), range.startContainer, pointer);
} else if ('Backspace' === e.code && 8 === e.which && 8203 === range.startContainer.textContent.charCodeAt(0) && range.collapsed) {
var parentEle = range.startContainer.parentElement, index = void 0, i = void 0;
Expand Down Expand Up @@ -12783,7 +12783,7 @@
}
}
}, Formats.prototype.removeCodeContent = function(range) {
var regEx = RegExp("\uFEFF", 'g');
var regEx = RegExp(String.fromCharCode(65279), 'g');
if (!(0, ej2_base.le)(range.endContainer.textContent.match(regEx))) {
var pointer = 65279 === range.endContainer.textContent.charCodeAt(range.endOffset - 1) ? range.endOffset - 2 : range.endOffset;
range.endContainer.textContent = range.endContainer.textContent.replace(regEx, ''), '' === range.endContainer.textContent ? this.parent.nodeSelection.setCursorPoint(this.parent.currentDocument, range.endContainer.parentElement, 0) : this.parent.nodeSelection.setCursorPoint(this.parent.currentDocument, range.endContainer, pointer);
Expand Down Expand Up @@ -14023,7 +14023,7 @@
if (range.collapsed) {
var currentFormatNode = isFormatted.getFormattedNode(range.startContainer, format, endNode), currentSelector = (0, ej2_base.le)(currentFormatNode) ? null : null === currentFormatNode.getAttribute('style') ? currentFormatNode.nodeName : currentFormatNode.nodeName + "[style='" + currentFormatNode.getAttribute('style') + "']";
if (nodes.length > 0) isCollapsed = !0, range = nodeCutter.GetCursorRange(docElement, range, nodes[0]);
else if (3 === range.startContainer.nodeType && (range.startContainer.parentElement.childElementCount > 0 && range.startOffset > 0 && 'br' !== range.startContainer.parentElement.firstElementChild.tagName.toLowerCase() || !(0, ej2_base.le)(currentFormatNode) && currentFormatNode === range.startContainer.parentElement.closest(currentSelector) && 0 != range.startContainer.parentElement.closest(currentSelector).textContent.replace(RegExp("​", 'g'), '').trim().length)) isCollapsed = !0, range = nodeCutter.GetCursorRange(docElement, range, range.startContainer), nodes.push(range.startContainer);
else if (3 === range.startContainer.nodeType && (range.startContainer.parentElement.childElementCount > 0 && range.startOffset > 0 && 'br' !== range.startContainer.parentElement.firstElementChild.tagName.toLowerCase() || !(0, ej2_base.le)(currentFormatNode) && currentFormatNode === range.startContainer.parentElement.closest(currentSelector) && 0 != range.startContainer.parentElement.closest(currentSelector).textContent.replace(RegExp(String.fromCharCode(8203), 'g'), '').trim().length)) isCollapsed = !0, range = nodeCutter.GetCursorRange(docElement, range, range.startContainer), nodes.push(range.startContainer);
else {
var cursorNode = this.insertCursorNode(docElement, domSelection, range, isFormatted, nodeCutter, format, value, endNode);
domSelection.endContainer = domSelection.startContainer = domSelection.getNodeArray(cursorNode, !0);
Expand All @@ -14042,7 +14042,7 @@
var cursorNodes = domSelection.getNodeCollection(range), domNode = new DOMNode(endNode, docElement), cursorFormat = cursorNodes.length > 0 ? cursorNodes.length > 1 && range.startContainer === range.endContainer ? this.getCursorFormat(isFormatted, cursorNodes, format, endNode) : isFormatted.getFormattedNode(cursorNodes[0], format, endNode) : null, cursorNode = null;
if (cursorFormat) {
if (cursorNode = cursorNodes[0], 8203 === cursorFormat.firstChild.textContent.charCodeAt(0) && 3 === cursorFormat.firstChild.nodeType) {
var regEx = RegExp("​", 'g'), emptySpaceNode = void 0;
var regEx = RegExp(String.fromCharCode(8203), 'g'), emptySpaceNode = void 0;
cursorFormat.firstChild === cursorNode ? (cursorNode.textContent = cursorFormat.parentElement && (domNode.isBlockNode(cursorFormat.parentElement) && cursorFormat.parentElement.textContent.length <= 1 ? cursorFormat.parentElement.childElementCount > 1 : 0 === cursorFormat.childElementCount) && (cursorFormat.parentElement.textContent.length > 1 || cursorFormat.parentElement.firstChild && 1 === cursorFormat.parentElement.firstChild.nodeType) ? cursorNode.textContent : cursorNode.textContent.replace(regEx, ''), emptySpaceNode = cursorNode) : (cursorFormat.firstChild.textContent = cursorFormat.firstChild.textContent.replace(regEx, ''), emptySpaceNode = cursorFormat.firstChild);
var pointer = void 0;
if (0 === emptySpaceNode.textContent.length) {
Expand Down Expand Up @@ -15517,7 +15517,7 @@
}, HtmlEditor.prototype.onSelectionRestore = function(e) {
this.parent.isBlur = !1, this.contentRenderer.getEditPanel().focus(), ((0, ej2_base.le)(e.items) || e.items) && this.saveSelection.restore();
}, HtmlEditor.prototype.onKeyUp = function(e) {
var pointer, args = e.args, range = this.parent.getRange(), regEx = RegExp("​", 'g');
var pointer, args = e.args, range = this.parent.getRange(), regEx = RegExp(String.fromCharCode(8203), 'g');
!(0 > [
8,
9,
Expand Down Expand Up @@ -28330,11 +28330,11 @@
return this.getSelectionNodesBr(this.getNodeCollection(range));
}, NodeSelection.prototype.getSelectionNodes = function(nodeCollection) {
nodeCollection = nodeCollection.reverse();
for(var regEx = RegExp("​", 'g'), index = 0; index < nodeCollection.length; index++)(3 !== nodeCollection[index].nodeType || '' === nodeCollection[index].textContent.trim() || 1 === nodeCollection[index].textContent.length && nodeCollection[index].textContent.match(regEx)) && (nodeCollection.splice(index, 1), index--);
for(var regEx = RegExp(String.fromCharCode(8203), 'g'), index = 0; index < nodeCollection.length; index++)(3 !== nodeCollection[index].nodeType || '' === nodeCollection[index].textContent.trim() || 1 === nodeCollection[index].textContent.length && nodeCollection[index].textContent.match(regEx)) && (nodeCollection.splice(index, 1), index--);
return nodeCollection.reverse();
}, NodeSelection.prototype.getSelectionNodesBr = function(nodeCollection) {
nodeCollection = nodeCollection.reverse();
for(var regEx = RegExp("​", 'g'), index = 0; index < nodeCollection.length; index++)'BR' !== nodeCollection[index].nodeName && (3 !== nodeCollection[index].nodeType || '' === nodeCollection[index].textContent.trim() || 1 === nodeCollection[index].textContent.length && nodeCollection[index].textContent.match(regEx)) && (nodeCollection.splice(index, 1), index--);
for(var regEx = RegExp(String.fromCharCode(8203), 'g'), index = 0; index < nodeCollection.length; index++)'BR' !== nodeCollection[index].nodeName && (3 !== nodeCollection[index].nodeType || '' === nodeCollection[index].textContent.trim() || 1 === nodeCollection[index].textContent.length && nodeCollection[index].textContent.match(regEx)) && (nodeCollection.splice(index, 1), index--);
return nodeCollection.reverse();
}, NodeSelection.prototype.getInsertNodeCollection = function(range) {
return this.getInsertNodes(this.getNodeCollection(range));
Expand Down

1 comment on commit 197c4e2

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: 197c4e2 Previous: c485099 Ratio
es/full/minify/libraries/antd 2015599464 ns/iter (± 68035698) 1938069534 ns/iter (± 191017062) 1.04
es/full/minify/libraries/d3 400699807 ns/iter (± 28182827) 381110153 ns/iter (± 33381537) 1.05
es/full/minify/libraries/echarts 1540969393 ns/iter (± 88508515) 1487816765 ns/iter (± 99087614) 1.04
es/full/minify/libraries/jquery 106640398 ns/iter (± 9723597) 92672060 ns/iter (± 13975938) 1.15
es/full/minify/libraries/lodash 141184190 ns/iter (± 16966109) 116728366 ns/iter (± 2923842) 1.21
es/full/minify/libraries/moment 60853783 ns/iter (± 5570227) 53112963 ns/iter (± 1393704) 1.15
es/full/minify/libraries/react 22783319 ns/iter (± 4277129) 20345586 ns/iter (± 2672636) 1.12
es/full/minify/libraries/terser 323756296 ns/iter (± 15545763) 298616799 ns/iter (± 36710174) 1.08
es/full/minify/libraries/three 522546434 ns/iter (± 16136740) 546508982 ns/iter (± 414745557) 0.96
es/full/minify/libraries/typescript 3512655795 ns/iter (± 186948066) 3368334246 ns/iter (± 132620049) 1.04
es/full/minify/libraries/victory 969085923 ns/iter (± 353575210) 791008956 ns/iter (± 120251038) 1.23
es/full/minify/libraries/vue 157653496 ns/iter (± 13527087) 138259070 ns/iter (± 15871191) 1.14
es/full/codegen/es3 34657 ns/iter (± 2601) 34151 ns/iter (± 1794) 1.01
es/full/codegen/es5 34895 ns/iter (± 5754) 34108 ns/iter (± 5022) 1.02
es/full/codegen/es2015 34741 ns/iter (± 4841) 33935 ns/iter (± 1344) 1.02
es/full/codegen/es2016 34159 ns/iter (± 5076) 33966 ns/iter (± 1820) 1.01
es/full/codegen/es2017 34763 ns/iter (± 4637) 33755 ns/iter (± 964) 1.03
es/full/codegen/es2018 35408 ns/iter (± 8271) 34206 ns/iter (± 9638) 1.04
es/full/codegen/es2019 34925 ns/iter (± 4992) 34123 ns/iter (± 1032) 1.02
es/full/codegen/es2020 34294 ns/iter (± 2736) 33751 ns/iter (± 1832) 1.02
es/full/all/es3 225232780 ns/iter (± 18837357) 198851563 ns/iter (± 23229565) 1.13
es/full/all/es5 210118684 ns/iter (± 18050430) 187149203 ns/iter (± 20290404) 1.12
es/full/all/es2015 162146384 ns/iter (± 15500366) 151784906 ns/iter (± 15687342) 1.07
es/full/all/es2016 163314876 ns/iter (± 14106843) 150974991 ns/iter (± 17550174) 1.08
es/full/all/es2017 160584253 ns/iter (± 17186508) 149988091 ns/iter (± 21528681) 1.07
es/full/all/es2018 146837027 ns/iter (± 14226079) 148765985 ns/iter (± 19253442) 0.99
es/full/all/es2019 163364984 ns/iter (± 18255459) 148101573 ns/iter (± 19670829) 1.10
es/full/all/es2020 138415607 ns/iter (± 12609983) 143943377 ns/iter (± 16754786) 0.96
es/full/parser 721402 ns/iter (± 14129) 761322 ns/iter (± 54220) 0.95
es/full/base/fixer 25873 ns/iter (± 608) 26925 ns/iter (± 3445) 0.96
es/full/base/resolver_and_hygiene 94577 ns/iter (± 2948) 95319 ns/iter (± 7481) 0.99
serialization of ast node 219 ns/iter (± 7) 219 ns/iter (± 20) 1
serialization of serde 220 ns/iter (± 3) 222 ns/iter (± 13) 0.99

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.