Yuta HIGUCHI
Committed by Yuta Higuchi

MapDBLog: clone byte[] before deserializing

- workaround for Kryo buffer underflow case
Change-Id: I0a9566f66fcd6fac3a91dda87f59d01fbed2d43a
...@@ -146,7 +146,7 @@ public class MapDBLog implements Log { ...@@ -146,7 +146,7 @@ public class MapDBLog implements Log {
146 DB db = txMaker.makeTx(); 146 DB db = txMaker.makeTx();
147 try { 147 try {
148 BTreeMap<Long, byte[]> log = getLogMap(db); 148 BTreeMap<Long, byte[]> log = getLogMap(db);
149 - return log.isEmpty() ? null : verifyNotNull(serializer.decode(log.firstEntry().getValue())); 149 + return log.isEmpty() ? null : verifyNotNull(decodeEntry(log.firstEntry().getValue()));
150 } finally { 150 } finally {
151 db.close(); 151 db.close();
152 } 152 }
...@@ -164,6 +164,13 @@ public class MapDBLog implements Log { ...@@ -164,6 +164,13 @@ public class MapDBLog implements Log {
164 } 164 }
165 } 165 }
166 166
167 + private <T extends Entry> T decodeEntry(final byte[] bytes) {
168 + if (bytes == null) {
169 + return null;
170 + }
171 + return serializer.decode(bytes.clone());
172 + }
173 +
167 @Override 174 @Override
168 public <T extends Entry> List<T> getEntries(long from, long to) { 175 public <T extends Entry> List<T> getEntries(long from, long to) {
169 assertIsOpen(); 176 assertIsOpen();
...@@ -179,7 +186,7 @@ public class MapDBLog implements Log { ...@@ -179,7 +186,7 @@ public class MapDBLog implements Log {
179 } 186 }
180 List<T> entries = new ArrayList<>((int) (to - from + 1)); 187 List<T> entries = new ArrayList<>((int) (to - from + 1));
181 for (long i = from; i <= to; i++) { 188 for (long i = from; i <= to; i++) {
182 - T entry = verifyNotNull(serializer.decode(log.get(i)), "LogEntry %s was null", i); 189 + T entry = verifyNotNull(decodeEntry(log.get(i)), "LogEntry %s was null", i);
183 entries.add(entry); 190 entries.add(entry);
184 } 191 }
185 return entries; 192 return entries;
...@@ -195,7 +202,7 @@ public class MapDBLog implements Log { ...@@ -195,7 +202,7 @@ public class MapDBLog implements Log {
195 try { 202 try {
196 BTreeMap<Long, byte[]> log = getLogMap(db); 203 BTreeMap<Long, byte[]> log = getLogMap(db);
197 byte[] entryBytes = log.get(index); 204 byte[] entryBytes = log.get(index);
198 - return entryBytes == null ? null : verifyNotNull(serializer.decode(entryBytes), 205 + return entryBytes == null ? null : verifyNotNull(decodeEntry(entryBytes),
199 "LogEntry %s was null", index); 206 "LogEntry %s was null", index);
200 } finally { 207 } finally {
201 db.close(); 208 db.close();
...@@ -220,7 +227,7 @@ public class MapDBLog implements Log { ...@@ -220,7 +227,7 @@ public class MapDBLog implements Log {
220 DB db = txMaker.makeTx(); 227 DB db = txMaker.makeTx();
221 try { 228 try {
222 BTreeMap<Long, byte[]> log = getLogMap(db); 229 BTreeMap<Long, byte[]> log = getLogMap(db);
223 - return log.isEmpty() ? null : verifyNotNull(serializer.decode(log.lastEntry().getValue())); 230 + return log.isEmpty() ? null : verifyNotNull(decodeEntry(log.lastEntry().getValue()));
224 } finally { 231 } finally {
225 db.close(); 232 db.close();
226 } 233 }
......