From b75ae5e0ac3842b9761bcf18671c99960230eb74 Mon Sep 17 00:00:00 2001 From: Thomas Heigl Date: Wed, 10 Nov 2021 17:43:13 +0100 Subject: [PATCH] #865 Ensure empty `PriorityQueue` can be deserialized (#866) --- .../kryo/serializers/DefaultSerializers.java | 5 +- .../serializers/DefaultSerializersTest.java | 61 +++++++++++++++++++ 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/src/com/esotericsoftware/kryo/serializers/DefaultSerializers.java b/src/com/esotericsoftware/kryo/serializers/DefaultSerializers.java index ae2d36b5a..d9768a638 100644 --- a/src/com/esotericsoftware/kryo/serializers/DefaultSerializers.java +++ b/src/com/esotericsoftware/kryo/serializers/DefaultSerializers.java @@ -743,7 +743,8 @@ protected PriorityQueue createCopy (Kryo kryo, PriorityQueue original) { } private PriorityQueue createPriorityQueue (Class type, int size, Comparator comparator) { - if (type == PriorityQueue.class || type == null) return new PriorityQueue(size, comparator); + final int initialCapacity = Math.max(size, 1); + if (type == PriorityQueue.class || type == null) return new PriorityQueue(initialCapacity, comparator); // Use reflection for subclasses. try { Constructor constructor = type.getConstructor(int.class, Comparator.class); @@ -753,7 +754,7 @@ private PriorityQueue createPriorityQueue (Class type, int } catch (SecurityException ignored) { } } - return (PriorityQueue)constructor.newInstance(comparator); + return (PriorityQueue)constructor.newInstance(initialCapacity, comparator); } catch (Exception ex) { throw new KryoException(ex); } diff --git a/test/com/esotericsoftware/kryo/serializers/DefaultSerializersTest.java b/test/com/esotericsoftware/kryo/serializers/DefaultSerializersTest.java index f77c43611..6b0318da4 100644 --- a/test/com/esotericsoftware/kryo/serializers/DefaultSerializersTest.java +++ b/test/com/esotericsoftware/kryo/serializers/DefaultSerializersTest.java @@ -340,6 +340,42 @@ public int compare (Integer o1, Integer o2) { assertEquals(queue.peek(), copy.peek()); } + @Test + void testPriorityQueue () { + List values = Arrays.asList(7, 0, 5, 123, 432); + PriorityQueue queue = new PriorityQueue(3, new IntegerComparator()); + queue.addAll(values); + + kryo.register(PriorityQueue.class); + kryo.register(IntegerComparator.class); + roundTrip(12, queue); + } + + @Test + void testPriorityQueueSubclass () { + List values = Arrays.asList(7, 0, 5, 123, 432); + PriorityQueue queue = new PriorityQueueSubclass(3, new IntegerComparator()); + queue.addAll(values); + + kryo.register(PriorityQueueSubclass.class); + kryo.register(IntegerComparator.class); + roundTrip(12, queue); + } + + @Test + void testEmptyPriorityQueue () { + PriorityQueue queue = new PriorityQueue(); + kryo.register(PriorityQueue.class); + roundTrip(3, queue); + } + + @Test + void testEmptyPriorityQueueSubclass () { + PriorityQueue queue = new PriorityQueueSubclass(); + kryo.register(PriorityQueueSubclass.class); + roundTrip(3, queue); + } + @Test void testCalendar () { kryo.setRegistrationRequired(false); @@ -467,6 +503,17 @@ void testURLSerializer () throws Exception { roundTrip(78, new URL("https://github.com:443/EsotericSoftware/kryo/pulls?utf8=%E2%9C%93&q=is%3Apr")); } + protected void doAssertEquals(Object object1, Object object2) { + if (object1 instanceof PriorityQueue && object2 instanceof PriorityQueue) { + final PriorityQueue q1 = (PriorityQueue) object1; + final PriorityQueue q2 = (PriorityQueue) object2; + super.doAssertEquals(q1.peek(), q2.peek()); + super.doAssertEquals(q1.toArray(), q2.toArray()); + } else { + super.doAssertEquals(object1, object2); + } + } + public enum TestEnum { a, b, c } @@ -500,4 +547,18 @@ public BigIntegerSubclass (String val) { } } + static class PriorityQueueSubclass extends PriorityQueue { + public PriorityQueueSubclass() { + } + + public PriorityQueueSubclass(int initialCapacity, Comparator comparator) { + super(initialCapacity, comparator); + } + } + + static class IntegerComparator implements Comparator { + public int compare(Integer o1, Integer o2) { + return o2 - o1; + } + } }