Skip to content

Commit

Permalink
Fix infinite loop inside LSPMessageFormatter for some cases
Browse files Browse the repository at this point in the history
Fixes eclipse-lemminx#856

Signed-off-by: azerr <[email protected]>
  • Loading branch information
angelozerr committed Sep 25, 2020
1 parent b132e4b commit f68e014
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -137,29 +137,28 @@ public static Object[] reformatSchemaArguments(XMLSchemaErrorCode code, Object[]
}
}

private static String reformatElementNames(boolean hasNamespace, String names) {
StringBuilder sb = new StringBuilder();

private static String reformatElementNames(String names) {
StringBuilder result = new StringBuilder();
MultiLineStream stream = new MultiLineStream(names, 0);

while (!stream.eos()) { // }
stream.advance(1);// Consume ' ' or '{' if first item
if(hasNamespace) {
// Check if the current character is a quote, which means that it's a namespace.
// ex : "http://maven.apache.org/POM/4.0.0":propertiesa
boolean hasNamespace = stream.peekChar() == _DQO;
if (hasNamespace) {
stream.advance(1); // Consume "
stream.advanceUntilAnyOfChars(_DQO, _SQO, _SIQ); // " | " | '
stream.advance(2); // Consume quotation and':'
}
sb.append(" - ");
result.append(" - ");
while (stream.peekChar() != _CCB && stream.peekChar() != _CMA) { // } | ,
sb.append(Character.toString((char) stream.peekChar()));
result.append(Character.toString((char) stream.peekChar()));
stream.advance(1);
}
sb.append("\n");
//if (stream.peekChar() == _CMA) {
stream.advance(1);
//}
result.append("\n");
stream.advance(1);
}
return sb.toString();
return result.toString();
}

/**
Expand Down Expand Up @@ -199,10 +198,6 @@ private static Matcher getNamespaceMatcher(String name) {
return namespacePattern.matcher(name);
}

// private static boolean isNamespaceDefined(String name) {
// return getNamespaceMatcher(name).matches();
// }

/**
* Parses the message for cvc.2.4.a and returns reformatted arguments
*
Expand All @@ -228,11 +223,11 @@ private static Object[] cvc_2_4_a_solution(Object[] arguments) {
if (m.matches()) {
name = m.group(2);
schema = "{" + m.group(1) + "}";
validNames = reformatElementNames(true, getString(arguments[1]));
validNames = reformatElementNames(getString(arguments[1]));
} else { // No namespace, so just element name
name = getString(arguments[0]);
schema = "{the schema}";
validNames = reformatElementNames(false, getString(arguments[1]));
validNames = reformatElementNames(getString(arguments[1]));
}
name = "- " + name;
return new Object[] { name, validNames, schema };
Expand Down Expand Up @@ -262,11 +257,11 @@ private static Object[] cvc_2_4_b_solution(Object[] arguments) {
String schema = null;

if (m.matches()) {
missingChildElements = reformatElementNames(true, getString(arguments[1]));
missingChildElements = reformatElementNames(getString(arguments[1]));
schema = "{" + m.group(1) + "}";
} else {
// No namespace, so just element name
missingChildElements = reformatElementNames(false, getString(arguments[1]));
missingChildElements = reformatElementNames(getString(arguments[1]));
schema = "{the schema}";
}
element = "- " + getString(arguments[0]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -561,20 +561,52 @@ public void fuzzyElementNameCodeActionTest() throws Exception {

@Test
public void fuzzyElementNamesWithOtherOptionsCodeActionTest() throws Exception {
String xml =
"<project xmlns=\"http://maven.apache.org/POM/4.0.0\" \r\n" +
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\r\n" +
" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\r\n" +
" <ciManagement>\r\n" +
" <XXXXXXXXX></XXXXXXXXX>\r\n" + // does not fuzzy match any, so provide code action for all possible
" </ciManagement>\r\n" +
"</project>";
Diagnostic diagnostic = d(4, 7, 4, 16, XMLSchemaErrorCode.cvc_complex_type_2_4_a,
"Invalid element name:\n - XXXXXXXXX\n\nOne of the following is expected:\n - system\n - url\n - notifiers\n\nError indicated by:\n {http://maven.apache.org/POM/4.0.0}\nwith code:");
String xml = "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" \r\n" + //
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\r\n" + //
" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\r\n"
+ //
" <ciManagement>\r\n" + //
" <XXXXXXXXX></XXXXXXXXX>\r\n" + // does not fuzzy match any, so provide code action for all
// possible
" </ciManagement>\r\n" + //
"</project>";
Diagnostic diagnostic = d(4, 7, 4, 16, XMLSchemaErrorCode.cvc_complex_type_2_4_a, //
"Invalid element name:\n" + //
" - XXXXXXXXX\n\n" + //
"One of the following is expected:\n" + //
" - system\n" + //
" - url\n" + //
" - notifiers\n\n" + "Error indicated by:\n" + //
" {http://maven.apache.org/POM/4.0.0}\n" + //
"with code:");
testDiagnosticsFor(xml, diagnostic);

testCodeActionsFor(xml, diagnostic, ca(diagnostic, te(4, 7, 4, 16, "notifiers"), te(4, 19, 4, 28, "notifiers")), ca(diagnostic, te(4, 7, 4, 16, "system"), te(4, 19, 4, 28, "system")), ca(diagnostic, te(4, 7, 4, 16, "url"), te(4, 19, 4, 28, "url")));
testCodeActionsFor(xml, diagnostic, //
ca(diagnostic, te(4, 7, 4, 16, "notifiers"), te(4, 19, 4, 28, "notifiers")), //
ca(diagnostic, te(4, 7, 4, 16, "system"), te(4, 19, 4, 28, "system")), //
ca(diagnostic, te(4, 7, 4, 16, "url"), te(4, 19, 4, 28, "url")));
}

/**
*
* @throws Exception
* @see https://github.com/eclipse/lemminx/issues/856
*/
@Test
public void elementFormDefaultUnqualified() throws Exception {
String xml = "<foo xmlns=\"http://foo\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://foo foo-unqualified.xsd\">\r\n"
+ //
" <bar />\r\n" + //
"</foo>";
Diagnostic diagnostic = d(1, 2, 1, 5, XMLSchemaErrorCode.cvc_complex_type_2_4_a, //
"Invalid element name:\n" + //
" - bar\n\n" + //
"One of the following is expected:\n" + //
" - bar\n\n" + //
"Error indicated by:\n" + //
" {http://foo}\n" + //
"with code:");
testDiagnosticsFor(xml, diagnostic);
}

@Test
public void fuzzyElementNamesWithPrefix() throws Exception {
Expand Down

0 comments on commit f68e014

Please sign in to comment.