PageRenderTime 45ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/core/petra/petra-io/src/test/java/com/liferay/petra/io/DeserializerTest.java

http://github.com/liferay/liferay-portal
Java | 746 lines | 489 code | 240 blank | 17 comment | 25 complexity | be5948e1580441b7baad7371938ebe81 MD5 | raw file
Possible License(s): LGPL-2.0
  1. /**
  2. * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
  3. *
  4. * This library is free software; you can redistribute it and/or modify it under
  5. * the terms of the GNU Lesser General Public License as published by the Free
  6. * Software Foundation; either version 2.1 of the License, or (at your option)
  7. * any later version.
  8. *
  9. * This library is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  11. * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  12. * details.
  13. */
  14. package com.liferay.petra.io;
  15. import com.liferay.petra.io.constants.SerializationConstants;
  16. import com.liferay.petra.io.unsync.UnsyncByteArrayOutputStream;
  17. import com.liferay.petra.lang.ClassLoaderPool;
  18. import com.liferay.petra.string.StringPool;
  19. import com.liferay.portal.kernel.test.ReflectionTestUtil;
  20. import com.liferay.portal.kernel.test.rule.AggregateTestRule;
  21. import com.liferay.portal.kernel.test.rule.CodeCoverageAssertor;
  22. import com.liferay.portal.test.rule.LiferayUnitTestRule;
  23. import java.io.ObjectOutputStream;
  24. import java.io.StreamCorruptedException;
  25. import java.lang.reflect.Constructor;
  26. import java.lang.reflect.InvocationTargetException;
  27. import java.lang.reflect.Method;
  28. import java.nio.ByteBuffer;
  29. import java.nio.ByteOrder;
  30. import java.nio.CharBuffer;
  31. import java.nio.DoubleBuffer;
  32. import java.nio.FloatBuffer;
  33. import java.nio.IntBuffer;
  34. import java.nio.LongBuffer;
  35. import java.nio.ShortBuffer;
  36. import java.util.Date;
  37. import java.util.List;
  38. import java.util.Random;
  39. import org.junit.Assert;
  40. import org.junit.ClassRule;
  41. import org.junit.Rule;
  42. import org.junit.Test;
  43. /**
  44. * @author Shuyang Zhou
  45. */
  46. public class DeserializerTest {
  47. @ClassRule
  48. @Rule
  49. public static final AggregateTestRule aggregateTestRule =
  50. new AggregateTestRule(
  51. new CodeCoverageAssertor() {
  52. @Override
  53. public void appendAssertClasses(List<Class<?>> assertClasses) {
  54. assertClasses.add(AnnotatedObjectOutputStream.class);
  55. assertClasses.add(
  56. ProtectedAnnotatedObjectInputStream.class);
  57. }
  58. },
  59. LiferayUnitTestRule.INSTANCE);
  60. @Test
  61. public void testBufferInputStream() throws Exception {
  62. byte[] data = new byte[_COUNT];
  63. _random.nextBytes(data);
  64. Deserializer deserializer = new Deserializer(ByteBuffer.wrap(data));
  65. BufferInputStream bufferInputStream = new BufferInputStream(
  66. deserializer);
  67. for (int i = 0; i < _COUNT; i++) {
  68. Assert.assertEquals(data[i], bufferInputStream.read());
  69. }
  70. deserializer = new Deserializer(ByteBuffer.wrap(data));
  71. bufferInputStream = new BufferInputStream(deserializer);
  72. int size1 = _COUNT * 2 / 3;
  73. int size2 = _COUNT - size1;
  74. byte[] newBytes = new byte[size1];
  75. int count = bufferInputStream.read(newBytes);
  76. Assert.assertEquals(size1, count);
  77. for (int i = 0; i < size1; i++) {
  78. Assert.assertEquals(data[i], newBytes[i]);
  79. }
  80. newBytes = new byte[size1];
  81. count = bufferInputStream.read(newBytes);
  82. Assert.assertEquals(size2, count);
  83. for (int i = 0; i < size2; i++) {
  84. Assert.assertEquals(data[i + size1], newBytes[i]);
  85. }
  86. }
  87. @Test
  88. public void testDetectBufferUnderflow() throws Exception {
  89. Method detectBufferUnderflowMethod = ReflectionTestUtil.getMethod(
  90. Deserializer.class, "_detectBufferUnderflow", int.class);
  91. ByteBuffer byteBuffer = ByteBuffer.allocate(4);
  92. Deserializer deserializer = new Deserializer(byteBuffer);
  93. detectBufferUnderflowMethod.invoke(deserializer, 4);
  94. try {
  95. detectBufferUnderflowMethod.invoke(deserializer, 5);
  96. Assert.fail();
  97. }
  98. catch (InvocationTargetException invocationTargetException) {
  99. Throwable throwable = invocationTargetException.getCause();
  100. Assert.assertTrue(
  101. throwable.toString(),
  102. throwable instanceof IllegalStateException);
  103. Assert.assertEquals("Buffer underflow", throwable.getMessage());
  104. }
  105. }
  106. @Test
  107. public void testReadBoolean() {
  108. byte[] bytes = new byte[_COUNT];
  109. for (int i = 0; i < _COUNT; i++) {
  110. bytes[i] = _random.nextBoolean() ? (byte)1 : (byte)0;
  111. }
  112. ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
  113. Deserializer deserializer = new Deserializer(byteBuffer);
  114. for (int i = 0; i < _COUNT; i++) {
  115. if (bytes[i] == 0) {
  116. Assert.assertFalse(deserializer.readBoolean());
  117. }
  118. else {
  119. Assert.assertTrue(deserializer.readBoolean());
  120. }
  121. }
  122. }
  123. @Test
  124. public void testReadByte() {
  125. byte[] bytes = new byte[_COUNT];
  126. _random.nextBytes(bytes);
  127. ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
  128. Deserializer deserializer = new Deserializer(byteBuffer);
  129. for (int i = 0; i < _COUNT; i++) {
  130. Assert.assertEquals(bytes[i], deserializer.readByte());
  131. }
  132. }
  133. @Test
  134. public void testReadChar() {
  135. ByteBuffer byteBuffer = ByteBuffer.allocate(_COUNT * 2);
  136. byteBuffer.order(ByteOrder.BIG_ENDIAN);
  137. CharBuffer charBuffer = byteBuffer.asCharBuffer();
  138. char[] chars = new char[_COUNT];
  139. for (int i = 0; i < _COUNT; i++) {
  140. chars[i] = (char)_random.nextInt();
  141. charBuffer.put(chars[i]);
  142. }
  143. Deserializer deserializer = new Deserializer(byteBuffer);
  144. for (int i = 0; i < _COUNT; i++) {
  145. Assert.assertEquals(chars[i], deserializer.readChar());
  146. }
  147. }
  148. @Test
  149. public void testReadDouble() {
  150. ByteBuffer byteBuffer = ByteBuffer.allocate(_COUNT * 8);
  151. byteBuffer.order(ByteOrder.BIG_ENDIAN);
  152. DoubleBuffer doubleBuffer = byteBuffer.asDoubleBuffer();
  153. double[] doubles = new double[_COUNT];
  154. for (int i = 0; i < _COUNT; i++) {
  155. doubles[i] = _random.nextDouble();
  156. doubleBuffer.put(doubles[i]);
  157. }
  158. Deserializer deserializer = new Deserializer(byteBuffer);
  159. for (int i = 0; i < _COUNT; i++) {
  160. Assert.assertEquals(
  161. (Double)doubles[i], (Double)deserializer.readDouble());
  162. }
  163. }
  164. @Test
  165. public void testReadFloat() {
  166. ByteBuffer byteBuffer = ByteBuffer.allocate(_COUNT * 4);
  167. byteBuffer.order(ByteOrder.BIG_ENDIAN);
  168. FloatBuffer floatBuffer = byteBuffer.asFloatBuffer();
  169. float[] floats = new float[_COUNT];
  170. for (int i = 0; i < _COUNT; i++) {
  171. floats[i] = _random.nextFloat();
  172. floatBuffer.put(floats[i]);
  173. }
  174. Deserializer deserializer = new Deserializer(byteBuffer);
  175. for (int i = 0; i < _COUNT; i++) {
  176. Assert.assertEquals(
  177. (Float)floats[i], (Float)deserializer.readFloat());
  178. }
  179. }
  180. @Test
  181. public void testReadInt() {
  182. ByteBuffer byteBuffer = ByteBuffer.allocate(_COUNT * 4);
  183. byteBuffer.order(ByteOrder.BIG_ENDIAN);
  184. IntBuffer intBuffer = byteBuffer.asIntBuffer();
  185. int[] ints = new int[_COUNT];
  186. for (int i = 0; i < _COUNT; i++) {
  187. ints[i] = _random.nextInt();
  188. intBuffer.put(ints[i]);
  189. }
  190. Deserializer deserializer = new Deserializer(byteBuffer);
  191. for (int i = 0; i < _COUNT; i++) {
  192. Assert.assertEquals(ints[i], deserializer.readInt());
  193. }
  194. }
  195. @Test
  196. public void testReadLong() {
  197. ByteBuffer byteBuffer = ByteBuffer.allocate(_COUNT * 8);
  198. byteBuffer.order(ByteOrder.BIG_ENDIAN);
  199. LongBuffer longBuffer = byteBuffer.asLongBuffer();
  200. long[] longs = new long[_COUNT];
  201. for (int i = 0; i < _COUNT; i++) {
  202. longs[i] = _random.nextLong();
  203. longBuffer.put(longs[i]);
  204. }
  205. Deserializer deserializer = new Deserializer(byteBuffer);
  206. for (int i = 0; i < _COUNT; i++) {
  207. Assert.assertEquals(longs[i], deserializer.readLong());
  208. }
  209. }
  210. @Test
  211. public void testReadObjectBoolean() throws ClassNotFoundException {
  212. ByteBuffer byteBuffer = ByteBuffer.allocate(2);
  213. byteBuffer.put(SerializationConstants.TC_BOOLEAN);
  214. byteBuffer.put((byte)1);
  215. byteBuffer.flip();
  216. Deserializer deserializer = new Deserializer(byteBuffer);
  217. Object object = deserializer.readObject();
  218. Assert.assertTrue(object instanceof Boolean);
  219. Assert.assertSame(Boolean.TRUE, object);
  220. }
  221. @Test
  222. public void testReadObjectByte() throws ClassNotFoundException {
  223. ByteBuffer byteBuffer = ByteBuffer.allocate(2);
  224. byteBuffer.put(SerializationConstants.TC_BYTE);
  225. byteBuffer.put((byte)101);
  226. byteBuffer.flip();
  227. Deserializer deserializer = new Deserializer(byteBuffer);
  228. Object object = deserializer.readObject();
  229. Assert.assertTrue(object instanceof Byte);
  230. Assert.assertSame(Byte.valueOf((byte)101), object);
  231. }
  232. @Test
  233. public void testReadObjectCharacter() throws ClassNotFoundException {
  234. ByteBuffer byteBuffer = ByteBuffer.allocate(3);
  235. byteBuffer.put(SerializationConstants.TC_CHARACTER);
  236. byteBuffer.putChar('a');
  237. byteBuffer.flip();
  238. Deserializer deserializer = new Deserializer(byteBuffer);
  239. Object object = deserializer.readObject();
  240. Assert.assertTrue(object instanceof Character);
  241. Assert.assertSame('a', object);
  242. }
  243. @Test
  244. public void testReadObjectClassWithBlankContextName() throws Exception {
  245. Class<?> clazz = getClass();
  246. String className = clazz.getName();
  247. ByteBuffer byteBuffer = ByteBuffer.allocate(className.length() + 11);
  248. byteBuffer.put(SerializationConstants.TC_CLASS);
  249. byteBuffer.put((byte)1);
  250. byteBuffer.putInt(0);
  251. byteBuffer.put((byte)1);
  252. byteBuffer.putInt(className.length());
  253. byteBuffer.put(className.getBytes(StringPool.UTF8));
  254. byteBuffer.flip();
  255. Deserializer deserializer = new Deserializer(byteBuffer);
  256. ClassLoaderPool.register(StringPool.BLANK, clazz.getClassLoader());
  257. try {
  258. Assert.assertSame(clazz, deserializer.readObject());
  259. }
  260. finally {
  261. ClassLoaderPool.unregister(clazz.getClassLoader());
  262. }
  263. }
  264. @Test
  265. public void testReadObjectClassWithNullContextName() throws Exception {
  266. Class<?> clazz = getClass();
  267. String className = clazz.getName();
  268. String contextName = StringPool.NULL;
  269. ByteBuffer byteBuffer = ByteBuffer.allocate(
  270. className.length() + contextName.length() + 11);
  271. byteBuffer.put(SerializationConstants.TC_CLASS);
  272. byteBuffer.put((byte)1);
  273. byteBuffer.putInt(contextName.length());
  274. byteBuffer.put(contextName.getBytes(StringPool.UTF8));
  275. byteBuffer.put((byte)1);
  276. byteBuffer.putInt(className.length());
  277. byteBuffer.put(className.getBytes(StringPool.UTF8));
  278. byteBuffer.flip();
  279. Deserializer deserializer = new Deserializer(byteBuffer);
  280. Class<?> readClass = deserializer.readObject();
  281. Assert.assertSame(clazz, readClass);
  282. }
  283. @Test
  284. public void testReadObjectDouble() throws ClassNotFoundException {
  285. ByteBuffer byteBuffer = ByteBuffer.allocate(9);
  286. byteBuffer.put(SerializationConstants.TC_DOUBLE);
  287. byteBuffer.putDouble(17.58D);
  288. byteBuffer.flip();
  289. Deserializer deserializer = new Deserializer(byteBuffer);
  290. Object object = deserializer.readObject();
  291. Assert.assertTrue(object instanceof Double);
  292. Assert.assertEquals(17.58D, object);
  293. }
  294. @Test
  295. public void testReadObjectFloat() throws ClassNotFoundException {
  296. ByteBuffer byteBuffer = ByteBuffer.allocate(5);
  297. byteBuffer.put(SerializationConstants.TC_FLOAT);
  298. byteBuffer.putFloat(17.58F);
  299. byteBuffer.flip();
  300. Deserializer deserializer = new Deserializer(byteBuffer);
  301. Object object = deserializer.readObject();
  302. Assert.assertTrue(object instanceof Float);
  303. Assert.assertEquals(17.58F, object);
  304. }
  305. @Test
  306. public void testReadObjectInteger() throws ClassNotFoundException {
  307. ByteBuffer byteBuffer = ByteBuffer.allocate(5);
  308. byteBuffer.put(SerializationConstants.TC_INTEGER);
  309. byteBuffer.putInt(101);
  310. byteBuffer.flip();
  311. Deserializer deserializer = new Deserializer(byteBuffer);
  312. Object object = deserializer.readObject();
  313. Assert.assertTrue(object instanceof Integer);
  314. Assert.assertSame(101, object);
  315. }
  316. @Test
  317. public void testReadObjectLong() throws ClassNotFoundException {
  318. ByteBuffer byteBuffer = ByteBuffer.allocate(9);
  319. byteBuffer.put(SerializationConstants.TC_LONG);
  320. byteBuffer.putLong(101);
  321. byteBuffer.flip();
  322. Deserializer deserializer = new Deserializer(byteBuffer);
  323. Object object = deserializer.readObject();
  324. Assert.assertTrue(object instanceof Long);
  325. Assert.assertSame(Long.valueOf(101), object);
  326. }
  327. @Test
  328. public void testReadObjectNull() throws ClassNotFoundException {
  329. ByteBuffer byteBuffer = ByteBuffer.allocate(1);
  330. byteBuffer.put(SerializationConstants.TC_NULL);
  331. byteBuffer.flip();
  332. Deserializer deserializer = new Deserializer(byteBuffer);
  333. Object object = deserializer.readObject();
  334. Assert.assertNull(object);
  335. }
  336. @Test
  337. public void testReadObjectOrdinary() throws Exception {
  338. UnsyncByteArrayOutputStream unsyncByteArrayOutputStream =
  339. new UnsyncByteArrayOutputStream();
  340. unsyncByteArrayOutputStream.write(SerializationConstants.TC_OBJECT);
  341. ObjectOutputStream objectOutputStream = new AnnotatedObjectOutputStream(
  342. unsyncByteArrayOutputStream);
  343. Date date = new Date(123456);
  344. objectOutputStream.writeObject(date);
  345. ByteBuffer byteBuffer =
  346. unsyncByteArrayOutputStream.unsafeGetByteBuffer();
  347. Deserializer deserializer = new Deserializer(byteBuffer);
  348. Object object = deserializer.readObject();
  349. Assert.assertTrue(object instanceof Date);
  350. Assert.assertEquals(date, object);
  351. }
  352. @Test
  353. public void testReadObjectOrdinaryNPE() throws Exception {
  354. UnsyncByteArrayOutputStream unsyncByteArrayOutputStream =
  355. new UnsyncByteArrayOutputStream();
  356. unsyncByteArrayOutputStream.write(SerializationConstants.TC_OBJECT);
  357. unsyncByteArrayOutputStream.write(1);
  358. unsyncByteArrayOutputStream.write(new byte[4]);
  359. ObjectOutputStream objectOutputStream = new ObjectOutputStream(
  360. unsyncByteArrayOutputStream);
  361. Date date = new Date(123456);
  362. objectOutputStream.writeObject(date);
  363. ByteBuffer byteBuffer =
  364. unsyncByteArrayOutputStream.unsafeGetByteBuffer();
  365. // Corrupt magic header
  366. byteBuffer.put(6, (byte)0xFF);
  367. Deserializer deserializer = new Deserializer(byteBuffer);
  368. try {
  369. deserializer.readObject();
  370. Assert.fail();
  371. }
  372. catch (RuntimeException runtimeException) {
  373. Assert.assertTrue(
  374. runtimeException.getCause() instanceof
  375. StreamCorruptedException);
  376. }
  377. }
  378. @Test
  379. public void testReadObjectShort() throws ClassNotFoundException {
  380. ByteBuffer byteBuffer = ByteBuffer.allocate(3);
  381. byteBuffer.put(SerializationConstants.TC_SHORT);
  382. byteBuffer.putShort((short)101);
  383. byteBuffer.flip();
  384. Deserializer deserializer = new Deserializer(byteBuffer);
  385. Object object = deserializer.readObject();
  386. Assert.assertTrue(object instanceof Short);
  387. Assert.assertSame((short)101, object);
  388. }
  389. @Test
  390. public void testReadObjectString() throws ClassNotFoundException {
  391. String asciiString = "abcdefghijklmn";
  392. byte[] buffer = new byte[asciiString.length() + 6];
  393. buffer[0] = SerializationConstants.TC_STRING;
  394. buffer[1] = 1;
  395. BigEndianCodec.putInt(buffer, 2, asciiString.length());
  396. for (int i = 0; i < asciiString.length(); i++) {
  397. buffer[6 + i] = (byte)asciiString.charAt(i);
  398. }
  399. ByteBuffer byteBuffer = ByteBuffer.wrap(buffer);
  400. Deserializer deserializer = new Deserializer(byteBuffer);
  401. Object object = deserializer.readObject();
  402. Assert.assertTrue(object instanceof String);
  403. Assert.assertEquals(asciiString, object);
  404. String nonasciiString = "非ASCII Code中文测试";
  405. buffer = new byte[(nonasciiString.length() * 2) + 6];
  406. buffer[0] = SerializationConstants.TC_STRING;
  407. buffer[1] = 0;
  408. BigEndianCodec.putInt(buffer, 2, nonasciiString.length());
  409. for (int i = 0; i < nonasciiString.length(); i++) {
  410. BigEndianCodec.putChar(
  411. buffer, 6 + (i * 2), nonasciiString.charAt(i));
  412. }
  413. byteBuffer = ByteBuffer.wrap(buffer);
  414. deserializer = new Deserializer(byteBuffer);
  415. object = deserializer.readObject();
  416. Assert.assertTrue(object instanceof String);
  417. Assert.assertEquals(nonasciiString, object);
  418. }
  419. @Test
  420. public void testReadObjectUnknowTCCode() throws ClassNotFoundException {
  421. ByteBuffer byteBuffer = ByteBuffer.allocate(1);
  422. byteBuffer.put((byte)12);
  423. Deserializer deserializer = new Deserializer(byteBuffer);
  424. try {
  425. deserializer.readObject();
  426. }
  427. catch (IllegalStateException illegalStateException) {
  428. Assert.assertEquals(
  429. "Unkown TC code 12", illegalStateException.getMessage());
  430. }
  431. }
  432. @Test
  433. public void testReadShort() {
  434. ByteBuffer byteBuffer = ByteBuffer.allocate(_COUNT * 2);
  435. byteBuffer.order(ByteOrder.BIG_ENDIAN);
  436. ShortBuffer shortBuffer = byteBuffer.asShortBuffer();
  437. short[] shorts = new short[_COUNT];
  438. for (int i = 0; i < _COUNT; i++) {
  439. shorts[i] = (short)_random.nextInt();
  440. shortBuffer.put(shorts[i]);
  441. }
  442. Deserializer deserializer = new Deserializer(byteBuffer);
  443. for (int i = 0; i < _COUNT; i++) {
  444. Assert.assertEquals(shorts[i], deserializer.readShort());
  445. }
  446. }
  447. @Test
  448. public void testReadString() {
  449. String asciiString = "abcdefghijklmn";
  450. byte[] buffer = new byte[asciiString.length() + 5];
  451. buffer[0] = 1;
  452. BigEndianCodec.putInt(buffer, 1, asciiString.length());
  453. for (int i = 0; i < asciiString.length(); i++) {
  454. buffer[5 + i] = (byte)asciiString.charAt(i);
  455. }
  456. ByteBuffer byteBuffer = ByteBuffer.wrap(buffer);
  457. Deserializer deserializer = new Deserializer(byteBuffer);
  458. String resultString = deserializer.readString();
  459. Assert.assertEquals(asciiString, resultString);
  460. String nonasciiString = "非ASCII Code中文测试";
  461. buffer = new byte[(nonasciiString.length() * 2) + 5];
  462. buffer[0] = 0;
  463. BigEndianCodec.putInt(buffer, 1, nonasciiString.length());
  464. for (int i = 0; i < nonasciiString.length(); i++) {
  465. BigEndianCodec.putChar(
  466. buffer, 5 + (i * 2), nonasciiString.charAt(i));
  467. }
  468. byteBuffer = ByteBuffer.wrap(buffer);
  469. deserializer = new Deserializer(byteBuffer);
  470. resultString = deserializer.readString();
  471. Assert.assertEquals(nonasciiString, resultString);
  472. }
  473. private static final int _COUNT = 1024;
  474. private final Random _random = new Random();
  475. private static class BufferInputStream {
  476. public int read() throws Exception {
  477. return (int)_readByteMethod.invoke(_bufferInputStream);
  478. }
  479. public int read(byte[] bytes) throws Exception {
  480. return (int)_readBytesMethod.invoke(
  481. _bufferInputStream, new Object[] {bytes});
  482. }
  483. private BufferInputStream(Deserializer deserializer) throws Exception {
  484. _bufferInputStream = _constructor.newInstance(deserializer);
  485. }
  486. private static final Constructor<?> _constructor;
  487. private static final Method _readByteMethod;
  488. private static final Method _readBytesMethod;
  489. static {
  490. try {
  491. Class<?> clazz = Class.forName(
  492. Deserializer.class.getName() + "$BufferInputStream");
  493. _constructor = clazz.getDeclaredConstructor(Deserializer.class);
  494. _constructor.setAccessible(true);
  495. _readByteMethod = ReflectionTestUtil.getMethod(clazz, "read");
  496. _readBytesMethod = ReflectionTestUtil.getMethod(
  497. clazz, "read", byte[].class);
  498. }
  499. catch (ReflectiveOperationException reflectiveOperationException) {
  500. throw new ExceptionInInitializerError(
  501. reflectiveOperationException);
  502. }
  503. }
  504. private final Object _bufferInputStream;
  505. }
  506. }