Enforce statement format validity 51/49451/19
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 31 Aug 2017 21:05:06 +0000 (23:05 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Wed, 11 Oct 2017 11:49:07 +0000 (13:49 +0200)
Statements with multiple colons and with the colon being the last
character are invalid. Report these as soon as we encounter them.

Change-Id: I9138e513d1bd271fbdb33bb5991e59f4498410ac
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
Signed-off-by: Peter Kajsa <pkajsa@cisco.com>
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangStatementParserListenerImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/rfc6020/repo/YangStatementStreamSource.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/rfc6020/repo/YinStatementStreamSource.java
yang/yang-parser-impl/src/test/resources/yang-grammar-test/stmtsep-in-statements-sub.yang
yang/yang-parser-impl/src/test/resources/yang-grammar-test/stmtsep-in-statements.yang
yang/yang-parser-impl/src/test/resources/yang-grammar-test/stmtsep-in-statements2.yang
yang/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/StatementStreamSource.java

index 5ae78c4e4181bac14b368278c30119b42f584b4d..cc67bf2acf95661b020d1f0669d9a220318a8883 100644 (file)
@@ -83,7 +83,7 @@ public class YangStatementParserListenerImpl extends YangStatementParserBaseList
         final StatementSourceReference ref = DeclarationInTextSource.atPosition(sourceName, ctx.getStart().getLine(),
                 ctx.getStart().getCharPositionInLine());
         final String keywordTxt = Verify.verifyNotNull(ctx.getChild(KeywordContext.class, 0)).getText();
-        final QName validStatementDefinition = getValidStatementDefinition(prefixes, stmtDef, keywordTxt);
+        final QName validStatementDefinition = getValidStatementDefinition(prefixes, stmtDef, keywordTxt, ref);
 
         final int childId = counters.peek().getAndIncrement();
         counters.push(new Counter());
@@ -107,7 +107,7 @@ public class YangStatementParserListenerImpl extends YangStatementParserBaseList
 
         final KeywordContext keyword = ctx.getChild(KeywordContext.class, 0);
         final String statementName = keyword.getText();
-        if (stmtDef != null && getValidStatementDefinition(prefixes, stmtDef, statementName) != null
+        if (stmtDef != null && getValidStatementDefinition(prefixes, stmtDef, statementName, ref) != null
                 && toBeSkipped.isEmpty()) {
             writer.endStatement(ref);
         }
@@ -125,10 +125,11 @@ public class YangStatementParserListenerImpl extends YangStatementParserBaseList
      * @param prefixes collection of all relevant prefix mappings supplied for actual parsing phase
      * @param stmtDef collection of all relevant statement definition mappings provided for actual parsing phase
      * @param keywordText statement keyword text to parse from source
+     * @param ref Source reference
      * @return valid QName for declared statement to be written, or null
      */
     private static QName getValidStatementDefinition(final PrefixToModule prefixes,
-            final QNameToStatementDefinition stmtDef, final String keywordText) {
+            final QNameToStatementDefinition stmtDef, final String keywordText, final StatementSourceReference ref) {
         final int firstColon = keywordText.indexOf(':');
         if (firstColon == -1) {
             final StatementDefinition statementDefinition = stmtDef.get(
@@ -136,11 +137,9 @@ public class YangStatementParserListenerImpl extends YangStatementParserBaseList
             return statementDefinition != null ? statementDefinition.getStatementName() : null;
         }
 
-        final int secondColon = keywordText.indexOf(':', firstColon + 1);
-        if (secondColon != -1) {
-            // Malformed string
-            return null;
-        }
+        SourceException.throwIf(firstColon == keywordText.length() - 1
+                || keywordText.indexOf(':', firstColon + 1) != -1, ref, "Malformed statement '%s'", keywordText);
+
         if (prefixes == null) {
             // No prefixes to look up from
             return null;
index 77f489675a817cc20de57e56814a92725263ba9b..15a7aa9440285cd8e960441e812a9189a20ac16e 100644 (file)
@@ -23,7 +23,6 @@ import org.antlr.v4.runtime.tree.TerminalNode;
 import org.opendaylight.yangtools.antlrv4.code.gen.YangStatementLexer;
 import org.opendaylight.yangtools.antlrv4.code.gen.YangStatementParser;
 import org.opendaylight.yangtools.antlrv4.code.gen.YangStatementParser.StatementContext;
-import org.opendaylight.yangtools.concepts.Identifiable;
 import org.opendaylight.yangtools.yang.common.YangVersion;
 import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
 import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
@@ -41,7 +40,7 @@ import org.opendaylight.yangtools.yang.parser.spi.source.StatementWriter;
  * @author Robert Varga
  */
 @Beta
-public final class YangStatementStreamSource implements Identifiable<SourceIdentifier>, StatementStreamSource {
+public final class YangStatementStreamSource implements StatementStreamSource {
     private static final ParseTreeListener MAKE_IMMUTABLE_LISTENER = new ParseTreeListener() {
         @Override
         public void enterEveryRule(final ParserRuleContext ctx) {
index a60caf05c9478f6204bfddd913beba7900fdced2..0cc8cc57c82ef84abf3a47cb2ef2621ba83ec533 100644 (file)
@@ -19,7 +19,6 @@ import java.net.URI;
 import java.net.URISyntaxException;
 import javax.annotation.Nonnull;
 import javax.xml.transform.TransformerException;
-import org.opendaylight.yangtools.concepts.Identifiable;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
@@ -47,7 +46,7 @@ import org.w3c.dom.NodeList;
  * @author Robert Varga
  */
 @Beta
-public final class YinStatementStreamSource implements Identifiable<SourceIdentifier>, StatementStreamSource {
+public final class YinStatementStreamSource implements StatementStreamSource {
     private static final Logger LOG = LoggerFactory.getLogger(YinStatementStreamSource.class);
     private static final LoadingCache<String, URI> URI_CACHE = CacheBuilder.newBuilder().weakValues().build(
         new CacheLoader<String, URI>() {
index 5a89db54fdf0def87d59dbeb5b0374d332d01123..434a5ce40895a1db90c6bf273457560f7ae3202b 100644 (file)
@@ -5,7 +5,7 @@ submodule subtest {
        }
     }
 
-    yang-version: 1;
+    yang-version 1;
 
     belongs-to test {
         aaa {
index a8ff5cfec54f70a8070fbd80a8659a3b9e0e14e9..b9e94ed51a7d8b097347275f6ee2faccd54e3ddd 100644 (file)
@@ -5,7 +5,7 @@ module test {
         }
     }
 
-    yang-version: 1;
+    yang-version 1;
     namespace "tst";
     prefix test;
 
index 32edea6e2fd3e697b756f8e898fcf615f2543ece..aa50e4f63f3bbb5641987aac1015eff784a854dc 100644 (file)
@@ -5,7 +5,7 @@ module test2 {
         }
     }
 
-    yang-version: 1;
+    yang-version 1;
     namespace "tst2";
     prefix test2;
 
index 11aa6b9e08241fe67fa4173979cc9c225a25eb47..8b67a03180031764c918d59050d7fac554ba2b3c 100644 (file)
@@ -7,7 +7,9 @@
  */
 package org.opendaylight.yangtools.yang.parser.spi.source;
 
+import org.opendaylight.yangtools.concepts.Identifiable;
 import org.opendaylight.yangtools.yang.common.YangVersion;
+import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
 
 /**
  * Statement stream source, which is used for inference of effective model.
@@ -49,7 +51,7 @@ import org.opendaylight.yangtools.yang.common.YangVersion;
  * build full declared statement model of source.</li>
  * </ol>
  */
-public interface StatementStreamSource {
+public interface StatementStreamSource extends Identifiable<SourceIdentifier> {
 
     /**
      * Emits only pre-linkage-related statements to supplied {@code writer}.