From aeb973897a08d499367bf95d7e7d51e3c38a3d5e Mon Sep 17 00:00:00 2001 From: ignazio Date: Fri, 5 Jun 2015 23:02:00 +0100 Subject: [PATCH] Fix RDF issues testing 4.1.0 RC 1 #412 This commit adds a test for ill formed XML literals, which are expected to fail to serialize. The issue is that ill formed literals would create ontologies that cannot be parsed back. --- .../OWLLiteralCorruptionTestCase.java | 14 +++++++++++ .../rdf/rdfxml/renderer/XMLWriterImpl.java | 24 +++++++++++++++---- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/contract/src/test/java/org/semanticweb/owlapi/api/test/literals/OWLLiteralCorruptionTestCase.java b/contract/src/test/java/org/semanticweb/owlapi/api/test/literals/OWLLiteralCorruptionTestCase.java index 33e4afd856..50e8eee859 100644 --- a/contract/src/test/java/org/semanticweb/owlapi/api/test/literals/OWLLiteralCorruptionTestCase.java +++ b/contract/src/test/java/org/semanticweb/owlapi/api/test/literals/OWLLiteralCorruptionTestCase.java @@ -52,6 +52,20 @@ public void shouldRoundTripXMLLiteral() throws OWLOntologyStorageException { assertTrue(string.contains(literal)); } + @Test + public void shouldFailOnMalformedXMLLiteral() throws OWLOntologyCreationException, OWLOntologyStorageException { + String literal = "A form of cancer that begins in melanocytes (cells that make the pigment melanin). It may begin in a mole (skin melanoma), but can also begin in other pigmented tissues, such as in the eye or in the intestines.NCI-GLOSS"; + OWLOntology o = m.createOntology(); + OWLDataProperty p = df.getOWLDataProperty(IRI.create("urn:test#p")); + OWLLiteral l = df.getOWLLiteral(literal, OWL2Datatype.RDF_XML_LITERAL); + OWLNamedIndividual i = df.getOWLNamedIndividual(IRI.create("urn:test#i")); + o.add( df.getOWLDataPropertyAssertionAxiom(p, i, l)); + expectedException.expect(OWLOntologyStorageException.class); + expectedException.expectMessage(literal); + expectedException.expectMessage("XML literal is not self contained"); + saveOntology(o).toString(); + } + @Test public void shouldRoundtripPaddedLiterals() throws OWLOntologyCreationException, OWLOntologyStorageException { String in = "Prefix(:=)\n" + "Prefix(a:=)\n" diff --git a/parsers/src/main/java/org/semanticweb/owlapi/rdf/rdfxml/renderer/XMLWriterImpl.java b/parsers/src/main/java/org/semanticweb/owlapi/rdf/rdfxml/renderer/XMLWriterImpl.java index f6ac1adc1a..4733d933d5 100644 --- a/parsers/src/main/java/org/semanticweb/owlapi/rdf/rdfxml/renderer/XMLWriterImpl.java +++ b/parsers/src/main/java/org/semanticweb/owlapi/rdf/rdfxml/renderer/XMLWriterImpl.java @@ -14,7 +14,9 @@ import static org.semanticweb.owlapi.util.OWLAPIPreconditions.*; +import java.io.IOException; import java.io.PrintWriter; +import java.io.StringReader; import java.util.*; import javax.annotation.Nonnull; @@ -23,7 +25,11 @@ import org.semanticweb.owlapi.io.XMLUtils; import org.semanticweb.owlapi.model.IRI; import org.semanticweb.owlapi.model.OWLRuntimeException; +import org.semanticweb.owlapi.util.SAXParsers; import org.semanticweb.owlapi.util.StringLengthComparator; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; import com.google.common.base.Splitter; import com.google.common.collect.Lists; @@ -59,10 +65,10 @@ public class XMLWriterImpl implements XMLWriter { * xml writer preferences instance */ public XMLWriterImpl(PrintWriter writer, XMLWriterNamespaceManager xmlWriterNamespaceManager, String xmlBase, - XMLWriterPreferences preferences) { + XMLWriterPreferences preferences) { this.writer = checkNotNull(writer, "writer cannot be null"); this.xmlWriterNamespaceManager = checkNotNull(xmlWriterNamespaceManager, - "xmlWriterNamespaceManager cannot be null"); + "xmlWriterNamespaceManager cannot be null"); this.xmlBase = checkNotNull(xmlBase, "xmlBase cannot be null"); xmlPreferences = checkNotNull(preferences, "preferences cannot be null"); elementStack = new Stack<>(); @@ -237,8 +243,8 @@ public void startDocument(IRI rootElement) { } for (String curPrefix : xmlWriterNamespaceManager.getPrefixes()) { if (!curPrefix.isEmpty()) { - writeAttribute("xmlns:" + curPrefix, - verifyNotNull(xmlWriterNamespaceManager.getNamespaceForPrefix(curPrefix))); + writeAttribute("xmlns:" + curPrefix, verifyNotNull(xmlWriterNamespaceManager.getNamespaceForPrefix( + curPrefix))); } } } @@ -404,6 +410,7 @@ private void writeTextContent() { if (textContent != null) { // only escape the data if this is not an XML literal if ("http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral".equals(attributes.get("rdf:datatype"))) { + checkProperXMLLiteral(textContent); writer.write(textContent); } else { writer.write(XMLUtils.escapeXML(verifyNotNull(textContent))); @@ -411,6 +418,15 @@ private void writeTextContent() { } } + private void checkProperXMLLiteral(String text) { + try { + SAXParsers.initParserWithOWLAPIStandards(null).parse(new InputSource(new StringReader(text)), + new DefaultHandler()); + } catch (SAXException | IOException e) { + throw new OWLRuntimeException("XML literal is not self contained: \"" + text + "\"", e); + } + } + private void insertIndentation() { if (xmlPreferences.isIndenting()) { for (int i = 0; i < indentation * xmlPreferences.getIndentSize(); i++) {