Skip to content

Commit 2dda29e

Browse files
committed
fix: Node factory methods are not invoked through NodesFactoryAccess when NodesFactory is extended.
1 parent fd6faf1 commit 2dda29e

File tree

2 files changed

+60
-2
lines changed

2 files changed

+60
-2
lines changed

src/main/java/cz/jirutka/rsql/parser/NodesFactoryAccess.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ private static MethodHandle methodHandle(Lookup lookup, String name, Class<?>...
7575
}
7676

7777
static LogicalNode create(NodesFactory factory, LogicalOperator operator, List<Node> children) {
78-
if (LOGICAL_NODE_MH == null) {
78+
if (LOGICAL_NODE_MH == null || factory.getClass() != NodesFactory.class) {
7979
return factory.createLogicalNode(operator, children);
8080
} else {
8181
try {
@@ -92,7 +92,7 @@ static LogicalNode create(NodesFactory factory, LogicalOperator operator, List<N
9292

9393
static ComparisonNode create(NodesFactory factory, String operatorToken, String selector, List<String> arguments)
9494
throws UnknownOperatorException {
95-
if (COMP_NODE_MH == null) {
95+
if (COMP_NODE_MH == null || factory.getClass() != NodesFactory.class) {
9696
return factory.createComparisonNode(operatorToken, selector, arguments);
9797
} else {
9898
try {

src/test/groovy/cz/jirutka/rsql/parser/NodesFactoryAccessSpec.groovy

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
package cz.jirutka.rsql.parser
2525

2626
import cz.jirutka.rsql.parser.ast.ComparisonNode
27+
import cz.jirutka.rsql.parser.ast.ComparisonOperator
2728
import cz.jirutka.rsql.parser.ast.LogicalOperator
2829
import cz.jirutka.rsql.parser.ast.NodesFactory
2930
import spock.lang.Specification
@@ -81,4 +82,61 @@ class NodesFactoryAccessSpec extends Specification {
8182

8283
actual.arguments.size() == arguments.size()
8384
}
85+
86+
def 'Should not use trusted constructors when NodesFactory is inherited'(LogicalOperator op) {
87+
given:
88+
def factory = new NodesFactoryExtended(defaultOperators())
89+
def children = [
90+
new ComparisonNode(EQUAL, 'a1', ['b1']),
91+
new ComparisonNode(NOT_EQUAL, 'a2', ['b2'])
92+
]
93+
94+
when:
95+
def actual = NodesFactoryAccess.create(factory, op, children)
96+
97+
then:
98+
actual.children.size() == children.size()
99+
100+
and: 'original is not modified by modifying copy'
101+
def childrenCopy = actual.children
102+
childrenCopy.removeLast()
103+
childrenCopy.size() + 1 == children.size()
104+
105+
and: 'modifying original it should not change in the LogicalNode'
106+
children.removeLast()
107+
108+
actual.children.size() == children.size() + 1
109+
110+
where:
111+
op << LogicalOperator.values()
112+
}
113+
114+
def 'Should not use trusted constructors when NodesFactory is inherited and creating comparison node'() {
115+
given:
116+
def factory = new NodesFactoryExtended(defaultOperators())
117+
def arguments = ['x', 'y', 'z']
118+
119+
when:
120+
def actual = NodesFactoryAccess.create(factory, '=in=', 'a1', arguments)
121+
122+
then:
123+
actual.arguments.size() == arguments.size()
124+
125+
and: 'original is not modified by modifying copy'
126+
def childrenCopy = actual.arguments
127+
childrenCopy.removeLast()
128+
childrenCopy.size() + 1 == arguments.size()
129+
130+
and: 'modifying original it should not change in the ComparisonNode'
131+
arguments.removeLast()
132+
133+
actual.arguments.size() == arguments.size() + 1
134+
}
135+
136+
static class NodesFactoryExtended extends NodesFactory {
137+
138+
NodesFactoryExtended(Set<ComparisonOperator> operators) {
139+
super(operators)
140+
}
141+
}
84142
}

0 commit comments

Comments
 (0)