[#3462] Field<Object>.in(Object...) can be called with Select<?> arguments, accidentally

This commit is contained in:
Lukas Eder 2014-07-28 11:42:06 +02:00
parent 05063e5b60
commit dbf42c7dac
3 changed files with 45 additions and 8 deletions

View File

@ -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();
}

View File

@ -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));
}
}

View File

@ -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));
}
}