From c53dce13e4d9de6df1a465c86d8e8574e7636614 Mon Sep 17 00:00:00 2001 From: Igor Foltin Date: Wed, 26 Jul 2017 13:14:06 +0200 Subject: [PATCH] Bug 8803: check for null return NamespaceContext.getNamespaceURI() 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 Signed-off-by: Robert Varga (cherry picked from commit 9946267ef128228dad7d6cc9dd5319bfad081756) Signed-off-by: Igor Foltin --- .../yang/data/codec/xml/RandomPrefix.java | 4 +- .../yang/data/codec/xml/Bug8803Test.java | 63 +++++++++++++++++++ .../src/test/resources/bug8803/bar.yang | 14 +++++ .../src/test/resources/bug8803/baz.yang | 14 +++++ .../src/test/resources/bug8803/foo.xml | 11 ++++ .../src/test/resources/bug8803/foo.yang | 14 +++++ 6 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 yang/yang-data-codec-xml/src/test/java/org/opendaylight/yangtools/yang/data/codec/xml/Bug8803Test.java create mode 100644 yang/yang-data-codec-xml/src/test/resources/bug8803/bar.yang create mode 100644 yang/yang-data-codec-xml/src/test/resources/bug8803/baz.yang create mode 100644 yang/yang-data-codec-xml/src/test/resources/bug8803/foo.xml create mode 100644 yang/yang-data-codec-xml/src/test/resources/bug8803/foo.yang diff --git a/yang/yang-data-codec-xml/src/main/java/org/opendaylight/yangtools/yang/data/codec/xml/RandomPrefix.java b/yang/yang-data-codec-xml/src/main/java/org/opendaylight/yangtools/yang/data/codec/xml/RandomPrefix.java index 80505dd546..facd582c57 100644 --- a/yang/yang-data-codec-xml/src/main/java/org/opendaylight/yangtools/yang/data/codec/xml/RandomPrefix.java +++ b/yang/yang-data-codec-xml/src/main/java/org/opendaylight/yangtools/yang/data/codec/xml/RandomPrefix.java @@ -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 index 0000000000..723e9108e4 --- /dev/null +++ b/yang/yang-data-codec-xml/src/test/java/org/opendaylight/yangtools/yang/data/codec/xml/Bug8803Test.java @@ -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 index 0000000000..64adc823cc --- /dev/null +++ b/yang/yang-data-codec-xml/src/test/resources/bug8803/bar.yang @@ -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 index 0000000000..abe4a57dc9 --- /dev/null +++ b/yang/yang-data-codec-xml/src/test/resources/bug8803/baz.yang @@ -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 index 0000000000..e8f8609635 --- /dev/null +++ b/yang/yang-data-codec-xml/src/test/resources/bug8803/foo.xml @@ -0,0 +1,11 @@ + + + + + + 150 + + /baz:top-cont/baz:keyed-list[baz:key-leaf='50'] + + + \ 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 index 0000000000..7c8bae425a --- /dev/null +++ b/yang/yang-data-codec-xml/src/test/resources/bug8803/foo.yang @@ -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 -- 2.36.6