This is an automated email from the ASF dual-hosted git repository.
joshtynjala pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/royale-compiler.git
The following commit(s) were added to refs/heads/develop by this push:
new 255bb4d04 formatter: fix stack overflow on some platforms when MXML
Script text is beyond a certain length
255bb4d04 is described below
commit 255bb4d040755184be0dfb176ac5608061bd1305
Author: Josh Tynjala <[email protected]>
AuthorDate: Fri Aug 11 10:45:13 2023 -0700
formatter: fix stack overflow on some platforms when MXML Script text is
beyond a certain length
Java's regular expressions don't seem to like lazy quantifiers, on Windows
especially
---
.../royale/formatter/MXMLTokenFormatter.java | 26 +++++++----
.../apache/royale/formatter/TestMXMLMetadata.java | 48 +++++++++++++++++++++
.../apache/royale/formatter/TestMXMLScript.java | 50 ++++++++++++++++++++++
3 files changed, 115 insertions(+), 9 deletions(-)
diff --git
a/formatter/src/main/java/org/apache/royale/formatter/MXMLTokenFormatter.java
b/formatter/src/main/java/org/apache/royale/formatter/MXMLTokenFormatter.java
index a0b5dccd6..f514eaa99 100644
---
a/formatter/src/main/java/org/apache/royale/formatter/MXMLTokenFormatter.java
+++
b/formatter/src/main/java/org/apache/royale/formatter/MXMLTokenFormatter.java
@@ -38,6 +38,8 @@ import
org.apache.royale.formatter.internal.BaseTokenFormatter;
public class MXMLTokenFormatter extends BaseTokenFormatter {
private static final int TOKEN_TYPE_EXTRA = 999999;
private static final Pattern SCRIPT_START_PATTERN =
Pattern.compile("<((?:mx|fx):(Script|Metadata))");
+ private static final Pattern TAG_START_WITH_OPTIONAL_CDATA_PATTERN =
Pattern.compile("^<((?:mx|fx):(\\w+))>\\s*(<!\\[CDATA\\[)?");
+ private static final Pattern TAG_END_WITH_OPTIONAL_CDATA_PATTERN =
Pattern.compile("(?:\\]\\]>)?\\s*<\\/(?:mx|fx):(?:\\w+)>$");
private static final String FORMATTER_TAG_OFF = "@formatter:off";
private static final String FORMATTER_TAG_ON = "@formatter:on";
@@ -338,22 +340,28 @@ public class MXMLTokenFormatter extends
BaseTokenFormatter {
}
}
StringBuilder builder = new StringBuilder();
- Pattern scriptPattern = Pattern.compile(
-
"^<((?:mx|fx):(\\w+))>\\s*(<!\\[CDATA\\[)?((?:.|(?:\\r?\\n))*?)(?:\\]\\]>)?\\s*<\\/(?:mx|fx):(?:\\w+)>$");
- Matcher scriptMatcher = scriptPattern.matcher(text);
- if (!scriptMatcher.matches()) {
+ Matcher scriptStartMatcher =
TAG_START_WITH_OPTIONAL_CDATA_PATTERN.matcher(text);
+ if (!scriptStartMatcher.find() || scriptStartMatcher.end() >
text.length()) {
return text;
}
+
+ int startEndSearch = scriptStartMatcher.end();
+ Matcher scriptEndMatcher =
TAG_END_WITH_OPTIONAL_CDATA_PATTERN.matcher(text.substring(startEndSearch));
+ if (!scriptEndMatcher.find()) {
+ return text;
+ }
+
+ String scriptTagText = scriptStartMatcher.group(1);
+ String scriptTagName = scriptStartMatcher.group(2);
+ String cdataText = scriptStartMatcher.group(3);
+ String scriptText = text.substring(startEndSearch,
startEndSearch + scriptEndMatcher.start());
+ boolean requireCdata = cdataText != null ||
"Script".equals(scriptTagName);
+
if (problems == null) {
// we need to know if there were problems because it
means that we
// need to return the original, unformatted text
problems = new ArrayList<ICompilerProblem>();
}
- String scriptTagText = scriptMatcher.group(1);
- String scriptTagName = scriptMatcher.group(2);
- String cdataText = scriptMatcher.group(3);
- String scriptText = scriptMatcher.group(4);
- boolean requireCdata = cdataText != null ||
"Script".equals(scriptTagName);
ASTokenFormatter asFormatter = new ASTokenFormatter(settings);
String formattedScriptText = asFormatter.format(filePath +
"@Script[" + line + "]", scriptText, problems);
if (!settings.ignoreProblems && hasErrors(problems)) {
diff --git
a/formatter/src/test/java/org/apache/royale/formatter/TestMXMLMetadata.java
b/formatter/src/test/java/org/apache/royale/formatter/TestMXMLMetadata.java
index c9264ca07..57c36cf62 100644
--- a/formatter/src/test/java/org/apache/royale/formatter/TestMXMLMetadata.java
+++ b/formatter/src/test/java/org/apache/royale/formatter/TestMXMLMetadata.java
@@ -48,6 +48,29 @@ public class TestMXMLMetadata extends BaseFormatterTests {
result);
}
+ @Test
+ public void testEmptyMetadataNoCdataNoWhitespace() {
+ FormatterSettings settings = new FormatterSettings();
+ settings.insertSpaces = false;
+ MXMLTokenFormatter formatter = new MXMLTokenFormatter(settings);
+ String result = formatter.format("file.mxml",
+ // @formatter:off
+ "<s:Application>\n" +
+ "<fx:Metadata></fx:Metadata>\n" +
+ "</s:Application>",
+ // @formatter:on
+ problems
+ );
+ assertEquals(
+ // @formatter:off
+ "<s:Application>\n" +
+ "\t<fx:Metadata>\n" +
+ "\t</fx:Metadata>\n" +
+ "</s:Application>",
+ // @formatter:on
+ result);
+ }
+
@Test
public void testEmptyMetadataWithCdata() {
FormatterSettings settings = new FormatterSettings();
@@ -76,6 +99,31 @@ public class TestMXMLMetadata extends BaseFormatterTests {
result);
}
+ @Test
+ public void testEmptyMetadataWithCdataNoWhitespace() {
+ FormatterSettings settings = new FormatterSettings();
+ settings.insertSpaces = false;
+ MXMLTokenFormatter formatter = new MXMLTokenFormatter(settings);
+ String result = formatter.format("file.mxml",
+ // @formatter:off
+ "<s:Application>\n" +
+ "<fx:Metadata><![CDATA[]]></fx:Metadata>\n" +
+ "</s:Application>",
+ // @formatter:on
+ problems
+ );
+ assertEquals(
+ // @formatter:off
+ "<s:Application>\n" +
+ "\t<fx:Metadata>\n" +
+ "\t\t<![CDATA[\n" +
+ "\t\t]]>\n" +
+ "\t</fx:Metadata>\n" +
+ "</s:Application>",
+ // @formatter:on
+ result);
+ }
+
@Test
public void testSingleMetadata() {
FormatterSettings settings = new FormatterSettings();
diff --git
a/formatter/src/test/java/org/apache/royale/formatter/TestMXMLScript.java
b/formatter/src/test/java/org/apache/royale/formatter/TestMXMLScript.java
index e40e2f62c..f5c6783e1 100644
--- a/formatter/src/test/java/org/apache/royale/formatter/TestMXMLScript.java
+++ b/formatter/src/test/java/org/apache/royale/formatter/TestMXMLScript.java
@@ -50,6 +50,31 @@ public class TestMXMLScript extends BaseFormatterTests {
result);
}
+ @Test
+ public void testEmptyScriptNoCdataNoWhitespace() {
+ FormatterSettings settings = new FormatterSettings();
+ settings.insertSpaces = false;
+ MXMLTokenFormatter formatter = new MXMLTokenFormatter(settings);
+ String result = formatter.format("file.mxml",
+ // @formatter:off
+ "<s:Application>\n" +
+ "<fx:Script></fx:Script>\n" +
+ "</s:Application>",
+ // @formatter:on
+ problems
+ );
+ assertEquals(
+ // @formatter:off
+ "<s:Application>\n" +
+ "\t<fx:Script>\n" +
+ "\t\t<![CDATA[\n" +
+ "\t\t]]>\n" +
+ "\t</fx:Script>\n" +
+ "</s:Application>",
+ // @formatter:on
+ result);
+ }
+
@Test
public void testEmptyScriptWithCdata() {
FormatterSettings settings = new FormatterSettings();
@@ -78,6 +103,31 @@ public class TestMXMLScript extends BaseFormatterTests {
result);
}
+ @Test
+ public void testEmptyScriptWithCdataNoWhitespace() {
+ FormatterSettings settings = new FormatterSettings();
+ settings.insertSpaces = false;
+ MXMLTokenFormatter formatter = new MXMLTokenFormatter(settings);
+ String result = formatter.format("file.mxml",
+ // @formatter:off
+ "<s:Application>\n" +
+ "<fx:Script><![CDATA[]]></fx:Script>\n" +
+ "</s:Application>",
+ // @formatter:on
+ problems
+ );
+ assertEquals(
+ // @formatter:off
+ "<s:Application>\n" +
+ "\t<fx:Script>\n" +
+ "\t\t<![CDATA[\n" +
+ "\t\t]]>\n" +
+ "\t</fx:Script>\n" +
+ "</s:Application>",
+ // @formatter:on
+ result);
+ }
+
@Test
public void testScriptWithActionScript() {
FormatterSettings settings = new FormatterSettings();