Bug 8803: check for null return NamespaceContext.getNamespaceURI() 67/60767/2
authorIgor Foltin <igor.foltin@pantheon.tech>
Wed, 26 Jul 2017 11:14:06 +0000 (13:14 +0200)
committerIgor Foltin <igor.foltin@pantheon.tech>
Wed, 26 Jul 2017 11:14:06 +0000 (13:14 +0200)
The javadoc indicates that for unbound prefixes this method should be
returning NULL_NS_URI (which is defined as an empty string), and there
is no mention of the possibility of returning null anywhere.

Nevertheless JDK8-default XMLOutputWriter returns null for unbound
prefixes, which leads to an infinite loop in RandomPrefix.

Fix this by adding an explicit check for null, too.

Change-Id: Ib8af7d03eb59b004f2fcb4d1806c0f4f256a974a
Signed-off-by: Igor Foltin <igor.foltin@pantheon.tech>
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit 9946267ef128228dad7d6cc9dd5319bfad081756)
Signed-off-by: Igor Foltin <igor.foltin@pantheon.tech>
yang/yang-data-codec-xml/src/main/java/org/opendaylight/yangtools/yang/data/codec/xml/RandomPrefix.java
yang/yang-data-codec-xml/src/test/java/org/opendaylight/yangtools/yang/data/codec/xml/Bug8803Test.java [new file with mode: 0644]
yang/yang-data-codec-xml/src/test/resources/bug8803/bar.yang [new file with mode: 0644]
yang/yang-data-codec-xml/src/test/resources/bug8803/baz.yang [new file with mode: 0644]
yang/yang-data-codec-xml/src/test/resources/bug8803/foo.xml [new file with mode: 0644]
yang/yang-data-codec-xml/src/test/resources/bug8803/foo.yang [new file with mode: 0644]

index 80505dd54659180a6d3c4d9d8b792e78a4ba85a4..facd582c570b94d39729cf63fd4d06624a9d614a 100644 (file)
@@ -60,8 +60,10 @@ class RandomPrefix {
             return false;
         }
 
+        // It seems JDK8 is violating the API contract of NamespaceContext by returning null for unbound prefixes,
+        // rather than specified NULL_NS_URI. Work this around by checking explicitly for null.
         final String str = context.getNamespaceURI(prefix);
-        return !XMLConstants.NULL_NS_URI.equals(str);
+        return str != null && !XMLConstants.NULL_NS_URI.equals(str);
     }
 
     @VisibleForTesting
diff --git a/yang/yang-data-codec-xml/src/test/java/org/opendaylight/yangtools/yang/data/codec/xml/Bug8803Test.java b/yang/yang-data-codec-xml/src/test/java/org/opendaylight/yangtools/yang/data/codec/xml/Bug8803Test.java
new file mode 100644 (file)
index 0000000..723e910
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.codec.xml;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.InputStream;
+import java.io.StringWriter;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
+
+public class Bug8803Test {
+
+    @Test
+    public void test() throws Exception {
+        final SchemaContext schemaContext = YangParserTestUtils.parseYangSources("/bug8803");
+        final InputStream resourceAsStream = Bug8803Test.class.getResourceAsStream("/bug8803/foo.xml");
+
+        // deserialization
+        final XMLInputFactory inputFactory = XMLInputFactory.newFactory();
+        final XMLStreamReader reader = inputFactory.createXMLStreamReader(resourceAsStream);
+
+        final NormalizedNodeResult result = new NormalizedNodeResult();
+        final NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
+        final XmlParserStream xmlParser = XmlParserStream.create(streamWriter, schemaContext, schemaContext);
+        xmlParser.parse(reader);
+        final NormalizedNode<?, ?> transformedInput = result.getResult();
+        assertNotNull(transformedInput);
+
+        // serialization
+        final StringWriter writer = new StringWriter();
+        final XMLOutputFactory outputFactory = XMLOutputFactory.newFactory();
+        // switching NS repairing to false does not help
+        outputFactory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, Boolean.TRUE);
+        final XMLStreamWriter xmlStreamWriter = outputFactory.createXMLStreamWriter(writer);
+
+        final NormalizedNodeStreamWriter xmlNormalizedNodeStreamWriter = XMLStreamNormalizedNodeStreamWriter.create(
+                xmlStreamWriter, schemaContext);
+
+        final NormalizedNodeWriter normalizedNodeWriter = NormalizedNodeWriter.forStreamWriter(
+                xmlNormalizedNodeStreamWriter);
+        normalizedNodeWriter.write(transformedInput);
+
+        final String serializedXml = writer.toString();
+        assertFalse(serializedXml.isEmpty());
+    }
+}
diff --git a/yang/yang-data-codec-xml/src/test/resources/bug8803/bar.yang b/yang/yang-data-codec-xml/src/test/resources/bug8803/bar.yang
new file mode 100644 (file)
index 0000000..64adc82
--- /dev/null
@@ -0,0 +1,14 @@
+module bar {
+    namespace bar-ns;
+    prefix bar;
+
+    import foo {
+        prefix foo;
+    }
+
+    augment "/foo:top-cont/foo:keyed-list" {
+        leaf iid-leaf {
+            type instance-identifier;
+        }
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-data-codec-xml/src/test/resources/bug8803/baz.yang b/yang/yang-data-codec-xml/src/test/resources/bug8803/baz.yang
new file mode 100644 (file)
index 0000000..abe4a57
--- /dev/null
@@ -0,0 +1,14 @@
+module baz {
+    namespace baz-ns;
+    prefix baz;
+
+    container top-cont {
+        list keyed-list {
+            key key-leaf;
+
+            leaf key-leaf {
+                type int32;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-data-codec-xml/src/test/resources/bug8803/foo.xml b/yang/yang-data-codec-xml/src/test/resources/bug8803/foo.xml
new file mode 100644 (file)
index 0000000..e8f8609
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<root>
+    <top-cont xmlns="foo-ns">
+        <keyed-list>
+            <key-leaf>150</key-leaf>
+            <iid-leaf xmlns="bar-ns" xmlns:baz="baz-ns">
+                /baz:top-cont/baz:keyed-list[baz:key-leaf='50']</iid-leaf>
+        </keyed-list>
+    </top-cont>
+</root>
\ No newline at end of file
diff --git a/yang/yang-data-codec-xml/src/test/resources/bug8803/foo.yang b/yang/yang-data-codec-xml/src/test/resources/bug8803/foo.yang
new file mode 100644 (file)
index 0000000..7c8bae4
--- /dev/null
@@ -0,0 +1,14 @@
+module foo {
+    namespace foo-ns;
+    prefix foo;
+
+    container top-cont {
+        list keyed-list {
+            key key-leaf;
+
+            leaf key-leaf {
+                type int32;
+            }
+        }
+    }
+}
\ No newline at end of file