[#3462] Field<Object>.in(Object...) can be called with Select<?> arguments, accidentally
This commit is contained in:
parent
05063e5b60
commit
dbf42c7dac
@ -767,8 +767,26 @@ abstract class AbstractField<T> extends AbstractQueryPart implements Field<T> {
|
||||
return like(concat, Utils.ESCAPE);
|
||||
}
|
||||
|
||||
private final boolean isAccidentalSelect(T[] values) {
|
||||
return (values != null && values.length == 1 && values[0] instanceof Select);
|
||||
}
|
||||
|
||||
private final boolean isAccidentalCollection(T[] values) {
|
||||
return (values != null && values.length == 1 && values[0] instanceof Collection);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public final Condition in(T... values) {
|
||||
|
||||
// [#3362] Prevent "rogue" API usage when using Field<Object>.in(Object... values)
|
||||
if (isAccidentalSelect(values))
|
||||
return in((Select<Record1<T>>) values[0]);
|
||||
|
||||
// [#3347] Prevent "rogue" API usage when using Field<Object>.in(Object... values)
|
||||
if (isAccidentalCollection(values))
|
||||
return in((Collection<?>) values[0]);
|
||||
|
||||
return in(Utils.fields(values, this).toArray(new Field<?>[0]));
|
||||
}
|
||||
|
||||
@ -798,8 +816,18 @@ abstract class AbstractField<T> extends AbstractQueryPart implements Field<T> {
|
||||
return compare(IN, query);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public final Condition notIn(T... values) {
|
||||
|
||||
// [#3362] Prevent "rogue" API usage when using Field<Object>.in(Object... values)
|
||||
if (isAccidentalSelect(values))
|
||||
return notIn((Select<Record1<T>>) values[0]);
|
||||
|
||||
// [#3347] Prevent "rogue" API usage when using Field<Object>.in(Object... values)
|
||||
if (isAccidentalCollection(values))
|
||||
return notIn((Collection<?>) values[0]);
|
||||
|
||||
if (values == null || values.length == 0) {
|
||||
return trueCondition();
|
||||
}
|
||||
|
||||
@ -786,13 +786,7 @@ final class Utils {
|
||||
|
||||
if (values != null && field != null) {
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
|
||||
// [#3347] Defend against rogue API usage, e.g. when calling
|
||||
// Field.in(T...) with a Collection argument
|
||||
if (values[i] instanceof Collection)
|
||||
result.addAll(fields(((Collection<?>) values[i]).toArray(), field));
|
||||
else
|
||||
result.add(field(values[i], field));
|
||||
result.add(field(values[i], field));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -40,11 +40,14 @@
|
||||
*/
|
||||
package org.jooq.test;
|
||||
|
||||
import static org.jooq.impl.DSL.val;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.jooq.Condition;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Select;
|
||||
import org.jooq.impl.DSL;
|
||||
|
||||
import org.junit.Test;
|
||||
@ -60,7 +63,7 @@ import org.junit.Test;
|
||||
public class RogueAPIUsageTest extends AbstractTest {
|
||||
|
||||
@Test
|
||||
public void testInPredicate() {
|
||||
public void testInPredicateWithCollection() {
|
||||
Field<Object> a = DSL.field("a");
|
||||
List<String> values = Arrays.asList("a", "b");
|
||||
|
||||
@ -70,4 +73,16 @@ public class RogueAPIUsageTest extends AbstractTest {
|
||||
assertEquals("a in ('a', 'b')", create.renderInlined(c));
|
||||
assertEquals("a in (:1, :2)", create.renderNamedParams(c));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInPredicateWithSelect() {
|
||||
Field<Object> a = DSL.field("a");
|
||||
Select<?> values = DSL.select(val(1));
|
||||
|
||||
Condition c = a.in(values);
|
||||
|
||||
assertEquals("a in (select ? from dual)", create.render(c));
|
||||
assertEquals("a in (select 1 from dual)", create.renderInlined(c));
|
||||
assertEquals("a in (select :1 from dual)", create.renderNamedParams(c));
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user