From 8dc8c85e43be7c78a8aa4081d970e924b9757b3f Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Sun, 22 Dec 2019 11:20:29 +0100 Subject: [PATCH] Force path expression parsing consume all data We really need to make sure we do not end up ignoring part of the expression just because our rules are not exhaustive. This adds the appropriate test and fix in grammar. JIRA: YANGTOOLS-1049 Change-Id: I85278f0cd109897459be1db029fafbc95e203201 Signed-off-by: Robert Varga --- .../data/impl/leafref/LeafRefPathParser.g4 | 2 +- .../antlrv4/code/gen/LeafRefPathParser.g4 | 2 +- .../stmt/path/PathExpressionParserTest.java | 85 +++++++++++++++++++ 3 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 yang/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/path/PathExpressionParserTest.java diff --git a/yang/yang-data-impl/src/main/antlr4/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathParser.g4 b/yang/yang-data-impl/src/main/antlr4/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathParser.g4 index ec60a4cc32..1ae7f9ef67 100644 --- a/yang/yang-data-impl/src/main/antlr4/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathParser.g4 +++ b/yang/yang-data-impl/src/main/antlr4/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathParser.g4 @@ -4,7 +4,7 @@ options { tokenVocab = LeafRefPathLexer; } -path_arg : absolute_path | relative_path; +path_arg : (absolute_path | relative_path) EOF; absolute_path : (SLASH node_identifier (path_predicate)*)+; diff --git a/yang/yang-parser-rfc7950/src/main/antlr4/org/opendaylight/yangtools/antlrv4/code/gen/LeafRefPathParser.g4 b/yang/yang-parser-rfc7950/src/main/antlr4/org/opendaylight/yangtools/antlrv4/code/gen/LeafRefPathParser.g4 index ec60a4cc32..1ae7f9ef67 100644 --- a/yang/yang-parser-rfc7950/src/main/antlr4/org/opendaylight/yangtools/antlrv4/code/gen/LeafRefPathParser.g4 +++ b/yang/yang-parser-rfc7950/src/main/antlr4/org/opendaylight/yangtools/antlrv4/code/gen/LeafRefPathParser.g4 @@ -4,7 +4,7 @@ options { tokenVocab = LeafRefPathLexer; } -path_arg : absolute_path | relative_path; +path_arg : (absolute_path | relative_path) EOF; absolute_path : (SLASH node_identifier (path_predicate)*)+; diff --git a/yang/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/path/PathExpressionParserTest.java b/yang/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/path/PathExpressionParserTest.java new file mode 100644 index 0000000000..07ee8c3486 --- /dev/null +++ b/yang/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/path/PathExpressionParserTest.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2019 PANTHEON.tech, s.r.o. 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.parser.rfc7950.stmt.path; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.startsWith; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.doReturn; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; +import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference; + +@RunWith(MockitoJUnitRunner.StrictStubs.class) +public class PathExpressionParserTest { + @Mock + private StmtContext ctx; + @Mock + private StatementSourceReference ref; + + @Before + public void before() { + doReturn(ref).when(ctx).getStatementSourceReference(); + } + + @Test + public void testDerefPath() { + try { + // deref() is not valid as per RFC7950, but YANGTOOLS-968 would allow it + new PathExpressionParser().parseExpression(ctx, "deref(../id)/../type"); + fail("SourceException should have been thrown"); + } catch (SourceException e) { + assertSame(ref, e.getSourceReference()); + assertThat(e.getMessage(), startsWith("mismatched input '(' expecting ")); + assertThat(e.getMessage(), containsString(" at 1:5 [at ")); + } + } + + @Test + public void testInvalidLeftParent() { + try { + new PathExpressionParser().parseExpression(ctx, "foo("); + fail("SourceException should have been thrown"); + } catch (SourceException e) { + assertSame(ref, e.getSourceReference()); + assertThat(e.getMessage(), startsWith("extraneous input '(' expecting ")); + assertThat(e.getMessage(), containsString(" at 1:3 [at ")); + } + } + + @Test + public void testInvalidRightParent() { + try { + new PathExpressionParser().parseExpression(ctx, "foo)"); + fail("SourceException should have been thrown"); + } catch (SourceException e) { + assertSame(ref, e.getSourceReference()); + assertThat(e.getMessage(), startsWith("extraneous input ')' expecting ")); + assertThat(e.getMessage(), containsString(" at 1:3 [at ")); + } + } + + @Test + public void testInvalidIdentifier() { + try { + new PathExpressionParser().parseExpression(ctx, "foo%"); + fail("SourceException should have been thrown"); + } catch (SourceException e) { + assertSame(ref, e.getSourceReference()); + assertThat(e.getMessage(), startsWith("token recognition error at: '%' at 1:3 [at ")); + } + } +} -- 2.36.6