[#5613] Incorrect deserialisation of deeply nested PostgreSQL ARRAYs / UDTs

This commit is contained in:
lukaseder 2016-11-01 17:14:30 +01:00
parent 4659e83f09
commit a3bb473e86
2 changed files with 32 additions and 16 deletions

View File

@ -2312,18 +2312,16 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
try {
Class<?> component = type.getComponentType();
String values = string.replaceAll("^\\{(.*)\\}$", "$1");
List<String> values = PostgresUtils.toPGArray(string);
if ("".equals(values)) {
if (values.isEmpty()) {
return (Object[]) java.lang.reflect.Array.newInstance(component, 0);
}
else {
String[] split = values.split(",");
Object[] result = (Object[]) java.lang.reflect.Array.newInstance(component, split.length);
Object[] result = (Object[]) java.lang.reflect.Array.newInstance(component, values.size());
for (int i = 0; i < split.length; i++) {
result[i] = pgFromString(type.getComponentType(), split[i]);
}
for (int i = 0; i < values.size(); i++)
result[i] = pgFromString(type.getComponentType(), values.get(i));
return result;
}

View File

@ -50,6 +50,7 @@ import java.io.OutputStream;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.jooq.Converter;
@ -266,10 +267,27 @@ public class PostgresUtils {
}
/**
* Tokenize a PGObject input string
* Tokenize a PGObject input string.
*/
public static List<String> toPGArray(String input) {
if ("{}".equals(input))
return Collections.emptyList();
return toPGObjectOrArray(input, '{', '}');
}
/**
* Tokenize a PGObject input string.
*/
public static List<String> toPGObject(String input) {
return toPGObjectOrArray(input, '(', ')');
}
/**
* Tokenize a PGObject input string.
*/
@SuppressWarnings("null")
public static List<String> toPGObject(String input) {
private static List<String> toPGObjectOrArray(String input, char open, char close) {
List<String> values = new ArrayList<String>();
int i = 0;
int state = PG_OBJECT_INIT;
@ -282,8 +300,8 @@ public class PostgresUtils {
// Initial state
case PG_OBJECT_INIT:
// Consume the opening parenthesis
if (c == '(') {
// Consume the opening bracket
if (c == open) {
state = PG_OBJECT_BEFORE_VALUE;
}
@ -300,7 +318,7 @@ public class PostgresUtils {
}
// Consume "empty"
else if (c == ')') {
else if (c == close) {
values.add(null);
state = PG_OBJECT_END;
}
@ -370,8 +388,8 @@ public class PostgresUtils {
// A value is being created
case PG_OBJECT_UNQUOTED_VALUE:
// Consume the closing parenthesis
if (c == ')') {
// Consume the closing bracket
if (c == close) {
values.add(sb.toString());
state = PG_OBJECT_END;
}
@ -392,8 +410,8 @@ public class PostgresUtils {
// A value was just added
case PG_OBJECT_AFTER_VALUE:
// Consume the closing parenthesis
if (c == ')') {
// Consume the closing bracket
if (c == close) {
state = PG_OBJECT_END;
}