diff --git a/src/main/java/net/openhft/chronicle/hash/serialization/BytesReader.java b/src/main/java/net/openhft/chronicle/hash/serialization/BytesReader.java index 05e9aa391..c05ae3b12 100644 --- a/src/main/java/net/openhft/chronicle/hash/serialization/BytesReader.java +++ b/src/main/java/net/openhft/chronicle/hash/serialization/BytesReader.java @@ -42,6 +42,8 @@ import java.io.Serializable; * * @Override * public LongPair[] read(Bytes bytes, long size, LongPair[] toReuse) { + * if (size > Integer.MAX_VALUE * 16L) + * throw new IllegalStateException("LongPair[] size couldn't be " + (size / 16L)); * int resLen = (int) (size / 16L); * LongPair[] res; * if (toReuse != null) { diff --git a/src/main/java/net/openhft/chronicle/hash/serialization/internal/ByteArrayMarshaller.java b/src/main/java/net/openhft/chronicle/hash/serialization/internal/ByteArrayMarshaller.java index cb1084c2b..d92787fbb 100644 --- a/src/main/java/net/openhft/chronicle/hash/serialization/internal/ByteArrayMarshaller.java +++ b/src/main/java/net/openhft/chronicle/hash/serialization/internal/ByteArrayMarshaller.java @@ -55,19 +55,24 @@ public enum ByteArrayMarshaller implements BytesInterop, BytesReader (long) Integer.MAX_VALUE) - throw new IllegalArgumentException("byte[] size should be non-negative int, " + - size + " given. Memory corruption?"); - if (toReuse == null || size != toReuse.length) - toReuse = new byte[(int) size]; + int resLen = resLen(size); + if (toReuse == null || resLen != toReuse.length) + toReuse = new byte[resLen]; bytes.read(toReuse); return toReuse; } + + private int resLen(long size) { + if (size < 0L || size > (long) Integer.MAX_VALUE) + throw new IllegalArgumentException("byte[] size should be non-negative int, " + + size + " given. Memory corruption?"); + return (int) size; + } } diff --git a/src/main/java/net/openhft/chronicle/hash/serialization/internal/CharArrayMarshaller.java b/src/main/java/net/openhft/chronicle/hash/serialization/internal/CharArrayMarshaller.java index 748575067..9e646beaf 100644 --- a/src/main/java/net/openhft/chronicle/hash/serialization/internal/CharArrayMarshaller.java +++ b/src/main/java/net/openhft/chronicle/hash/serialization/internal/CharArrayMarshaller.java @@ -45,19 +45,28 @@ public enum CharArrayMarshaller implements BytesInterop, BytesReader Integer.MAX_VALUE) + throw new IllegalArgumentException("char[] size should be non-negative int, " + + resLen + " given. Memory corruption?"); + return (int) resLen; + } + @Override public long size(char[] chars) { return chars.length * 2L; diff --git a/src/test/java/net/openhft/chronicle/map/CHMUseCasesTest.java b/src/test/java/net/openhft/chronicle/map/CHMUseCasesTest.java index 47f062435..7eac9d042 100644 --- a/src/test/java/net/openhft/chronicle/map/CHMUseCasesTest.java +++ b/src/test/java/net/openhft/chronicle/map/CHMUseCasesTest.java @@ -1,5 +1,6 @@ package net.openhft.chronicle.map; +import com.google.common.primitives.Chars; import junit.framework.Assert; import net.openhft.chronicle.hash.replication.TcpTransportAndNetworkConfig; import net.openhft.lang.io.ByteBufferBytes; @@ -21,6 +22,7 @@ import java.util.*; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; +import static java.util.Arrays.asList; import static org.junit.Assert.*; /** @@ -36,7 +38,7 @@ public class CHMUseCasesTest { @Parameterized.Parameters public static Collection data() { - return Arrays.asList(new Object[][]{ + return asList(new Object[][]{ { TypeOfMap.SIMPLE }, @@ -76,7 +78,6 @@ public class CHMUseCasesTest { @Test - @Ignore("HCOLL-256 Maps containing Value as char[], get() returns too many char[]'s") public void testCharArrayValue() throws ExecutionException, InterruptedException, IOException { int valueSize = 10; @@ -92,8 +93,7 @@ public class CHMUseCasesTest { char[] actual = map.get("Key"); System.out.println(actual); - assertTrue(Arrays.equals(expected, map.get("Key"))); - + assertEquals(Chars.asList(expected), Chars.asList(map.get("Key"))); } } @@ -2063,33 +2063,33 @@ public class CHMUseCasesTest { try (ChronicleMap> map = newInstance(builder)) { map.put("1", Collections.emptyList()); - map.put("2", Arrays.asList("two-A")); + map.put("2", asList("two-A")); List list1 = new ArrayList<>(); try (WriteContext wc = map.acquireUsingLocked("1", list1)) { list1.add("one"); - assertEquals(Arrays.asList("one"), list1); + assertEquals(asList("one"), list1); } List list2 = new ArrayList<>(); try (ReadContext rc = map.getUsingLocked("1", list2)) { assertTrue(rc.present()); - assertEquals(Arrays.asList("one"), list2); + assertEquals(asList("one"), list2); } try (ReadContext rc = map.getUsingLocked("2", list2)) { assertTrue(rc.present()); list2.add("two-B"); // this is not written as it only a read context - assertEquals(Arrays.asList("two-A", "two-B"), list2); + assertEquals(asList("two-A", "two-B"), list2); } try (WriteContext wc = map.acquireUsingLocked("2", list1)) { list1.add("two-C"); - assertEquals(Arrays.asList("two-A", "two-C"), list1); + assertEquals(asList("two-A", "two-C"), list1); } try (ReadContext rc = map.getUsingLocked("2", list2)) { assertTrue(rc.present()); - assertEquals(Arrays.asList("two-A", "two-C"), list2); + assertEquals(asList("two-A", "two-C"), list2); } } } @@ -2107,25 +2107,25 @@ public class CHMUseCasesTest { try (ChronicleMap> map = newInstance(builder)) { map.put("1", Collections.emptySet()); - map.put("2", new LinkedHashSet(Arrays.asList("one"))); + map.put("2", new LinkedHashSet(asList("one"))); Set list1 = new LinkedHashSet<>(); try (WriteContext wc = map.acquireUsingLocked("1", list1)) { list1.add("two"); - assertEquals(new LinkedHashSet(Arrays.asList("two")), list1); + assertEquals(new LinkedHashSet(asList("two")), list1); } Set list2 = new LinkedHashSet<>(); try (ReadContext rc = map.getUsingLocked("1", list2)) { assertTrue(rc.present()); - assertEquals(new LinkedHashSet(Arrays.asList("two")), list2); + assertEquals(new LinkedHashSet(asList("two")), list2); } try (WriteContext wc = map.acquireUsingLocked("2", list1)) { list1.add("three"); - assertEquals(new LinkedHashSet(Arrays.asList("one", "three")), list1); + assertEquals(new LinkedHashSet(asList("one", "three")), list1); } try (ReadContext rc = map.getUsingLocked("2", list2)) { assertTrue(rc.present()); - assertEquals(new LinkedHashSet(Arrays.asList("one", "three")), list2); + assertEquals(new LinkedHashSet(asList("one", "three")), list2); } } } diff --git a/src/test/java/net/openhft/chronicle/map/fromdocs/LongPairArrayReader.java b/src/test/java/net/openhft/chronicle/map/fromdocs/LongPairArrayReader.java index 198ef89e5..25173b946 100644 --- a/src/test/java/net/openhft/chronicle/map/fromdocs/LongPairArrayReader.java +++ b/src/test/java/net/openhft/chronicle/map/fromdocs/LongPairArrayReader.java @@ -31,6 +31,8 @@ enum LongPairArrayReader implements BytesReader { @Override public LongPair[] read(Bytes bytes, long size, LongPair[] toReuse) { + if (size > Integer.MAX_VALUE * 16L) + throw new IllegalStateException("LongPair[] size couldn't be " + (size / 16L)); int resLen = (int) (size / 16L); LongPair[] res; if (toReuse != null) {