Skip to content

Commit

Permalink
Do not complete paths in attr unless beginning of value looks like a
Browse files Browse the repository at this point in the history
path

Fixes redhat-developer/vscode-xml#668

Signed-off-by: David Thompson <[email protected]>
  • Loading branch information
datho7561 committed Sep 15, 2022
1 parent de9c702 commit e85f353
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,17 +89,19 @@ public void onDTDSystemId(String value, ICompletionRequest request, ICompletionR

private static void addCompletionItems(String value, ICompletionRequest request, ICompletionResponse response)
throws Exception {
String fullValue = value;
if (isEmpty(fullValue)) {
return;
}

DOMDocument xmlDocument = request.getXMLDocument();
String text = xmlDocument.getText();

// Get value and range for file path declared inside the attribute value
// ex value="file:///C:/fold|er"
int valuePathStartOffset = xmlDocument.offsetAt(request.getReplaceRange().getStart());

String fullValue = value;
boolean inDoctype = isInDoctype(valuePathStartOffset, xmlDocument);
if (isEmpty(fullValue) && !inDoctype) {
return;
}

int endPathOffset = request.getOffset(); // offset after the typed character
int startPathOffset = StringUtils.getOffsetAfterWhitespace(fullValue, endPathOffset - valuePathStartOffset)
+ valuePathStartOffset; // first character of URI
Expand Down Expand Up @@ -132,6 +134,9 @@ private static void addCompletionItems(String value, ICompletionRequest request,
return;
}
}
} else if (!hasPathBeginning(valuePath) && !inDoctype) {
// the user probably didn't intend to complete a path
return;
}
// On Linux, Mac OS replace '\\' with '/'
if (!isWindows) {
Expand Down Expand Up @@ -259,4 +264,33 @@ private static void createFilePathCompletionItem(File f, Range replaceRange, ICo
response.addCompletionItem(item);
}

private static boolean hasPathBeginning(String currentText) {
if (currentText.startsWith("/")
|| currentText.startsWith("./")
|| currentText.startsWith("../")
|| currentText.startsWith("..\\")
|| currentText.startsWith(".\\")) {
return true;
}
return isAbsoluteWindowsPath(currentText);
}

private static boolean isAbsoluteWindowsPath(String currentText) {
if (currentText.length() < 3) {
return false;
}
char driveLetter = currentText.charAt(0);
if (driveLetter < 'A' || (driveLetter > 'Z' && driveLetter < 'a') || (driveLetter) > 'z') {
return false;
}
return currentText.charAt(1) == ':' && currentText.charAt(2) == '\\';
}

private static boolean isInDoctype(int offset, DOMDocument xmlDocument) {
if (xmlDocument.getDoctype() == null) {
return false;
}
return xmlDocument.getDoctype().getStart() <= offset && offset <= xmlDocument.getDoctype().getEnd();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ public abstract class AbstractCacheBasedTest {

@BeforeEach
public final void setupCache() throws Exception {
System.out.println(this.getClass().getName() + ": " + uuid);
clearCache();
FilesUtils.resetDeployPath();
Assertions.assertNotNull(parentDir);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,13 @@ public void testFilePathCompletionFolderABackSlash() throws BadLocationException
@Test
public void testFilePathCompletionFolderB() throws BadLocationException {
String xml = "<a path=\"folderB/|\">";
CompletionItem[] items = getCompletionItemList("/", 0, 16, 17, "xsdB1.xsd", "xmlB1.xml");
testCompletionFor(xml, 2, items);
testCompletionFor(xml, 0);
}

@Test
public void testFilePathCompletionFolderBBackSlash() throws BadLocationException {
String xml = "<a path=\"folderB\\|\">";
CompletionItem[] items = getCompletionItemList("\\", 0, 16, 17, "xsdB1.xsd", "xmlB1.xml");
testCompletionFor(xml, 2, items);
testCompletionFor(xml, 0);
}

@Test
Expand Down Expand Up @@ -113,44 +111,42 @@ public void testFilePathCompletionFolderBAbsolutePathWithFileScheme() throws Bad

@Test
public void testFilePathCompletionNestedA() throws BadLocationException {
String xml = "<a path=\"NestedA/|\">";
CompletionItem[] items = getCompletionItemList("/", 0, 16, 17, "NestedB");
String xml = "<a path=\"./NestedA/|\">";
CompletionItem[] items = getCompletionItemList("/", 0, 18, 19, "NestedB");
testCompletionFor(xml, 1, items);
}

@Test
public void testFilePathCompletionNestedABackSlash() throws BadLocationException {
String xml = "<a path=\"NestedA\\|\">";
CompletionItem[] items = getCompletionItemList("\\", 0, 16, 17, "NestedB");
String xml = "<a path=\"./NestedA\\|\">";
CompletionItem[] items = getCompletionItemList("\\", 0, 18, 19, "NestedB");
testCompletionFor(xml, 1, items);
}

@Test
public void testFilePathCompletionNestedBIncomplete() throws BadLocationException {
String xml = "<a path=\"NestedA/NestedB/ZZZ|\">";
CompletionItem[] items = getCompletionItemList("/", 0, 24, 28, "nestedXSD.xsd");
String xml = "<a path=\"./NestedA/NestedB/ZZZ|\">";
CompletionItem[] items = getCompletionItemList("/", 0, 26, 30, "nestedXSD.xsd");
testCompletionFor(xml, 1, items);
}

@Test
public void testFilePathCompletionNestedBIncompleteBackSlash() throws BadLocationException {
String xml = "<a path=\"NestedA\\NestedB\\ZZZ|\">";
CompletionItem[] items = getCompletionItemList("\\", 0, 24, 28, "nestedXSD.xsd");
String xml = "<a path=\".\\NestedA\\NestedB\\ZZZ|\">";
CompletionItem[] items = getCompletionItemList("\\", 0, 26, 30, "nestedXSD.xsd");
testCompletionFor(xml, 1, items);
}

@Test
public void testFilePathCompletionExtraTextInValue() throws BadLocationException {
String xml = "<a path=\"NAMESPACE_IGNORE_ME NestedA/NestedB/|\">";
CompletionItem[] items = getCompletionItemList("/", 0, 44, 45, "nestedXSD.xsd");
testCompletionFor(xml, 1, items);
testCompletionFor(xml, 0);
}

@Test
public void testFilePathCompletionExtraTextInValueBackSlash() throws BadLocationException {
String xml = "<a path=\"NAMESPACE_IGNORE_ME NestedA\\NestedB\\|\">";
CompletionItem[] items = getCompletionItemList("\\", 0, 44, 45, "nestedXSD.xsd");
testCompletionFor(xml, 1, items);
testCompletionFor(xml, 0);
}

@Test
Expand All @@ -166,11 +162,8 @@ public void testFilePathCompletionExtraTextInValueAbsolute() throws BadLocationE
@Test
public void testFilePathCompletionExtraTextInValueAbsoluteBackSlash() throws BadLocationException {
String filePath = userDirBackSlash + "\\src\\test\\resources\\filePathCompletion\\NestedA\\NestedB\\";
int filePathLength = filePath.length();
String xml = "<a path=\"NAMESPACE_IGNORE_ME " + filePath + "|\">";
CompletionItem[] items = getCompletionItemList("\\", 0, 29 + filePathLength - 1, 29 + filePathLength,
"nestedXSD.xsd");
testCompletionFor(xml, 1, items);
testCompletionFor(xml, 0);
}

@Test
Expand Down Expand Up @@ -262,22 +255,22 @@ public void testFilePathCompletionDTDFolderABackSlash() throws BadLocationExcept

@Test
public void testFilePathCompletionDTDFolderB() throws BadLocationException {
String xml = "<!DOCTYPE foo SYSTEM \"folderB/|\">";
CompletionItem[] items = getCompletionItemList("/", 0, 29, 30, "xsdB1.xsd", "xmlB1.xml");
String xml = "<!DOCTYPE foo SYSTEM \"./folderB/|\">";
CompletionItem[] items = getCompletionItemList("/", 0, 31, 32, "xsdB1.xsd", "xmlB1.xml");
testCompletionFor(xml, 2, items);
}

@Test
public void testFilePathCompletionDTDFolderBBackSlash() throws BadLocationException {
String xml = "<!DOCTYPE foo SYSTEM \"folderB\\|\">";
CompletionItem[] items = getCompletionItemList("\\", 0, 29, 30, "xsdB1.xsd", "xmlB1.xml");
String xml = "<!DOCTYPE foo SYSTEM \"./folderB\\|\">";
CompletionItem[] items = getCompletionItemList("\\", 0, 31, 32, "xsdB1.xsd", "xmlB1.xml");
testCompletionFor(xml, 2, items);
}

@Test
public void testFilePathNoCompletion() throws BadLocationException {
public void testFilePathCompletionForEmptyDoctype() throws BadLocationException {
String xml = "<!DOCTYPE foo SYSTEM \"|\">";
testCompletionFor(xml, 0);
testCompletionFor(xml, 5);
}

@Test
Expand All @@ -288,8 +281,8 @@ public void testFilePathNoCompletionMissingSystemId() throws BadLocationExceptio

@Test
public void testFilePathCompletionWithSpacesFolder() throws BadLocationException {
String xml = "<a path=\"folderC/|\">";
CompletionItem[] items = getCompletionItemList("/", 0, 16, 17, "a@b", "with%20spaces");
String xml = "<a path=\"./folderC/|\">";
CompletionItem[] items = getCompletionItemList("/", 0, 18, 19, "a@b", "with%20spaces");
testCompletionFor(xml, 2, items);
}

Expand All @@ -301,6 +294,18 @@ public void testFilePathCompletionInsideSpecialChars() throws BadLocationExcepti
XMLAssert.testCompletionFor(xml, null, fileURI, 2, items);
}

@Test
public void testFilePathCompletionWithBrokenAbsoluteWindowsPath() throws BadLocationException {
String xml = "<a path=\"C|\">";
testCompletionFor(xml, 0);
xml = "<a path=\"C:|\">";
testCompletionFor(xml, 0);
xml = "<a path=\"C\\\\|\">";
testCompletionFor(xml, 0);
xml = "<a path=\"C::|\">";
testCompletionFor(xml, 0);
}

private static void testCompletionFor(String xml, CompletionItem... expectedItems) throws BadLocationException {
testCompletionFor(xml, null, expectedItems);
}
Expand Down

0 comments on commit e85f353

Please sign in to comment.