Index: base/md5_unittest.cc |
diff --git a/base/md5_unittest.cc b/base/md5_unittest.cc |
index 1112c4b4258d21eb13bc4a55a0fc5a6d06ef8526..46d15134a1a3b3ba5ed99e99c10c7e06c1ae3c90 100644 |
--- a/base/md5_unittest.cc |
+++ b/base/md5_unittest.cc |
@@ -204,4 +204,53 @@ TEST(MD5, ContextWithStringData) { |
EXPECT_EQ(expected, actual); |
} |
+// Test that a cloned context gives the same digest as an uncloned context, and |
+// also that the cloned-from context gives the same digest as a context which |
+// was never cloned. |
+TEST(MD5, Clone) { |
+ // Independent context over the header. |
+ MD5Context check_header_context; |
+ MD5Init(&check_header_context); |
+ |
+ // Independent context over entire input. |
+ MD5Context check_full_context; |
+ MD5Init(&check_full_context); |
+ |
+ // Context will be cloned after header. |
+ MD5Context context; |
+ MD5Init(&context); |
+ |
+ const char kHeader[] = "header data"; |
+ const char kBody[] = "payload data"; |
+ |
+ MD5Update(&context, kHeader); |
+ MD5Update(&check_header_context, kHeader); |
+ MD5Update(&check_full_context, kHeader); |
+ |
+ MD5Digest check_header_digest; |
+ MD5Final(&check_header_digest, &check_header_context); |
+ |
+ MD5Context clone_context; |
+ MD5Clone(&clone_context, &context); |
+ |
+ MD5Digest clone_digest; |
+ MD5Final(&clone_digest, &clone_context); |
+ |
+ MD5Update(&context, kBody); |
+ MD5Update(&check_full_context, kBody); |
+ |
+ MD5Digest check_full_digest; |
+ MD5Final(&check_full_digest, &check_full_context); |
+ |
+ MD5Digest digest; |
+ MD5Final(&digest, &context); |
+ |
+ // The header and full digest pairs are the same, and they aren't the same as |
+ // each other. |
+ EXPECT_TRUE(!memcmp(&check_header_digest, &clone_digest, |
+ sizeof(check_header_digest))); |
+ EXPECT_TRUE(!memcmp(&digest, &check_full_digest, sizeof(digest))); |
+ EXPECT_FALSE(!memcmp(&digest, &clone_digest, sizeof(digest))); |
+} |
+ |
} // namespace base |