From 2b0657c5aa03744a2af7db0995a0ef2acb12b74e Mon Sep 17 00:00:00 2001 From: moriadry Date: Sat, 17 Aug 2019 16:02:24 +0800 Subject: [PATCH 1/2] fix stackoverflow of protostuff and other errors --- .../protostuff/ProtostuffObjectInput.java | 6 +-- .../protostuff/ProtostuffObjectOutput.java | 6 +-- .../ProtostuffObjectOutputTest.java | 53 +++++++++++++++++++ 3 files changed, 59 insertions(+), 6 deletions(-) diff --git a/dubbo-serialization/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectInput.java b/dubbo-serialization/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectInput.java index e8307748deb..834a4ca5f48 100644 --- a/dubbo-serialization/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectInput.java +++ b/dubbo-serialization/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectInput.java @@ -17,7 +17,7 @@ package org.apache.dubbo.common.serialize.protostuff; -import io.protostuff.GraphIOUtil; +import io.protostuff.ProtobufIOUtil; import io.protostuff.Schema; import io.protostuff.runtime.RuntimeSchema; import java.io.DataInputStream; @@ -61,12 +61,12 @@ public Object readObject() throws IOException, ClassNotFoundException { if (WrapperUtils.needWrapper(clazz)) { Schema schema = RuntimeSchema.getSchema(Wrapper.class); Wrapper wrapper = schema.newMessage(); - GraphIOUtil.mergeFrom(bytes, wrapper, schema); + ProtobufIOUtil.mergeFrom(bytes, wrapper, schema); result = wrapper.getData(); } else { Schema schema = RuntimeSchema.getSchema(clazz); result = schema.newMessage(); - GraphIOUtil.mergeFrom(bytes, result, schema); + ProtobufIOUtil.mergeFrom(bytes, result, schema); } return result; diff --git a/dubbo-serialization/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectOutput.java b/dubbo-serialization/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectOutput.java index ab94d3ba8df..5657adbc254 100644 --- a/dubbo-serialization/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectOutput.java +++ b/dubbo-serialization/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectOutput.java @@ -17,7 +17,7 @@ package org.apache.dubbo.common.serialize.protostuff; -import io.protostuff.GraphIOUtil; +import io.protostuff.ProtobufIOUtil; import io.protostuff.LinkedBuffer; import io.protostuff.Schema; import io.protostuff.runtime.RuntimeSchema; @@ -50,11 +50,11 @@ public void writeObject(Object obj) throws IOException { if (obj == null || WrapperUtils.needWrapper(obj)) { Schema schema = RuntimeSchema.getSchema(Wrapper.class); Wrapper wrapper = new Wrapper(obj); - bytes = GraphIOUtil.toByteArray(wrapper, schema, buffer); + bytes = ProtobufIOUtil.toByteArray(wrapper, schema, buffer); classNameBytes = Wrapper.class.getName().getBytes(); } else { Schema schema = RuntimeSchema.getSchema(obj.getClass()); - bytes = GraphIOUtil.toByteArray(obj, schema, buffer); + bytes = ProtobufIOUtil.toByteArray(obj, schema, buffer); classNameBytes = obj.getClass().getName().getBytes(); } } finally { diff --git a/dubbo-serialization/dubbo-serialization-test/src/test/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectOutputTest.java b/dubbo-serialization/dubbo-serialization-test/src/test/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectOutputTest.java index 52397920f0f..37347cdad40 100644 --- a/dubbo-serialization/dubbo-serialization-test/src/test/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectOutputTest.java +++ b/dubbo-serialization/dubbo-serialization-test/src/test/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectOutputTest.java @@ -23,9 +23,13 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.Serializable; import java.sql.Timestamp; +import java.util.ArrayList; import java.util.Date; +import java.util.List; +import org.apache.dubbo.common.serialize.model.SerializablePerson; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -90,9 +94,58 @@ public void testSerializeDate() throws IOException, ClassNotFoundException { assertThat(serializedTime, is(originTime)); } + @Test + public void testListObject() throws IOException, ClassNotFoundException { + List list = new ArrayList(); + list.add(new SerializablePerson()); + list.add(new SerializablePerson()); + list.add(new SerializablePerson()); + SerializablePersonList personList = new SerializablePersonList(list); + this.protostuffObjectOutput.writeObject(personList); + this.flushToInput(); + + SerializablePersonList serializedTime = protostuffObjectInput.readObject(SerializablePersonList.class); + assertThat(serializedTime, is(personList)); + } + private void flushToInput() throws IOException { this.protostuffObjectOutput.flushBuffer(); this.byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); this.protostuffObjectInput = new ProtostuffObjectInput(byteArrayInputStream); } + + private class SerializablePersonList implements Serializable { + private static final long serialVersionUID = 1L; + + public List personList; + + public SerializablePersonList() {} + + public SerializablePersonList(List list) { + this.personList = list; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + + SerializablePersonList list = (SerializablePersonList) obj; + if (list.personList == null && this.personList == null) + return true; + if (list.personList == null || this.personList == null) + return false; + if (list.personList.size() != this.personList.size()) + return false; + for (int i =0; i < this.personList.size(); i++) { + if (!this.personList.get(i).equals(list.personList.get(i))) + return false; + } + return true; + } + } } From 7651e3ad859c32e6fc47b8ab806fe03ded2cf706 Mon Sep 17 00:00:00 2001 From: moriadry Date: Mon, 19 Aug 2019 14:19:33 +0800 Subject: [PATCH 2/2] revert --- .../protostuff/ProtostuffObjectInput.java | 6 +- .../protostuff/ProtostuffObjectOutput.java | 6 +- .../ProtostuffObjectOutputTest.java | 113 ++++++++++++++++-- 3 files changed, 108 insertions(+), 17 deletions(-) diff --git a/dubbo-serialization/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectInput.java b/dubbo-serialization/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectInput.java index 834a4ca5f48..e8307748deb 100644 --- a/dubbo-serialization/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectInput.java +++ b/dubbo-serialization/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectInput.java @@ -17,7 +17,7 @@ package org.apache.dubbo.common.serialize.protostuff; -import io.protostuff.ProtobufIOUtil; +import io.protostuff.GraphIOUtil; import io.protostuff.Schema; import io.protostuff.runtime.RuntimeSchema; import java.io.DataInputStream; @@ -61,12 +61,12 @@ public Object readObject() throws IOException, ClassNotFoundException { if (WrapperUtils.needWrapper(clazz)) { Schema schema = RuntimeSchema.getSchema(Wrapper.class); Wrapper wrapper = schema.newMessage(); - ProtobufIOUtil.mergeFrom(bytes, wrapper, schema); + GraphIOUtil.mergeFrom(bytes, wrapper, schema); result = wrapper.getData(); } else { Schema schema = RuntimeSchema.getSchema(clazz); result = schema.newMessage(); - ProtobufIOUtil.mergeFrom(bytes, result, schema); + GraphIOUtil.mergeFrom(bytes, result, schema); } return result; diff --git a/dubbo-serialization/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectOutput.java b/dubbo-serialization/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectOutput.java index 5657adbc254..ab94d3ba8df 100644 --- a/dubbo-serialization/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectOutput.java +++ b/dubbo-serialization/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectOutput.java @@ -17,7 +17,7 @@ package org.apache.dubbo.common.serialize.protostuff; -import io.protostuff.ProtobufIOUtil; +import io.protostuff.GraphIOUtil; import io.protostuff.LinkedBuffer; import io.protostuff.Schema; import io.protostuff.runtime.RuntimeSchema; @@ -50,11 +50,11 @@ public void writeObject(Object obj) throws IOException { if (obj == null || WrapperUtils.needWrapper(obj)) { Schema schema = RuntimeSchema.getSchema(Wrapper.class); Wrapper wrapper = new Wrapper(obj); - bytes = ProtobufIOUtil.toByteArray(wrapper, schema, buffer); + bytes = GraphIOUtil.toByteArray(wrapper, schema, buffer); classNameBytes = Wrapper.class.getName().getBytes(); } else { Schema schema = RuntimeSchema.getSchema(obj.getClass()); - bytes = ProtobufIOUtil.toByteArray(obj, schema, buffer); + bytes = GraphIOUtil.toByteArray(obj, schema, buffer); classNameBytes = obj.getClass().getName().getBytes(); } } finally { diff --git a/dubbo-serialization/dubbo-serialization-test/src/test/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectOutputTest.java b/dubbo-serialization/dubbo-serialization-test/src/test/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectOutputTest.java index 37347cdad40..6cb2cfbc42c 100644 --- a/dubbo-serialization/dubbo-serialization-test/src/test/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectOutputTest.java +++ b/dubbo-serialization/dubbo-serialization-test/src/test/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectOutputTest.java @@ -25,6 +25,7 @@ import java.io.IOException; import java.io.Serializable; import java.sql.Timestamp; +import java.time.LocalTime; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -75,32 +76,66 @@ public void testSerializeSqlDate() throws IOException, ClassNotFoundException { } @Test - public void testSerializeSqlTime() throws IOException, ClassNotFoundException { - java.sql.Time originTime = new java.sql.Time(System.currentTimeMillis()); - this.protostuffObjectOutput.writeObject(originTime); + public void testObjectList() throws IOException, ClassNotFoundException { + List args = new ArrayList(); + args.add(new SerializablePerson()); + + this.protostuffObjectOutput.writeObject(args); this.flushToInput(); - java.sql.Time serializedTime = protostuffObjectInput.readObject(java.sql.Time.class); - assertThat(serializedTime, is(originTime)); + List serializedTime = (List) protostuffObjectInput.readObject(); + assertThat(serializedTime, is(args)); } @Test - public void testSerializeDate() throws IOException, ClassNotFoundException { - Date originTime = new Date(); - this.protostuffObjectOutput.writeObject(originTime); + public void testCustomizeDateList() throws IOException, ClassNotFoundException { + java.sql.Date originTime = new java.sql.Date(System.currentTimeMillis()); + java.sql.Date yesterdayTime = new java.sql.Date(System.currentTimeMillis() + 30*60*1000); + java.sql.Date beforeTime = new java.sql.Date(System.currentTimeMillis() + 30*60*1000*4); + List list = new ArrayList<>(); + + list.add(originTime); + list.add(yesterdayTime); + list.add(beforeTime); + + this.protostuffObjectOutput.writeObject(list); this.flushToInput(); - Date serializedTime = protostuffObjectInput.readObject(Date.class); - assertThat(serializedTime, is(originTime)); + List serializedTimeList = (List) protostuffObjectInput.readObject(); + assertThat(serializedTimeList, is(list)); + } + + @Test + public void testCustomizeTimeList() throws IOException, ClassNotFoundException { + + List list = new ArrayList(); + + LocalTime localTime = LocalTime.parse("12:00:00"); + LocalTime localSecondTime = LocalTime.parse("13:00:00"); + LocalTime localThirdTime = LocalTime.parse("14:00:00"); + list.add(localTime); + list.add(localSecondTime); + list.add(localThirdTime); + + LocalTimeList timeList = new LocalTimeList(list); + this.protostuffObjectOutput.writeObject(timeList); + this.flushToInput(); + + LocalTimeList serializedTime = protostuffObjectInput.readObject(LocalTimeList.class); + assertThat(serializedTime, is(timeList)); } @Test public void testListObject() throws IOException, ClassNotFoundException { + List list = new ArrayList(); + list.add(new SerializablePerson()); list.add(new SerializablePerson()); list.add(new SerializablePerson()); + SerializablePersonList personList = new SerializablePersonList(list); + this.protostuffObjectOutput.writeObject(personList); this.flushToInput(); @@ -108,13 +143,34 @@ public void testListObject() throws IOException, ClassNotFoundException { assertThat(serializedTime, is(personList)); } + + @Test + public void testSerializeSqlTime() throws IOException, ClassNotFoundException { + java.sql.Time originTime = new java.sql.Time(System.currentTimeMillis()); + this.protostuffObjectOutput.writeObject(originTime); + this.flushToInput(); + + java.sql.Time serializedTime = protostuffObjectInput.readObject(java.sql.Time.class); + assertThat(serializedTime, is(originTime)); + } + + @Test + public void testSerializeDate() throws IOException, ClassNotFoundException { + Date originTime = new Date(); + this.protostuffObjectOutput.writeObject(originTime); + this.flushToInput(); + + Date serializedTime = protostuffObjectInput.readObject(Date.class); + assertThat(serializedTime, is(originTime)); + } + private void flushToInput() throws IOException { this.protostuffObjectOutput.flushBuffer(); this.byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); this.protostuffObjectInput = new ProtostuffObjectInput(byteArrayInputStream); } - private class SerializablePersonList implements Serializable { + private static class SerializablePersonList implements Serializable { private static final long serialVersionUID = 1L; public List personList; @@ -148,4 +204,39 @@ public boolean equals(Object obj) { return true; } } + + private static class LocalTimeList implements Serializable { + private static final long serialVersionUID = 1L; + + List timeList; + + public LocalTimeList() {} + + public LocalTimeList(List timeList) { + this.timeList = timeList; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + + LocalTimeList timeList = (LocalTimeList) obj; + if (timeList.timeList == null && this.timeList == null) + return true; + if (timeList.timeList == null || this.timeList == null) + return false; + if (timeList.timeList.size() != this.timeList.size()) + return false; + for (int i =0; i < this.timeList.size(); i++) { + if (!this.timeList.get(i).equals(timeList.timeList.get(i))) + return false; + } + return true; + } + } }