This is an automated email from the ASF dual-hosted git repository.
andy pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/jena.git
The following commit(s) were added to refs/heads/main by this push:
new a3f605c194 GH-2619: Fix writing invalid rdf:XMLLiterals
a3f605c194 is described below
commit a3f605c19429ef2ed9f46ddd3b1e6bb942e786b6
Author: Andy Seaborne <[email protected]>
AuthorDate: Tue Aug 6 15:57:23 2024 +0100
GH-2619: Fix writing invalid rdf:XMLLiterals
---
.../org/apache/jena/riot/writer/TS_RiotWriter.java | 5 +-
.../apache/jena/riot/writer/TestWriterRDFXML.java | 70 ++++++++++++++++++++++
...rties.java => TestWriterRDFXML_Properties.java} | 2 +-
.../jena/rdfxml/xmloutput/impl/Unparser.java | 6 +-
4 files changed, 79 insertions(+), 4 deletions(-)
diff --git
a/jena-arq/src/test/java/org/apache/jena/riot/writer/TS_RiotWriter.java
b/jena-arq/src/test/java/org/apache/jena/riot/writer/TS_RiotWriter.java
index 7cab9dc100..a65492e2d8 100644
--- a/jena-arq/src/test/java/org/apache/jena/riot/writer/TS_RiotWriter.java
+++ b/jena-arq/src/test/java/org/apache/jena/riot/writer/TS_RiotWriter.java
@@ -24,14 +24,15 @@ import org.junit.runners.Suite.SuiteClasses ;
@RunWith(Suite.class)
@SuiteClasses(
-{
+{
TestWriterRegistration.class
, TestRiotWriterGraph.class
, TestRiotWriterDataset.class
, TestRDFJSON.class
, TestTurtleWriter.class
, TestTriXWriter.class
- , TestRDFXML_WriterProperties.class
+ , TestWriterRDFXML.class
+ , TestWriterRDFXML_Properties.class
})
public class TS_RiotWriter
diff --git
a/jena-arq/src/test/java/org/apache/jena/riot/writer/TestWriterRDFXML.java
b/jena-arq/src/test/java/org/apache/jena/riot/writer/TestWriterRDFXML.java
new file mode 100644
index 0000000000..d416562ef6
--- /dev/null
+++ b/jena-arq/src/test/java/org/apache/jena/riot/writer/TestWriterRDFXML.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS"
BASIS,rdf:parseType="Literal"
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.riot.writer;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.apache.jena.atlas.logging.LogCtl;
+import org.apache.jena.graph.Graph;
+import org.apache.jena.rdf.model.ModelFactory;
+import org.apache.jena.riot.*;
+import org.apache.jena.vocabulary.RDF;
+import org.apache.jena.vocabulary.RDFS;
+import org.junit.Test;
+
+/**
+ * Additional tests for RDF/XML writing.
+ */
+public class TestWriterRDFXML {
+ @Test public void testRDFXMLLIterals_1() {
+ // Valid RDF XMLLiteral.
+ testXMLLiteral("<ns:text xmlns:ns='http://example/ns#'>ABC</ns:text>",
true);
+ }
+
+ @Test public void testRDFXMLLIterals_2() {
+ // Valid RDF XMLLiteral. Document fragment.
+ testXMLLiteral("<ns:text
xmlns:ns='http://example/ns#'>ABC</ns:text><content>XYZ</content>", true);
+ }
+
+ @Test public void testRDFXMLLIterals_bad_1() {
+ // Invalid RDF XMLLiteral. Not self contained XML - no namespaces
+ testXMLLiteral("<ns:text>ABC</ns:text>", false);
+ }
+
+ @Test public void testRDFXMLLIterals_bad_2() {
+ // Invalid RDF XMLLiteral. Not valid XML - no namespaces
+ testXMLLiteral("<ns:text>ABC", false);
+ }
+
+ private static void testXMLLiteral(String lex, boolean expectValid) {
+ var m = ModelFactory.createDefaultModel();//createOntologyModel();
+ m.createResource().addProperty(RDFS.comment, m.createTypedLiteral(lex,
RDF.dtXMLLiteral));
+ String s =
RDFWriter.source(m).format(RDFFormat.RDFXML_ABBREV).toString();
+
+ // Valid RDF XML Literal - write as rdf:parseType Literal
+ // Invalid RDF XML Literal - write as rdf:datatype
+
+ assertEquals(expectValid, s.contains("rdf:parseType=\"Literal\""));
+ assertEquals(expectValid, ! s.contains("rdf:datatype="));
+
+ LogCtl.withLevel(SysRIOT.getLogger(), "ERROR", ()->{
+ Graph g = RDFParser.fromString(s, Lang.RDFXML).toGraph();
+ });
+ }
+}
diff --git
a/jena-arq/src/test/java/org/apache/jena/riot/writer/TestRDFXML_WriterProperties.java
b/jena-arq/src/test/java/org/apache/jena/riot/writer/TestWriterRDFXML_Properties.java
similarity index 98%
rename from
jena-arq/src/test/java/org/apache/jena/riot/writer/TestRDFXML_WriterProperties.java
rename to
jena-arq/src/test/java/org/apache/jena/riot/writer/TestWriterRDFXML_Properties.java
index b9ce3c336a..124487f28a 100644
---
a/jena-arq/src/test/java/org/apache/jena/riot/writer/TestRDFXML_WriterProperties.java
+++
b/jena-arq/src/test/java/org/apache/jena/riot/writer/TestWriterRDFXML_Properties.java
@@ -31,7 +31,7 @@ import org.junit.Assert ;
import org.junit.Test ;
/** Tests of the RDF/XML writers used via RIOT */
-public class TestRDFXML_WriterProperties {
+public class TestWriterRDFXML_Properties {
static Model model = ModelFactory.createDefaultModel() ;
static {
diff --git
a/jena-core/src/main/java/org/apache/jena/rdfxml/xmloutput/impl/Unparser.java
b/jena-core/src/main/java/org/apache/jena/rdfxml/xmloutput/impl/Unparser.java
index db7e80fca1..cd0dc4954c 100644
---
a/jena-core/src/main/java/org/apache/jena/rdfxml/xmloutput/impl/Unparser.java
+++
b/jena-core/src/main/java/org/apache/jena/rdfxml/xmloutput/impl/Unparser.java
@@ -428,13 +428,17 @@ class Unparser {
* propName '>'
*/
private boolean wPropertyEltLiteral(WType wt, Property prop, Statement
statement, RDFNode rdfNode) {
+ // Is the rule blocked?
if (prettyWriter.sParseTypeLiteralPropertyElt)
return false;
if ( ! (rdfNode instanceof Literal lit) )
return false;
-
if (! XMLLiteralType.isXMLLiteral(lit.getDatatype()) )
return false;
+ // Must be a legal XML fragment.
+ // It must be valid XML and also self-contained XML content (e.g.
includes namespaces - they are not inherited from the model).
+ if ( ! lit.asNode().getLiteral().isWellFormed() )
+ return false;
// print out.
done(statement);