From: Samuel Kontris Date: Thu, 25 Feb 2021 18:09:20 +0000 (+0100) Subject: Restore unrecognized statement defensiveness X-Git-Tag: v6.0.6~9 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=yangtools.git;a=commitdiff_plain;h=99d0a43d0f67ab0b98d56ac4a5b51cb7b1f76e80 Restore unrecognized statement defensiveness We are in a bad place here, as we are trying to come up with something that passes for a QName based on zero understanding of argument structure. Previous cleanup of the logic here, done in YANGTOOLS-1191 omitted a possible source of errors -- when the value contains something resembling a qualified node identier to the point of actually resolving to a module -- but the localname part is not actually valid. Fix this by going through UnqualifiedQName.tryCreate(), just as we do in the unqualified case. The test model is a simplified version of tailf yang models (specifically "tailf-ncs-devices@2020-02-04.yang" model), where the argument structure is actually a descendant schema node identifier. JIRA: YANGTOOLS-1261 Change-Id: I885828221382f5689b491f26161b35987dfd4482 Signed-off-by: Samuel Kontris Signed-off-by: Robert Varga --- diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/extension/UnrecognizedEffectiveStatementImpl.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/extension/UnrecognizedEffectiveStatementImpl.java index c34936e64b..15c964557b 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/extension/UnrecognizedEffectiveStatementImpl.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/extension/UnrecognizedEffectiveStatementImpl.java @@ -93,6 +93,7 @@ final class UnrecognizedEffectiveStatementImpl extends UnknownEffectiveStatement final int next = value.indexOf(':', colon + 1); final String localName = next == -1 ? value.substring(colon + 1) : value.substring(colon + 1, next); - return QName.create(qnameModule, localName).intern(); + final UnqualifiedQName qname = UnqualifiedQName.tryCreate(localName); + return qname == null ? null : qname.bindTo(qnameModule).intern(); } } diff --git a/yang/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/YT1261Test.java b/yang/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/YT1261Test.java new file mode 100644 index 0000000000..2e60af9bb9 --- /dev/null +++ b/yang/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/YT1261Test.java @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2021 PANTHEON.tech, 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.stmt; + +import org.junit.Test; + +public class YT1261Test { + @Test + public void testExtensionArgumentInterpretation() throws Exception { + TestUtils.parseYangSource("/bugs/yt1261.yang"); + } +} diff --git a/yang/yang-parser-rfc7950/src/test/resources/bugs/yt1261.yang b/yang/yang-parser-rfc7950/src/test/resources/bugs/yt1261.yang new file mode 100644 index 0000000000..95b1d2ebae --- /dev/null +++ b/yang/yang-parser-rfc7950/src/test/resources/bugs/yt1261.yang @@ -0,0 +1,60 @@ +module foo { + namespace "foo"; + prefix "foo"; + + extension dependency { + argument path { + foo:arg-type { + type string; + } + } + } + + extension arg-type { + foo:use-in "argument"; + foo:substatement "type"; + } + + extension use-in { + argument name { + foo:arg-type { + type string; + } + } + foo:use-in "extension"; + } + + extension substatement { + argument name { + foo:arg-type { + type string; + } + } + foo:use-in "extension"; + } + + container root-container { + container container-with-must-with-prefix { + must "./foo/bar = 'something'" { + foo:dependency "foo:foo/bar"; + } + leaf leaf1 { + type string; + } + } + container container-with-must-without-prefix { + must "./foo/bar = 'something'" { + foo:dependency "foo/bar"; + } + leaf leaf2 { + type string; + } + } + + container foo { + leaf bar { + type string; + } + } + } +}