From 95e29b8f9f08ccc1106de66df096ed332f93306a Mon Sep 17 00:00:00 2001 From: Juan Medina Date: Wed, 2 Dec 2020 18:31:47 -0600 Subject: [PATCH 1/4] Fixing bug #1244 Added validations to prevent tagged literals from being modified --- js/src/javascript/beautifier.js | 11 ++++++++--- js/test/generated/beautify-javascript-tests.js | 4 ++++ python/jsbeautifier/tests/generated/tests.py | 4 ++++ test/data/javascript/tests.js | 12 ++++++++++++ 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/js/src/javascript/beautifier.js b/js/src/javascript/beautifier.js index 6490e4d73..bd6f1e785 100644 --- a/js/src/javascript/beautifier.js +++ b/js/src/javascript/beautifier.js @@ -1057,19 +1057,24 @@ Beautifier.prototype.handle_semicolon = function(current_token) { }; Beautifier.prototype.handle_string = function(current_token) { + var backtickRegex = /^[`].+[`]$/gm; if (this.start_of_statement(current_token)) { // The conditional starts the statement if appropriate. // One difference - strings want at least a space before - this._output.space_before_token = true; + if (!(backtickRegex.test(current_token.text) && (this._flags.last_token.type === TOKEN.END_EXPR || this._flags.last_token.type === TOKEN.WORD) && current_token.whitespace_before === '')) { + this._output.space_before_token = true; + } } else { this.handle_whitespace_and_comments(current_token); if (this._flags.last_token.type === TOKEN.RESERVED || this._flags.last_token.type === TOKEN.WORD || this._flags.inline_frame) { - this._output.space_before_token = true; + if (!(backtickRegex.test(current_token.text) && (this._flags.last_token.type === TOKEN.END_EXPR || this._flags.last_token.type === TOKEN.WORD) && current_token.whitespace_before === '')) { + this._output.space_before_token = true; + } } else if (this._flags.last_token.type === TOKEN.COMMA || this._flags.last_token.type === TOKEN.START_EXPR || this._flags.last_token.type === TOKEN.EQUALS || this._flags.last_token.type === TOKEN.OPERATOR) { if (!this.start_of_object_property()) { this.allow_wrap_or_preserved_newline(current_token); } - } else { + } else if ((backtickRegex.test(current_token.text) && (this._flags.last_token.type === TOKEN.END_EXPR || this._flags.last_token.type === TOKEN.WORD) && current_token.whitespace_before === '')) {} else { this.print_newline(); } } diff --git a/js/test/generated/beautify-javascript-tests.js b/js/test/generated/beautify-javascript-tests.js index 7bb597bad..bf9be7694 100644 --- a/js/test/generated/beautify-javascript-tests.js +++ b/js/test/generated/beautify-javascript-tests.js @@ -3218,6 +3218,10 @@ function run_javascript_tests(test_obj, Urlencoded, js_beautify, html_beautify, '} else {\n' + ' c;\n' + '}'); + bt('fn`tagged`'); + bt('fn()`tagged`'); + bt('fn`${algo} ${`6string`}`'); + bt('fn`${fn2()} more text ${`${`more text`}`} banana ${fn3`test`} ${fn4()`moretest banana2`}`'); //============================================================ diff --git a/python/jsbeautifier/tests/generated/tests.py b/python/jsbeautifier/tests/generated/tests.py index 3ea33818d..d56e3a8c9 100644 --- a/python/jsbeautifier/tests/generated/tests.py +++ b/python/jsbeautifier/tests/generated/tests.py @@ -2979,6 +2979,10 @@ def unicode_char(value): '} else {\n' + ' c;\n' + '}') + bt('fn`tagged`') + bt('fn()`tagged`') + bt('fn`${algo} ${`6string`}`') + bt('fn`${fn2()} more text ${`${`more text`}`} banana ${fn3`test`} ${fn4()`moretest banana2`}`') #============================================================ diff --git a/test/data/javascript/tests.js b/test/data/javascript/tests.js index ad1215496..d9c411532 100644 --- a/test/data/javascript/tests.js +++ b/test/data/javascript/tests.js @@ -1708,6 +1708,18 @@ exports.test_data = { { input: 'if (a)\n{\nb;\n}\nelse\n{\nc;\n}', output: 'if (a) {\n b;\n} else {\n c;\n}' + }, + { + unchanged: 'fn`tagged`' + }, + { + unchanged: 'fn()`tagged`' + }, + { + unchanged: 'fn`${algo} ${`6string`}`' + }, + { + unchanged: 'fn`${fn2()} more text ${`${`more text`}`} banana ${fn3`test`} ${fn4()`moretest banana2`}`' } ] }, { From b14e2451edc5f2fd9de7368c3bbb68ab4395d7ad Mon Sep 17 00:00:00 2001 From: Juan Medina Date: Fri, 18 Dec 2020 23:42:15 -0600 Subject: [PATCH 2/4] Revert "Fixing bug #1244" This reverts commit 95e29b8f9f08ccc1106de66df096ed332f93306a. --- js/src/javascript/beautifier.js | 11 +++-------- js/test/generated/beautify-javascript-tests.js | 4 ---- python/jsbeautifier/tests/generated/tests.py | 4 ---- test/data/javascript/tests.js | 12 ------------ 4 files changed, 3 insertions(+), 28 deletions(-) diff --git a/js/src/javascript/beautifier.js b/js/src/javascript/beautifier.js index bd6f1e785..6490e4d73 100644 --- a/js/src/javascript/beautifier.js +++ b/js/src/javascript/beautifier.js @@ -1057,24 +1057,19 @@ Beautifier.prototype.handle_semicolon = function(current_token) { }; Beautifier.prototype.handle_string = function(current_token) { - var backtickRegex = /^[`].+[`]$/gm; if (this.start_of_statement(current_token)) { // The conditional starts the statement if appropriate. // One difference - strings want at least a space before - if (!(backtickRegex.test(current_token.text) && (this._flags.last_token.type === TOKEN.END_EXPR || this._flags.last_token.type === TOKEN.WORD) && current_token.whitespace_before === '')) { - this._output.space_before_token = true; - } + this._output.space_before_token = true; } else { this.handle_whitespace_and_comments(current_token); if (this._flags.last_token.type === TOKEN.RESERVED || this._flags.last_token.type === TOKEN.WORD || this._flags.inline_frame) { - if (!(backtickRegex.test(current_token.text) && (this._flags.last_token.type === TOKEN.END_EXPR || this._flags.last_token.type === TOKEN.WORD) && current_token.whitespace_before === '')) { - this._output.space_before_token = true; - } + this._output.space_before_token = true; } else if (this._flags.last_token.type === TOKEN.COMMA || this._flags.last_token.type === TOKEN.START_EXPR || this._flags.last_token.type === TOKEN.EQUALS || this._flags.last_token.type === TOKEN.OPERATOR) { if (!this.start_of_object_property()) { this.allow_wrap_or_preserved_newline(current_token); } - } else if ((backtickRegex.test(current_token.text) && (this._flags.last_token.type === TOKEN.END_EXPR || this._flags.last_token.type === TOKEN.WORD) && current_token.whitespace_before === '')) {} else { + } else { this.print_newline(); } } diff --git a/js/test/generated/beautify-javascript-tests.js b/js/test/generated/beautify-javascript-tests.js index bf9be7694..7bb597bad 100644 --- a/js/test/generated/beautify-javascript-tests.js +++ b/js/test/generated/beautify-javascript-tests.js @@ -3218,10 +3218,6 @@ function run_javascript_tests(test_obj, Urlencoded, js_beautify, html_beautify, '} else {\n' + ' c;\n' + '}'); - bt('fn`tagged`'); - bt('fn()`tagged`'); - bt('fn`${algo} ${`6string`}`'); - bt('fn`${fn2()} more text ${`${`more text`}`} banana ${fn3`test`} ${fn4()`moretest banana2`}`'); //============================================================ diff --git a/python/jsbeautifier/tests/generated/tests.py b/python/jsbeautifier/tests/generated/tests.py index d56e3a8c9..3ea33818d 100644 --- a/python/jsbeautifier/tests/generated/tests.py +++ b/python/jsbeautifier/tests/generated/tests.py @@ -2979,10 +2979,6 @@ def unicode_char(value): '} else {\n' + ' c;\n' + '}') - bt('fn`tagged`') - bt('fn()`tagged`') - bt('fn`${algo} ${`6string`}`') - bt('fn`${fn2()} more text ${`${`more text`}`} banana ${fn3`test`} ${fn4()`moretest banana2`}`') #============================================================ diff --git a/test/data/javascript/tests.js b/test/data/javascript/tests.js index d9c411532..ad1215496 100644 --- a/test/data/javascript/tests.js +++ b/test/data/javascript/tests.js @@ -1708,18 +1708,6 @@ exports.test_data = { { input: 'if (a)\n{\nb;\n}\nelse\n{\nc;\n}', output: 'if (a) {\n b;\n} else {\n c;\n}' - }, - { - unchanged: 'fn`tagged`' - }, - { - unchanged: 'fn()`tagged`' - }, - { - unchanged: 'fn`${algo} ${`6string`}`' - }, - { - unchanged: 'fn`${fn2()} more text ${`${`more text`}`} banana ${fn3`test`} ${fn4()`moretest banana2`}`' } ] }, { From 30ca6301e96ccc93f8747a03fcf78de6d4458d9b Mon Sep 17 00:00:00 2001 From: Juan Medina Date: Wed, 23 Dec 2020 11:37:58 -0600 Subject: [PATCH 3/4] Update tokenizer to accept empty tags --- js/src/javascript/tokenizer.js | 2 +- js/test/generated/beautify-javascript-tests.js | 11 +++++++++++ python/jsbeautifier/javascript/tokenizer.py | 2 +- python/jsbeautifier/tests/generated/tests.py | 11 +++++++++++ test/data/javascript/tests.js | 14 ++++++++++++++ 5 files changed, 38 insertions(+), 2 deletions(-) diff --git a/js/src/javascript/tokenizer.js b/js/src/javascript/tokenizer.js index 6e346650b..71e06d399 100644 --- a/js/src/javascript/tokenizer.js +++ b/js/src/javascript/tokenizer.js @@ -126,7 +126,7 @@ var Tokenizer = function(input_string, options) { html_comment_end: pattern_reader.matching(/-->/), include: pattern_reader.starting_with(/#include/).until_after(acorn.lineBreak), shebang: pattern_reader.starting_with(/#!/).until_after(acorn.lineBreak), - xml: pattern_reader.matching(/[\s\S]*?<(\/?)([-a-zA-Z:0-9_.]+|{[\s\S]+?}|!\[CDATA\[[\s\S]*?\]\])(\s+{[\s\S]+?}|\s+[-a-zA-Z:0-9_.]+|\s+[-a-zA-Z:0-9_.]+\s*=\s*('[^']*'|"[^"]*"|{[\s\S]+?}))*\s*(\/?)\s*>/), + xml: pattern_reader.matching(/[\s\S]*?<(\/?)([-a-zA-Z:0-9_.]+|{[\s\S]+?}|!\[CDATA\[[\s\S]*?\]\]|)(\s+{[\s\S]+?}|\s+[-a-zA-Z:0-9_.]+|\s+[-a-zA-Z:0-9_.]+\s*=\s*('[^']*'|"[^"]*"|{[\s\S]+?}))*\s*(\/?)\s*>/), single_quote: templatable.until(/['\\\n\r\u2028\u2029]/), double_quote: templatable.until(/["\\\n\r\u2028\u2029]/), template_text: templatable.until(/[`\\$]/), diff --git a/js/test/generated/beautify-javascript-tests.js b/js/test/generated/beautify-javascript-tests.js index 7bb597bad..6b828740d 100644 --- a/js/test/generated/beautify-javascript-tests.js +++ b/js/test/generated/beautify-javascript-tests.js @@ -4418,6 +4418,17 @@ function run_javascript_tests(test_obj, Urlencoded, js_beautify, html_beautify, ' {children}\n' + ' \n' + ');'); + bt( + 'class Columns extends React.Component {\n' + + ' render() {\n' + + ' return (\n' + + ' \n' + + ' Hello\n' + + ' World\n' + + ' \n' + + ' );\n' + + ' }\n' + + '}'); //============================================================ diff --git a/python/jsbeautifier/javascript/tokenizer.py b/python/jsbeautifier/javascript/tokenizer.py index 00f39da22..2e01a23f7 100644 --- a/python/jsbeautifier/javascript/tokenizer.py +++ b/python/jsbeautifier/javascript/tokenizer.py @@ -119,7 +119,7 @@ def __init__(self): directives_core = Directives(r"/\*", r"\*/") xmlRegExp = re.compile( - r'[\s\S]*?<(\/?)([-a-zA-Z:0-9_.]+|{[\s\S]+?}|!\[CDATA\[[\s\S]*?\]\])(\s+{[\s\S]+?}|\s+[-a-zA-Z:0-9_.]+|\s+[-a-zA-Z:0-9_.]+\s*=\s*(\'[^\']*\'|"[^"]*"|{[\s\S]+?}))*\s*(/?)\s*>' + r'[\s\S]*?<(\/?)([-a-zA-Z:0-9_.]+|{[\s\S]+?}|!\[CDATA\[[\s\S]*?\]\]|)(\s+{[\s\S]+?}|\s+[-a-zA-Z:0-9_.]+|\s+[-a-zA-Z:0-9_.]+\s*=\s*(\'[^\']*\'|"[^"]*"|{[\s\S]+?}))*\s*(/?)\s*>' ) diff --git a/python/jsbeautifier/tests/generated/tests.py b/python/jsbeautifier/tests/generated/tests.py index 3ea33818d..e9efd88a9 100644 --- a/python/jsbeautifier/tests/generated/tests.py +++ b/python/jsbeautifier/tests/generated/tests.py @@ -4168,6 +4168,17 @@ def unicode_char(value): ' {children}\n' + ' \n' + ');') + bt( + 'class Columns extends React.Component {\n' + + ' render() {\n' + + ' return (\n' + + ' \n' + + ' Hello\n' + + ' World\n' + + ' \n' + + ' );\n' + + ' }\n' + + '}') #============================================================ diff --git a/test/data/javascript/tests.js b/test/data/javascript/tests.js index ad1215496..225d3d319 100644 --- a/test/data/javascript/tests.js +++ b/test/data/javascript/tests.js @@ -2490,6 +2490,20 @@ exports.test_data = { ' ', ');' ] + }, + { + unchanged: [ + 'class Columns extends React.Component {', + ' render() {', + ' return (', + ' ', + ' Hello', + ' World', + ' ', + ' );', + ' }', + '}' + ] } ] }, From f13a684f8c8f87f8ea9654331016331e35784eeb Mon Sep 17 00:00:00 2001 From: Juan Medina Date: Wed, 23 Dec 2020 16:09:25 -0600 Subject: [PATCH 4/4] Changed test back to empty tags --- js/test/generated/beautify-javascript-tests.js | 4 ++-- python/jsbeautifier/tests/generated/tests.py | 4 ++-- test/data/javascript/tests.js | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/js/test/generated/beautify-javascript-tests.js b/js/test/generated/beautify-javascript-tests.js index 6b828740d..35aab5a11 100644 --- a/js/test/generated/beautify-javascript-tests.js +++ b/js/test/generated/beautify-javascript-tests.js @@ -4422,10 +4422,10 @@ function run_javascript_tests(test_obj, Urlencoded, js_beautify, html_beautify, 'class Columns extends React.Component {\n' + ' render() {\n' + ' return (\n' + - ' \n' + + ' <>\n' + ' Hello\n' + ' World\n' + - ' \n' + + ' \n' + ' );\n' + ' }\n' + '}'); diff --git a/python/jsbeautifier/tests/generated/tests.py b/python/jsbeautifier/tests/generated/tests.py index e9efd88a9..87cfed911 100644 --- a/python/jsbeautifier/tests/generated/tests.py +++ b/python/jsbeautifier/tests/generated/tests.py @@ -4172,10 +4172,10 @@ def unicode_char(value): 'class Columns extends React.Component {\n' + ' render() {\n' + ' return (\n' + - ' \n' + + ' <>\n' + ' Hello\n' + ' World\n' + - ' \n' + + ' \n' + ' );\n' + ' }\n' + '}') diff --git a/test/data/javascript/tests.js b/test/data/javascript/tests.js index 225d3d319..4a30146e5 100644 --- a/test/data/javascript/tests.js +++ b/test/data/javascript/tests.js @@ -2496,10 +2496,10 @@ exports.test_data = { 'class Columns extends React.Component {', ' render() {', ' return (', - ' ', + ' <>', ' Hello', ' World', - ' ', + ' ', ' );', ' }', '}'