Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 334593

Summary: NPE caused by ConcreteSyntaxConstraintProvider calling grammar util with null AbstractElement
Product: [Modeling] TMF Reporter: Henrik Lindberg <henrik.lindberg>
Component: XtextAssignee: Project Inbox <tmf.xtext-inbox>
Status: CLOSED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: dennis.huebner, sebastian.zarnekow
Version: 1.0.1   
Target Milestone: ---   
Hardware: All   
OS: All   
Whiteboard:

Description Henrik Lindberg CLA 2011-01-17 17:49:33 EST
When the ConcreteSyntaxConstraintProvider checks a trailing optional group consisting of two data rules NPE is trown. The loop in ConcreteSyntaxConstraintProvider has no check if it produces a null element. (Checks for other types except group has a corresponding check). (But since I am not 100 sure if it has bad input, or if the error is local to ConcreteSyntaxConstraintProvider, I stopped investigating this further).

The rules that caused this was changed from something like:
ARule : x += X (COMMA OWS x += X)* endComma? ;
endComma : COMMA OWS ;

terminal COMMA : ',' ;
OWS : WHITE * ;
WHITE : (SP | TAB | CR | NL) ; 
// SP, TAB etc. are all terminal

When changed to:
ARule : x += X (COMMA OWS x += X)* (COMMA OWS)? ;

...a NPE is thrown because the logic below in createElement method does not check if it assigns
null to ele, which will be the case if no element in the group is considered "relevant".

// lines 341 - 357
} else if (ele instanceof Group || ele instanceof UnorderedGroup) {
	CompoundElement comp = (CompoundElement) ele;
	AbstractElement lastChild = null;
	for (AbstractElement o : comp.getElements())
		if (containsRelevantElement(o)) {
			if (lastChild == null)
				lastChild = o;
			else {
				List<AbstractElement> c = new ArrayList<AbstractElement>(comp.getElements());
				List<ISyntaxConstraint> e = createSummarizedAssignments(comp, c, semanticType, optional);
				if (e.size() == 1 && c.size() == 0)
					return e.get(0);
				return createElement(ConstraintType.GROUP, ele, c, e, semanticType, multiple, optional);
			}
		}
	ele = lastChild;
	continue;


java.lang.NullPointerException
	at org.eclipse.xtext.GrammarUtil.isOneOrMoreCardinality(GrammarUtil.java:295)
	at org.eclipse.xtext.GrammarUtil.isMultipleCardinality(GrammarUtil.java:291)
	at org.eclipse.xtext.validation.impl.ConcreteSyntaxConstraintProvider.createElement(ConcreteSyntaxConstraintProvider.java:334)
	at org.eclipse.xtext.validation.impl.ConcreteSyntaxConstraintProvider.createElement(ConcreteSyntaxConstraintProvider.java:319)
	at org.eclipse.xtext.validation.impl.ConcreteSyntaxConstraintProvider.createElement(ConcreteSyntaxConstraintProvider.java:353)
	at org.eclipse.xtext.validation.impl.ConcreteSyntaxConstraintProvider.getConstraint(ConcreteSyntaxConstraintProvider.java:448)
	at org.eclipse.xtext.validation.impl.ConcreteSyntaxConstraintProvider.getConstraints(ConcreteSyntaxConstraintProvider.java:463)
	at org.eclipse.xtext.validation.impl.ConcreteSyntaxValidator.validateObject(ConcreteSyntaxValidator.java:104)
	at org.eclipse.xtext.validation.impl.ConcreteSyntaxValidator.validateRecursive(ConcreteSyntaxValidator.java:150)
	at org.eclipse.xtext.parsetree.reconstr.Serializer.serialize(Serializer.java:48)
	at org.eclipse.xtext.parsetree.reconstr.Serializer.serialize(Serializer.java:71)
	at org.eclipse.xtext.parsetree.reconstr.Serializer.serialize(Serializer.java:65)
	at org.eclipse.xtext.junit.AbstractXtextTests.serialize(AbstractXtextTests.java:131)
	at org.cloudsmith.geppetto.pp.dsl.test.TestPuppetResourceExpr.test_Serialize_1(TestPuppetResourceExpr.java:103)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at junit.framework.TestCase.runTest(TestCase.java:168)
	at junit.framework.TestCase.runBare(TestCase.java:134)
	at junit.framework.TestResult$1.protect(TestResult.java:110)
	at junit.framework.TestResult.runProtected(TestResult.java:128)
	at junit.framework.TestResult.run(TestResult.java:113)
	at junit.framework.TestCase.run(TestCase.java:124)
	at junit.framework.TestSuite.runTest(TestSuite.java:232)
	at junit.framework.TestSuite.run(TestSuite.java:227)
	at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
	at org.eclipse.pde.internal.junit.runtime.RemotePluginTestRunner.main(RemotePluginTestRunner.java:62)
	at org.eclipse.pde.internal.junit.runtime.CoreTestApplication.run(CoreTestApplication.java:23)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.eclipse.equinox.internal.app.EclipseAppContainer.callMethodWithException(EclipseAppContainer.java:587)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:198)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:369)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:619)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:574)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1407)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1383)
Comment 1 Sven Efftinge CLA 2012-11-20 10:44:19 EST
has been fixed in the meantime :

} else if (ele instanceof Group || ele instanceof UnorderedGroup) {
				CompoundElement comp = (CompoundElement) ele;
				AbstractElement lastChild = null;
				for (AbstractElement o : comp.getElements())
					if (containsRelevantElement(o)) {
						if (lastChild == null)
							lastChild = o;
						else {
							List<AbstractElement> c = new ArrayList<AbstractElement>(comp.getElements());
							List<ISyntaxConstraint> e = createSummarizedAssignments(comp, c, semanticType, optional);
							if (e.size() == 1 && c.size() == 0)
								return e.get(0);
							return createElement(ConstraintType.GROUP, ele, c, e, semanticType, multiple, optional);
						}
					}
				if (lastChild == null)
					return null;
				ele = lastChild;
				continue;
			}
Comment 2 Eclipse Webmaster CLA 2017-10-31 10:46:42 EDT
Requested via bug 522520.

-M.
Comment 3 Eclipse Webmaster CLA 2017-10-31 10:57:56 EDT
Requested via bug 522520.

-M.