You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by re...@apache.org on 2020/05/04 12:40:10 UTC
[uima-uimaj] 01/01: [UIMA-6225] Unable to install a pear package
into a directory containing special character like <, > or &
This is an automated email from the ASF dual-hosted git repository.
rec pushed a commit to branch UIMA-6225-PEAR-install-fails-with-XMl-special-chars-in-target-path
in repository https://gitbox.apache.org/repos/asf/uima-uimaj.git
commit f40fd06ecaeeaeac310f712f709238c078878fac
Author: Richard Eckart de Castilho <re...@apache.org>
AuthorDate: Mon May 4 14:39:51 2020 +0200
[UIMA-6225] Unable to install a pear package into a directory containing special character like <,> or &
- Escape XML element values in XMLUtil (which is used to serialize PEAR installation descriptors
- Added unit test trying to install PEAR into a path with an XML special character
- Cleaned up and modernized TestPearInstallationVerification
---
.../java/org/apache/uima/pear/util/XMLUtil.java | 144 ++++++++++++++-------
.../util/TestPearInstallationVerification.java | 131 +++++++------------
2 files changed, 146 insertions(+), 129 deletions(-)
diff --git a/uimaj-core/src/main/java/org/apache/uima/pear/util/XMLUtil.java b/uimaj-core/src/main/java/org/apache/uima/pear/util/XMLUtil.java
index a990ab3..1c02982 100644
--- a/uimaj-core/src/main/java/org/apache/uima/pear/util/XMLUtil.java
+++ b/uimaj-core/src/main/java/org/apache/uima/pear/util/XMLUtil.java
@@ -170,11 +170,13 @@ public class XMLUtil {
do {
nextByte = iStream.read();
// store as possible UTF signature or BOM
- if (byteCounter < 16)
- prefix[byteCounter] = nextByte;
+ if (byteCounter < 16) {
+ prefix[byteCounter] = nextByte;
+ }
byteCounter++;
- if (nextByte < 0)
- throw new IOException("cannot read file");
+ if (nextByte < 0) {
+ throw new IOException("cannot read file");
+ }
} while (nextByte == 0xEF || nextByte == 0xBB || nextByte == 0xBF || nextByte == 0xFE
|| nextByte == 0xFF || nextByte == 0x00);
int prefixLength = byteCounter < 17 ? byteCounter - 1 : 16;
@@ -185,12 +187,15 @@ public class XMLUtil {
boolean utf32Signature = false;
if (utfSignature != null) {
// check signature name
- if (utfSignature.startsWith("UTF-8"))
- utf8Signature = true;
- else if (utfSignature.startsWith("UTF-16"))
- utf16Signature = true;
- else if (utfSignature.startsWith("UTF-32"))
- utf32Signature = true;
+ if (utfSignature.startsWith("UTF-8")) {
+ utf8Signature = true;
+ }
+ else if (utfSignature.startsWith("UTF-16")) {
+ utf16Signature = true;
+ }
+ else if (utfSignature.startsWith("UTF-32")) {
+ utf32Signature = true;
+ }
}
byte[] buffer = null;
int bytes2put = 0;
@@ -199,15 +204,17 @@ public class XMLUtil {
// UTF-16 - put 2 bytes of signature + 7x2 bytes
bytes2put = 7 * 2; // <?xml?>
buffer = new byte[prefixLength + bytes2put];
- for (int i = 0; i < prefixLength; i++)
- buffer[i] = (byte) prefix[i];
+ for (int i = 0; i < prefixLength; i++) {
+ buffer[i] = (byte) prefix[i];
+ }
byteCounter = prefixLength;
} else if (utf32Signature) {
// UTF-32 - put 4 bytes of signature + 7x4 bytes
bytes2put = 7 * 4; // <?xml?>
buffer = new byte[prefixLength + bytes2put];
- for (int i = 0; i < prefixLength; i++)
- buffer[i] = (byte) prefix[i];
+ for (int i = 0; i < prefixLength; i++) {
+ buffer[i] = (byte) prefix[i];
+ }
byteCounter = prefixLength;
} else {
// UTF8 or no signature - put only text characters
@@ -222,12 +229,14 @@ public class XMLUtil {
int offset = 0;
while (offset < (bytes2put - 1)) {
int bytesRead = iStream.read(buffer, offset + byteCounter, bytes2put - 1 - offset);
- if (bytesRead == -1)
- break;
+ if (bytesRead == -1) {
+ break;
+ }
offset += bytesRead;
}
- if (offset != (bytes2put - 1))
+ if (offset != (bytes2put - 1)) {
throw new IOException("cannot read file");
+ }
// check first XML header characters - '<?'
// buffer is 7 bytes
// some Javas won't properly decode an odd number of bytes for utf16 coding
@@ -237,20 +246,23 @@ public class XMLUtil {
if (utf8Signature) {
// check for UTF-8
String test = new String(buffer, "UTF-8");
- if (test.startsWith(FIRST_XML_CHARS))
- encoding = "UTF-8";
+ if (test.startsWith(FIRST_XML_CHARS)) {
+ encoding = "UTF-8";
+ }
} else if (utf16Signature) {
// check for UTF-16
String test = new String(buffer6, "UTF-16");
- if (test.startsWith(FIRST_XML_CHARS))
- encoding = "UTF-16";
+ if (test.startsWith(FIRST_XML_CHARS)) {
+ encoding = "UTF-16";
+ }
} else if (utf32Signature) {
// we don't support this
} else {
// no signature - check for UTF-8 in XML header characters
String test = new String(buffer, "UTF-8");
- if (test.startsWith(FIRST_XML_CHARS))
- encoding = "UTF-8";
+ if (test.startsWith(FIRST_XML_CHARS)) {
+ encoding = "UTF-8";
+ }
else {
// next, check for UTF-16LE in XML header characters
test = new String(buffer6, "UTF-16LE");
@@ -275,8 +287,9 @@ public class XMLUtil {
while ((line = fReader.readLine()) != null) {
String xmlLine = line.trim();
if (xmlLine.length() > 0) {
- if (xmlLine.charAt(0) == '<')
+ if (xmlLine.charAt(0) == '<') {
encoding = "UTF-8";
+ }
break;
}
}
@@ -291,8 +304,9 @@ public class XMLUtil {
while ((line = fReader.readLine()) != null) {
String xmlLine = line.trim();
if (xmlLine.length() > 0) {
- if (xmlLine.charAt(0) == '<')
- encoding = "UTF-16";
+ if (xmlLine.charAt(0) == '<') {
+ encoding = "UTF-16";
+ }
break;
}
}
@@ -306,17 +320,19 @@ public class XMLUtil {
} catch (Throwable err) {
throw new IOException(err.toString());
} finally {
- if (iStream != null)
+ if (iStream != null) {
try {
iStream.close();
} catch (Exception e) {
}
- if (fReader != null)
+ }
+ if (fReader != null) {
try {
fReader.close();
} catch (Exception e) {
}
}
+ }
return encoding;
} // detectXmlFileEncoding()
@@ -343,12 +359,13 @@ public class XMLUtil {
} catch (SAXException err) {
isValid = false;
} finally {
- if (iStream != null)
+ if (iStream != null) {
try {
iStream.close();
} catch (Exception e) {
}
}
+ }
return isValid;
} // isValidXmlFile()
@@ -369,8 +386,9 @@ public class XMLUtil {
String systemId = ex.getSystemId();
if (systemId != null) {
int index = systemId.lastIndexOf('/');
- if (index != -1)
- systemId = systemId.substring(index + 1);
+ if (index != -1) {
+ systemId = systemId.substring(index + 1);
+ }
System.err.print(systemId);
}
System.err.print(':');
@@ -433,8 +451,9 @@ public class XMLUtil {
String eValue = elements.getProperty(tag);
if (eValue != null) {
// print XML element(s)
- if (multiValue)
- printXMLElements(tag, eValue, valueDelimiter, oWriter, level);
+ if (multiValue) {
+ printXMLElements(tag, eValue, valueDelimiter, oWriter, level);
+ }
else {
printXMLElement(tag, eValue, oWriter, level);
// insert new line
@@ -460,9 +479,10 @@ public class XMLUtil {
if (!done) {
// print XML element(s)
String eValue = elements.getProperty(tag);
- if (multiValue)
+ if (multiValue) {
printXMLElements(tag, eValue, valueDelimiter, oWriter, level);
- else {
+ }
+ else {
printXMLElement(tag, eValue, oWriter, level);
// insert new line
oWriter.println();
@@ -725,17 +745,27 @@ public class XMLUtil {
* if any I/O exception occurred.
*/
public static void printXMLElementValue(String elemValue, boolean putInCdataSection,
- PrintWriter oWriter, int level) throws IOException {
+ PrintWriter oWriter, int level)
+ throws IOException
+ {
// add marginal tabs
- for (int l = 0; l < level; l++)
+ for (int l = 0; l < level; l++) {
oWriter.print('\t');
+ }
+
if (elemValue != null) {
// print XML element value
- if (putInCdataSection)
+ if (putInCdataSection) {
oWriter.print(CDATA_SECTION_BEG);
- oWriter.print(elemValue.trim());
- if (putInCdataSection)
+ }
+
+ // Either put the element value into a CDATA section or escape special XML characters properly
+ oWriter.print(putInCdataSection ? elemValue.trim() : xmlEscape(elemValue.trim()));
+
+ if (putInCdataSection) {
oWriter.print(CDATA_SECTION_END);
+ }
+
oWriter.flush();
}
}
@@ -754,8 +784,9 @@ public class XMLUtil {
*/
public static void printXMLHeader(String encoding, PrintWriter oWriter) throws IOException {
oWriter.print(XML_HEADER_BEG);
- if (encoding != null && encoding.length() > 0) // add encoding
- oWriter.print(" " + XML_ENCODING_TAG + "=\"" + encoding + "\"");
+ if (encoding != null && encoding.length() > 0) {
+ oWriter.print(" " + XML_ENCODING_TAG + "=\"" + encoding + "\"");
+ }
oWriter.println(XML_HEADER_END);
}
@@ -801,13 +832,16 @@ public class XMLUtil {
public static void printXMLTag(String tag, Properties attributes, PrintWriter oWriter,
boolean tagEnd, int level) throws IOException {
// add marginal tabs
- for (int l = 0; l < level; l++)
- oWriter.print('\t');
+ for (int l = 0; l < level; l++) {
+ oWriter.print('\t');
+ }
// print XML tag prefix
- if (tagEnd)
- oWriter.print("</");
- else
- oWriter.print('<');
+ if (tagEnd) {
+ oWriter.print("</");
+ }
+ else {
+ oWriter.print('<');
+ }
// print XML tag name
oWriter.print(tag);
if (!tagEnd && attributes != null) {
@@ -828,4 +862,18 @@ public class XMLUtil {
oWriter.print('>');
oWriter.flush();
}
+
+ private static String xmlEscape(String value)
+ {
+ if (value == null) {
+ return value;
+ }
+
+ return value
+ .replace("&", "&")
+ .replace("<", "<")
+ .replace(">", ">")
+ .replace("\"", """)
+ .replace("'", "'");
+ }
}
diff --git a/uimaj-core/src/test/java/org/apache/uima/pear/util/TestPearInstallationVerification.java b/uimaj-core/src/test/java/org/apache/uima/pear/util/TestPearInstallationVerification.java
index 410b834..ad5319a 100644
--- a/uimaj-core/src/test/java/org/apache/uima/pear/util/TestPearInstallationVerification.java
+++ b/uimaj-core/src/test/java/org/apache/uima/pear/util/TestPearInstallationVerification.java
@@ -19,107 +19,76 @@
package org.apache.uima.pear.util;
-import java.io.File;
+import static org.apache.uima.pear.tools.InstallationController.TestStatus.TEST_SUCCESSFUL;
+import static org.apache.uima.test.junit_extension.JUnitExtension.getFile;
+import static org.assertj.core.api.Assertions.assertThat;
-import org.junit.Assert;
-import junit.framework.TestCase;
+import java.io.File;
+import java.io.IOException;
+import org.apache.uima.UIMAException;
+import org.apache.uima.UIMARuntimeException;
import org.apache.uima.pear.tools.InstallationController.TestStatus;
import org.apache.uima.pear.tools.InstallationTester;
import org.apache.uima.pear.tools.PackageBrowser;
import org.apache.uima.pear.tools.PackageInstaller;
-import org.apache.uima.test.junit_extension.JUnitExtension;
+import org.apache.uima.resource.ResourceInitializationException;
+import org.apache.uima.util.InvalidXMLException;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
/**
* Test the pear installation verification
- *
*/
-public class TestPearInstallationVerification extends TestCase {
+public class TestPearInstallationVerification {
// Temporary working directory, used to install the pear package
- private File tempInstallDir = null;
+ public @Rule TemporaryFolder temp = new TemporaryFolder();
+
+ @Test
+ public void testAePearVerification() throws Exception {
+ assertThatPearInstalls(
+ getFile("pearTests/analysisEngine.pear"),
+ temp.newFolder("pear_verification_test_tmp"));
+ }
- /**
- * @see junit.framework.TestCase#setUp()
- */
- protected void setUp() throws Exception {
-
- // create temporary working directory
- File tempFile = File.createTempFile("pear_verification_test_", "tmp");
- if (tempFile.delete()) {
- File tempDir = tempFile;
- if (tempDir.mkdirs())
- this.tempInstallDir = tempDir;
- }
+ @Test
+ public void testCcPearVerification() throws Exception {
+ assertThatPearInstalls(
+ getFile("pearTests/casConsumer.pear"),
+ temp.newFolder("pear_verification_test_tmp"));
}
- /**
- * @see junit.framework.TestCase#tearDown()
- */
- protected void tearDown() throws Exception {
- if (this.tempInstallDir != null) {
- FileUtil.deleteDirectory(this.tempInstallDir);
- }
+ @Test
+ public void testTsPearVerification() throws Exception {
+ assertThatPearInstalls(
+ getFile("pearTests/typeSystem.pear"),
+ temp.newFolder("pear_verification_test_tmp"));
}
-
- public void testAePearVerification() throws Exception {
-
- //get pear file to install
- File pearFile = JUnitExtension.getFile("pearTests/analysisEngine.pear");
- Assert.assertNotNull("analysisEngine.pear file not found", pearFile);
-
- // Install PEAR package without verification
- PackageBrowser instPear = PackageInstaller.installPackage(
- this.tempInstallDir, pearFile, false);
-
- //check package browser
- Assert.assertNotNull("PackageBrowser is null", instPear);
-
- InstallationTester installTester = new InstallationTester(instPear);
- TestStatus status = installTester.doTest();
-
- Assert.assertEquals(status.getRetCode(), TestStatus.TEST_SUCCESSFUL);
+ // TODO: create testcases for ci, cr, cpe pear packages
+
+ @Test
+ public void thatSpecialXmlCharactersInTargetPathDoNotBreakInstallation() throws Exception {
+ assertThatPearInstalls(
+ getFile("pearTests/analysisEngine.pear"),
+ temp.newFolder("<>'\"&"));
}
- public void testCcPearVerification() throws Exception {
-
- //get pear file to install
- File pearFile = JUnitExtension.getFile("pearTests/casConsumer.pear");
- Assert.assertNotNull("casConsumer.pear file not found", pearFile);
-
- // Install PEAR package without verification
- PackageBrowser instPear = PackageInstaller.installPackage(
- this.tempInstallDir, pearFile, false);
-
- //check package browser
- Assert.assertNotNull("PackageBrowser is null", instPear);
-
- InstallationTester installTester = new InstallationTester(instPear);
- TestStatus status = installTester.doTest();
-
- Assert.assertEquals(status.getRetCode(), TestStatus.TEST_SUCCESSFUL);
- }
+ private void assertThatPearInstalls(File pearFile, File targetDir) throws InvalidXMLException,
+ ResourceInitializationException, UIMARuntimeException, UIMAException, IOException {
+ assertThat(pearFile).as("PEAR file %s not found", pearFile).isNotNull();
- public void testTsPearVerification() throws Exception {
-
- //get pear file to install
- File pearFile = JUnitExtension.getFile("pearTests/typeSystem.pear");
- Assert.assertNotNull("typeSystem.pear file not found", pearFile);
-
- // Install PEAR package without verification
- PackageBrowser instPear = PackageInstaller.installPackage(
- this.tempInstallDir, pearFile, false);
-
- //check package browser
- Assert.assertNotNull("PackageBrowser is null", instPear);
-
- InstallationTester installTester = new InstallationTester(instPear);
- TestStatus status = installTester.doTest();
-
- Assert.assertEquals(status.getRetCode(), TestStatus.TEST_SUCCESSFUL);
- }
+ // Install PEAR package without verification
+ PackageBrowser instPear = PackageInstaller.installPackage(targetDir, pearFile, false);
- //TODO: create testcases for ci, cr, cpe pear packages
+ // Check package browser
+ assertThat(instPear).as("PackageBrowser is null").isNotNull();
+ InstallationTester installTester = new InstallationTester(instPear);
+ TestStatus status = installTester.doTest();
+
+ assertThat(status.getRetCode()).isEqualTo(TEST_SUCCESSFUL);
+ }
}