From 61db8e9f1ebe01412f26bb90d63af7663db49a3d Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 8 Jul 2016 12:20:49 +0200 Subject: [PATCH] DigestUtils processes InputStream with buffered read instead of full copy Issue: SPR-14427 --- .../org/springframework/util/DigestUtils.java | 21 +++++++----- .../util/DigestUtilsTests.java | 32 +++++++++++++++---- 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/util/DigestUtils.java b/spring-core/src/main/java/org/springframework/util/DigestUtils.java index 6251c7aa96..36b1a583c8 100644 --- a/spring-core/src/main/java/org/springframework/util/DigestUtils.java +++ b/spring-core/src/main/java/org/springframework/util/DigestUtils.java @@ -23,11 +23,13 @@ import java.security.NoSuchAlgorithmException; /** * Miscellaneous methods for calculating digests. + * *

Mainly for internal use within the framework; consider * Apache Commons Codec * for a more comprehensive suite of digest utilities. * * @author Arjen Poutsma + * @author Juergen Hoeller * @author Craig Andrews * @since 3.0 */ @@ -49,8 +51,8 @@ public abstract class DigestUtils { } /** - * Calculate the MD5 digest of the given InputStream. - * @param inputStream the inputStream to calculate the digest over + * Calculate the MD5 digest of the given stream. + * @param inputStream the InputStream to calculate the digest over * @return the digest * @since 4.2 */ @@ -59,8 +61,7 @@ public abstract class DigestUtils { } /** - * Return a hexadecimal string representation of the MD5 digest of the given - * bytes. + * Return a hexadecimal string representation of the MD5 digest of the given bytes. * @param bytes the bytes to calculate the digest over * @return a hexadecimal digest string */ @@ -69,9 +70,8 @@ public abstract class DigestUtils { } /** - * Return a hexadecimal string representation of the MD5 digest of the given - * inputStream. - * @param inputStream the inputStream to calculate the digest over + * Return a hexadecimal string representation of the MD5 digest of the given stream. + * @param inputStream the InputStream to calculate the digest over * @return a hexadecimal digest string * @since 4.2 */ @@ -127,7 +127,12 @@ public abstract class DigestUtils { return messageDigest.digest(); } else { - return messageDigest.digest(StreamUtils.copyToByteArray(inputStream)); + final byte[] buffer = new byte[StreamUtils.BUFFER_SIZE]; + int bytesRead = -1; + while ((bytesRead = inputStream.read(buffer)) != -1) { + messageDigest.update(buffer, 0, bytesRead); + } + return messageDigest.digest(); } } diff --git a/spring-core/src/test/java/org/springframework/util/DigestUtilsTests.java b/spring-core/src/test/java/org/springframework/util/DigestUtilsTests.java index 6842bfee1d..5db3ea51b3 100644 --- a/spring-core/src/test/java/org/springframework/util/DigestUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/util/DigestUtilsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,8 @@ package org.springframework.util; +import java.io.ByteArrayInputStream; +import java.io.IOException; import java.io.UnsupportedEncodingException; import org.junit.Before; @@ -25,6 +27,7 @@ import static org.junit.Assert.*; /** * @author Arjen Poutsma + * @author Juergen Hoeller */ public class DigestUtilsTests { @@ -38,24 +41,39 @@ public class DigestUtilsTests { @Test - public void md5() { - byte[] result = DigestUtils.md5Digest(bytes); + public void md5() throws IOException { byte[] expected = new byte[] {-0x4f, 0xa, -0x73, -0x4f, 0x64, -0x20, 0x75, 0x41, 0x5, -0x49, -0x57, -0x65, -0x19, 0x2e, 0x3f, -0x1b}; + + byte[] result = DigestUtils.md5Digest(bytes); + assertArrayEquals("Invalid hash", expected, result); + + result = DigestUtils.md5Digest(new ByteArrayInputStream(bytes)); assertArrayEquals("Invalid hash", expected, result); } @Test - public void md5Hex() throws UnsupportedEncodingException { + public void md5Hex() throws IOException { + String expected = "b10a8db164e0754105b7a99be72e3fe5"; + String hash = DigestUtils.md5DigestAsHex(bytes); - assertEquals("Invalid hash", "b10a8db164e0754105b7a99be72e3fe5", hash); + assertEquals("Invalid hash", expected, hash); + + hash = DigestUtils.md5DigestAsHex(new ByteArrayInputStream(bytes)); + assertEquals("Invalid hash", expected, hash); } @Test - public void md5StringBuilder() throws UnsupportedEncodingException { + public void md5StringBuilder() throws IOException { + String expected = "b10a8db164e0754105b7a99be72e3fe5"; + StringBuilder builder = new StringBuilder(); DigestUtils.appendMd5DigestAsHex(bytes, builder); - assertEquals("Invalid hash", "b10a8db164e0754105b7a99be72e3fe5", builder.toString()); + assertEquals("Invalid hash", expected, builder.toString()); + + builder = new StringBuilder(); + DigestUtils.appendMd5DigestAsHex(new ByteArrayInputStream(bytes), builder); + assertEquals("Invalid hash", expected, builder.toString()); } }