Restore unrecognized statement defensiveness 99/94999/3
authorSamuel Kontris <samuel.kontris@pantheon.tech>
Thu, 25 Feb 2021 18:09:20 +0000 (19:09 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Fri, 26 Feb 2021 14:36:36 +0000 (15:36 +0100)
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 <samuel.kontris@pantheon.tech>
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/extension/UnrecognizedEffectiveStatementImpl.java
yang/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/YT1261Test.java [new file with mode: 0644]
yang/yang-parser-rfc7950/src/test/resources/bugs/yt1261.yang [new file with mode: 0644]

index c34936e64b40ee1452c4b5a477d61998e77b2bbe..15c964557b117a3a6f44578396a94e32950d1317 100644 (file)
@@ -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 (file)
index 0000000..2e60af9
--- /dev/null
@@ -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 (file)
index 0000000..95b1d2e
--- /dev/null
@@ -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;
+      }
+    }
+  }
+}