subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From stef...@apache.org
Subject svn commit: r1515049 - in /subversion/branches/log-addressing/subversion: libsvn_subr/ tests/libsvn_subr/
Date Sat, 17 Aug 2013 23:20:28 GMT
Author: stefan2
Date: Sat Aug 17 23:20:28 2013
New Revision: 1515049

URL: http://svn.apache.org/r1515049
Log:
In preparation of the addition of support for FNV-1a checksums, clean up
the existing svn_checksum_t implementations for MD5 and SHA1.

This includes eliminating duplicate digest conversion and matching code.
Also, make the API implementation and test code much more generic to
make it simple to add more checksum kinds.  As a result, the sha1.*
files as well as md5.h are are obsolete now.

* subversion/libsvn_subr/checksum.h
  (): new file
  (svn__empty_string_digest,
   svn__digest_to_cstring_display,
   svn__digest_to_cstring,
   svn__digests_match): declare new, generic replacements of the similarly
                        named MD5 / SHA1 functions

* subversion/libsvn_subr/checksum.c
  (md5_empty_string_digest_array,
   sha1_empty_string_digest_array): declare empty digests taken from former
                                    specific implementations
  (empty_string_digests,
   digest_sizes): constants addressable by checksum kind
  (DIGESTSIZE): switch definition to ranges instead of enumeration
  (MAX_DIGESTSIZE): new definition
  (svn__empty_string_digest,
   svn__digest_to_cstring_display,
   svn__digest_to_cstring,
   svn__digests_match): implement taking previous copy-n-paste code
  (svn_checksum_create,
   svn_checksum_match,
   svn_checksum_to_cstring_display,
   svn_checksum_to_cstring,
   svn_checksum_dup,
   svn_checksum_empty_checksum,
   svn_checksum_is_empty_checksum): simplify using the new generics
  (svn_checksum_serialize): check for valid range instead of individual kinds

* subversion/libsvn_subr/md5.c
  (svn_md5__empty_string_digest_array,
   svn_md5__empty_string_digest,
   svn_md5__digest_to_cstring_display,
   svn_md5__digest_to_cstring,
   svn_md5__digests_match): drop MD5-specific code & definitions
  (svn_md5_empty_string_digest,
   svn_md5_digest_to_cstring_display,
   svn_md5_digest_to_cstring,
   svn_md5_digests_match): implement in terms of the new generic functions

* subversion/tests/libsvn_subr/checksum-test.c
  (checksum_parse_kind): factored out generic part of ...
  (test_checksum_parse): ... this one
  (test_checksum_empty): replace unrolled code with loop over checksum kinds
  (zero_match_kind):  factored out generic part of ...
  (zero_match): ... this one; restrict to single checksum types
  (zero_cross_match): new test covering the cross-kind checks
  (test_funcs): register new test

* subversion/libsvn_subr/cache-membuffer.c
  (): remove unneeded #include

* subversion/libsvn_subr/md5.h,
  subversion/libsvn_subr/sha1.c,
  subversion/libsvn_subr/sha1.h: drop

Added:
    subversion/branches/log-addressing/subversion/libsvn_subr/checksum.h
Removed:
    subversion/branches/log-addressing/subversion/libsvn_subr/md5.h
    subversion/branches/log-addressing/subversion/libsvn_subr/sha1.c
    subversion/branches/log-addressing/subversion/libsvn_subr/sha1.h
Modified:
    subversion/branches/log-addressing/subversion/libsvn_subr/cache-membuffer.c
    subversion/branches/log-addressing/subversion/libsvn_subr/checksum.c
    subversion/branches/log-addressing/subversion/libsvn_subr/md5.c
    subversion/branches/log-addressing/subversion/tests/libsvn_subr/checksum-test.c

Modified: subversion/branches/log-addressing/subversion/libsvn_subr/cache-membuffer.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_subr/cache-membuffer.c?rev=1515049&r1=1515048&r2=1515049&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_subr/cache-membuffer.c (original)
+++ subversion/branches/log-addressing/subversion/libsvn_subr/cache-membuffer.c Sat Aug 17
23:20:28 2013
@@ -27,7 +27,6 @@
 
 #include "svn_pools.h"
 #include "svn_checksum.h"
-#include "md5.h"
 #include "svn_private_config.h"
 #include "cache.h"
 #include "svn_string.h"

Modified: subversion/branches/log-addressing/subversion/libsvn_subr/checksum.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_subr/checksum.c?rev=1515049&r1=1515048&r2=1515049&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_subr/checksum.c (original)
+++ subversion/branches/log-addressing/subversion/libsvn_subr/checksum.c Sat Aug 17 23:20:28
2013
@@ -21,6 +21,7 @@
  * ====================================================================
  */
 
+#define APR_WANT_BYTEFUNC
 
 #include <ctype.h>
 
@@ -30,9 +31,9 @@
 #include "svn_checksum.h"
 #include "svn_error.h"
 #include "svn_ctype.h"
+#include "svn_sorts.h"
 
-#include "sha1.h"
-#include "md5.h"
+#include "checksum.h"
 
 #include "private/svn_subr_private.h"
 
@@ -40,10 +41,88 @@
 
 
 
+/* The MD5 digest for the empty string. */
+static const unsigned char md5_empty_string_digest_array[] = {
+  0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
+  0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e
+};
+
+/* The SHA1 digest for the empty string. */
+static const unsigned char sha1_empty_string_digest_array[] = {
+  0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55,
+  0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09
+};
+
+/* Digests for an empty string, indexed by checksum type */
+static const unsigned char * empty_string_digests[] = {
+  md5_empty_string_digest_array,
+  sha1_empty_string_digest_array
+};
+
+/* Digest sizes in bytes, indexed by checksum type */
+static const apr_size_t digest_sizes[] = {
+  APR_MD5_DIGESTSIZE,
+  APR_SHA1_DIGESTSIZE
+};
+
 /* Returns the digest size of it's argument. */
-#define DIGESTSIZE(k) ((k) == svn_checksum_md5 ? APR_MD5_DIGESTSIZE : \
-                       (k) == svn_checksum_sha1 ? APR_SHA1_DIGESTSIZE : 0)
+#define DIGESTSIZE(k) \
+  (((k) < svn_checksum_md5 || (k) > svn_checksum_sha1) ? 0 : digest_sizes[k])
+
+/* Largest supported digest size */
+#define MAX_DIGESTSIZE (MAX(APR_MD5_DIGESTSIZE,APR_SHA1_DIGESTSIZE))
+
+const unsigned char *
+svn__empty_string_digest(svn_checksum_kind_t kind)
+{
+  return empty_string_digests[kind];
+}
+
+const char *
+svn__digest_to_cstring_display(const unsigned char digest[],
+                               apr_size_t digest_size,
+                               apr_pool_t *pool)
+{
+  static const char *hex = "0123456789abcdef";
+  char *str = apr_palloc(pool, (digest_size * 2) + 1);
+  int i;
+
+  for (i = 0; i < digest_size; i++)
+    {
+      str[i*2]   = hex[digest[i] >> 4];
+      str[i*2+1] = hex[digest[i] & 0x0f];
+    }
+  str[i*2] = '\0';
+
+  return str;
+}
+
 
+const char *
+svn__digest_to_cstring(const unsigned char digest[],
+                       apr_size_t digest_size,
+                       apr_pool_t *pool)
+{
+  static const unsigned char zeros_digest[MAX_DIGESTSIZE] = { 0 };
+
+  if (memcmp(digest, zeros_digest, digest_size) != 0)
+    return svn__digest_to_cstring_display(digest, digest_size, pool);
+  else
+    return NULL;
+}
+
+
+svn_boolean_t
+svn__digests_match(const unsigned char d1[],
+                   const unsigned char d2[],
+                   apr_size_t digest_size)
+{
+  static const unsigned char zeros[MAX_DIGESTSIZE] = { 0 };
+
+  return ((memcmp(d1, d2, digest_size) == 0)
+          || (memcmp(d2, zeros, digest_size) == 0)
+          || (memcmp(d1, zeros, digest_size) == 0));
+}
 
 /* Check to see if KIND is something we recognize.  If not, return
  * SVN_ERR_BAD_CHECKSUM_KIND */
@@ -93,11 +172,10 @@ svn_checksum_create(svn_checksum_kind_t 
   switch (kind)
     {
       case svn_checksum_md5:
-        digest_size = APR_MD5_DIGESTSIZE;
-        break;
       case svn_checksum_sha1:
-        digest_size = APR_SHA1_DIGESTSIZE;
+        digest_size = digest_sizes[kind];
         break;
+
       default:
         return NULL;
     }
@@ -145,9 +223,11 @@ svn_checksum_match(const svn_checksum_t 
   switch (checksum1->kind)
     {
       case svn_checksum_md5:
-        return svn_md5__digests_match(checksum1->digest, checksum2->digest);
       case svn_checksum_sha1:
-        return svn_sha1__digests_match(checksum1->digest, checksum2->digest);
+        return svn__digests_match(checksum1->digest,
+                                  checksum2->digest,
+                                  digest_sizes[checksum1->kind]);
+
       default:
         /* We really shouldn't get here, but if we do... */
         return FALSE;
@@ -161,9 +241,11 @@ svn_checksum_to_cstring_display(const sv
   switch (checksum->kind)
     {
       case svn_checksum_md5:
-        return svn_md5__digest_to_cstring_display(checksum->digest, pool);
       case svn_checksum_sha1:
-        return svn_sha1__digest_to_cstring_display(checksum->digest, pool);
+        return svn__digest_to_cstring_display(checksum->digest,
+                                              digest_sizes[checksum->kind],
+                                              pool);
+
       default:
         /* We really shouldn't get here, but if we do... */
         return NULL;
@@ -180,9 +262,11 @@ svn_checksum_to_cstring(const svn_checks
   switch (checksum->kind)
     {
       case svn_checksum_md5:
-        return svn_md5__digest_to_cstring(checksum->digest, pool);
       case svn_checksum_sha1:
-        return svn_sha1__digest_to_cstring(checksum->digest, pool);
+        return svn__digest_to_cstring(checksum->digest,
+                                      digest_sizes[checksum->kind],
+                                      pool);
+
       default:
         /* We really shouldn't get here, but if we do... */
         return NULL;
@@ -197,8 +281,8 @@ svn_checksum_serialize(const svn_checksu
 {
   const char *ckind_str;
 
-  SVN_ERR_ASSERT_NO_RETURN(checksum->kind == svn_checksum_md5
-                           || checksum->kind == svn_checksum_sha1);
+  SVN_ERR_ASSERT_NO_RETURN(checksum->kind >= svn_checksum_md5
+                           || checksum->kind <= svn_checksum_sha1);
   ckind_str = (checksum->kind == svn_checksum_md5 ? "$md5 $" : "$sha1$");
   return apr_pstrcat(result_pool,
                      ckind_str,
@@ -302,11 +386,12 @@ svn_checksum_dup(const svn_checksum_t *c
   switch (checksum->kind)
     {
       case svn_checksum_md5:
-        return svn_checksum__from_digest_md5(checksum->digest, pool);
-        break;
       case svn_checksum_sha1:
-        return svn_checksum__from_digest_sha1(checksum->digest, pool);
-        break;
+        return checksum_create(checksum->kind,
+                               digest_sizes[checksum->kind],
+                               checksum->digest,
+                               pool);
+
       default:
         SVN_ERR_MALFUNCTION_NO_RETURN();
         break;
@@ -353,12 +438,11 @@ svn_checksum_empty_checksum(svn_checksum
   switch (kind)
     {
       case svn_checksum_md5:
-        return svn_checksum__from_digest_md5(svn_md5__empty_string_digest(),
-                                             pool);
-
       case svn_checksum_sha1:
-        return svn_checksum__from_digest_sha1(svn_sha1__empty_string_digest(),
-                                              pool);
+        return checksum_create(kind,
+                               digest_sizes[kind],
+                               empty_string_digests[kind],
+                               pool);
 
       default:
         /* We really shouldn't get here, but if we do... */
@@ -486,12 +570,10 @@ svn_checksum_is_empty_checksum(svn_check
   switch (checksum->kind)
     {
       case svn_checksum_md5:
-        return svn_md5__digests_match(checksum->digest,
-                                      svn_md5__empty_string_digest());
-
       case svn_checksum_sha1:
-        return svn_sha1__digests_match(checksum->digest,
-                                       svn_sha1__empty_string_digest());
+        return svn__digests_match(checksum->digest,
+                                  svn__empty_string_digest(checksum->kind),
+                                  digest_sizes[checksum->kind]);
 
       default:
         /* We really shouldn't get here, but if we do... */

Added: subversion/branches/log-addressing/subversion/libsvn_subr/checksum.h
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_subr/checksum.h?rev=1515049&view=auto
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_subr/checksum.h (added)
+++ subversion/branches/log-addressing/subversion/libsvn_subr/checksum.h Sat Aug 17 23:20:28
2013
@@ -0,0 +1,74 @@
+/*
+ * checksum.h: Converting and comparing checksums
+ *
+ * ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one
+ *    or more contributor license agreements.  See the NOTICE file
+ *    distributed with this work for additional information
+ *    regarding copyright ownership.  The ASF licenses this file
+ *    to you under the Apache License, Version 2.0 (the
+ *    "License"); you may not use this file except in compliance
+ *    with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing,
+ *    software distributed under the License is distributed on an
+ *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *    KIND, either express or implied.  See the License for the
+ *    specific language governing permissions and limitations
+ *    under the License.
+ * ====================================================================
+ */
+
+#ifndef SVN_LIBSVN_SUBR_CHECKSUM_H
+#define SVN_LIBSVN_SUBR_CHECKSUM_H
+
+#include <apr_pools.h>
+
+#include "svn_checksum.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+
+/* The digest of the given KIND for the empty string. */
+const unsigned char *
+svn__empty_string_digest(svn_checksum_kind_t kind);
+
+
+/* Return the hex representation of DIGEST, which must be
+ * DIGEST_SIZE bytes long, allocating the string in POOL.
+ */
+const char *
+svn__digest_to_cstring_display(const unsigned char digest[],
+                               apr_size_t digest_size,
+                               apr_pool_t *pool);
+
+
+/* Return the hex representation of DIGEST, which must be
+ * DIGEST_SIZE bytes long, allocating the string in POOL.
+ * If DIGEST is all zeros, then return NULL.
+ */
+const char *
+svn__digest_to_cstring(const unsigned char digest[],
+                       apr_size_t digest_size,
+                       apr_pool_t *pool);
+
+
+/* Compare digests D1 and D2, each DIGEST_SIZE bytes long.
+ * If neither is all zeros, and they do not match, then return FALSE;
+ * else return TRUE.
+ */
+svn_boolean_t
+svn__digests_match(const unsigned char d1[],
+                   const unsigned char d2[],
+                   apr_size_t digest_size);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* SVN_LIBSVN_SUBR_CHECKSUM_H */

Modified: subversion/branches/log-addressing/subversion/libsvn_subr/md5.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_subr/md5.c?rev=1515049&r1=1515048&r2=1515049&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_subr/md5.c (original)
+++ subversion/branches/log-addressing/subversion/libsvn_subr/md5.c Sat Aug 17 23:20:28 2013
@@ -23,88 +23,36 @@
 
 
 #include <apr_md5.h>
-#include "md5.h"
+
+#include "svn_checksum.h"
 #include "svn_md5.h"
+#include "checksum.h"
 
 
 
-/* The MD5 digest for the empty string. */
-static const unsigned char svn_md5__empty_string_digest_array[] = {
-  0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
-  0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e
-};
-
-const unsigned char *
-svn_md5__empty_string_digest(void)
-{
-  return svn_md5__empty_string_digest_array;
-}
-
-
-const char *
-svn_md5__digest_to_cstring_display(const unsigned char digest[],
-                                   apr_pool_t *pool)
-{
-  static const char *hex = "0123456789abcdef";
-  char *str = apr_palloc(pool, (APR_MD5_DIGESTSIZE * 2) + 1);
-  int i;
-
-  for (i = 0; i < APR_MD5_DIGESTSIZE; i++)
-    {
-      str[i*2]   = hex[digest[i] >> 4];
-      str[i*2+1] = hex[digest[i] & 0x0f];
-    }
-  str[i*2] = '\0';
-
-  return str;
-}
-
-
-const char *
-svn_md5__digest_to_cstring(const unsigned char digest[], apr_pool_t *pool)
-{
-  static const unsigned char zeros_digest[APR_MD5_DIGESTSIZE] = { 0 };
-
-  if (memcmp(digest, zeros_digest, APR_MD5_DIGESTSIZE) != 0)
-    return svn_md5__digest_to_cstring_display(digest, pool);
-  else
-    return NULL;
-}
-
-
-svn_boolean_t
-svn_md5__digests_match(const unsigned char d1[], const unsigned char d2[])
-{
-  static const unsigned char zeros[APR_MD5_DIGESTSIZE] = { 0 };
-
-  return ((memcmp(d1, zeros, APR_MD5_DIGESTSIZE) == 0)
-          || (memcmp(d2, zeros, APR_MD5_DIGESTSIZE) == 0)
-          || (memcmp(d1, d2, APR_MD5_DIGESTSIZE) == 0));
-}
-
 /* These are all deprecated, and just wrap the internal functions defined
    above. */
 const unsigned char *
 svn_md5_empty_string_digest(void)
 {
-  return svn_md5__empty_string_digest();
+  return svn__empty_string_digest(svn_checksum_md5);
 }
 
 const char *
 svn_md5_digest_to_cstring_display(const unsigned char digest[],
                                   apr_pool_t *pool)
 {
-  return svn_md5__digest_to_cstring_display(digest, pool);
+  return svn__digest_to_cstring_display(digest, APR_MD5_DIGESTSIZE, pool);
 }
 
 const char *
 svn_md5_digest_to_cstring(const unsigned char digest[], apr_pool_t *pool)
 {
-  return svn_md5__digest_to_cstring(digest, pool);
+  return svn__digest_to_cstring(digest, APR_MD5_DIGESTSIZE, pool);
 }
 
 svn_boolean_t
 svn_md5_digests_match(const unsigned char d1[], const unsigned char d2[])
 {
-  return svn_md5__digests_match(d1, d2);
+  return svn__digests_match(d1, d2, APR_MD5_DIGESTSIZE);
 }

Modified: subversion/branches/log-addressing/subversion/tests/libsvn_subr/checksum-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/tests/libsvn_subr/checksum-test.c?rev=1515049&r1=1515048&r2=1515049&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/tests/libsvn_subr/checksum-test.c (original)
+++ subversion/branches/log-addressing/subversion/tests/libsvn_subr/checksum-test.c Sat Aug
17 23:20:28 2013
@@ -28,34 +28,39 @@
 
 #include "../svn_test.h"
 
+/* Verify that DIGEST of checksum type KIND can be parsed and
+ * converted back to a string matching DIGEST.  NAME will be used
+ * to identify the type of checksum in error messages.
+ */
 static svn_error_t *
-test_checksum_parse(apr_pool_t *pool)
+checksum_parse_kind(const char *digest,
+                    svn_checksum_kind_t kind,
+                    const char *name,
+                    apr_pool_t *pool)
 {
-  const char *md5_digest = "8518b76f7a45fe4de2d0955085b41f98";
-  const char *sha1_digest = "74d82379bcc6771454377db03b912c2b62704139";
   const char *checksum_display;
   svn_checksum_t *checksum;
 
-  SVN_ERR(svn_checksum_parse_hex(&checksum, svn_checksum_md5, md5_digest, pool));
+  SVN_ERR(svn_checksum_parse_hex(&checksum, kind, digest, pool));
   checksum_display = svn_checksum_to_cstring_display(checksum, pool);
 
-  if (strcmp(checksum_display, md5_digest) != 0)
+  if (strcmp(checksum_display, digest) != 0)
     return svn_error_createf
       (SVN_ERR_CHECKSUM_MISMATCH, NULL,
-       "verify-checksum: md5 checksum mismatch:\n"
+       "verify-checksum: %s checksum mismatch:\n"
        "   expected:  %s\n"
-       "     actual:  %s\n", md5_digest, checksum_display);
+       "     actual:  %s\n", name, digest, checksum_display);
 
-  SVN_ERR(svn_checksum_parse_hex(&checksum, svn_checksum_sha1, sha1_digest,
-                                 pool));
-  checksum_display = svn_checksum_to_cstring_display(checksum, pool);
+  return SVN_NO_ERROR;
+}
 
-  if (strcmp(checksum_display, sha1_digest) != 0)
-    return svn_error_createf
-      (SVN_ERR_CHECKSUM_MISMATCH, NULL,
-       "verify-checksum: sha1 checksum mismatch:\n"
-       "   expected:  %s\n"
-       "     actual:  %s\n", sha1_digest, checksum_display);
+static svn_error_t *
+test_checksum_parse(apr_pool_t *pool)
+{
+  SVN_ERR(checksum_parse_kind("8518b76f7a45fe4de2d0955085b41f98",
+                              svn_checksum_md5, "md5", pool));
+  SVN_ERR(hecksum_parse_kind("74d82379bcc6771454377db03b912c2b62704139",
+                             svn_checksum_sha1, "sha1", pool));
 
   return SVN_NO_ERROR;
 }
@@ -63,20 +68,18 @@ test_checksum_parse(apr_pool_t *pool)
 static svn_error_t *
 test_checksum_empty(apr_pool_t *pool)
 {
-  svn_checksum_t *checksum;
-  char data = '\0';
-
-  checksum = svn_checksum_empty_checksum(svn_checksum_md5, pool);
-  SVN_TEST_ASSERT(svn_checksum_is_empty_checksum(checksum));
-
-  checksum = svn_checksum_empty_checksum(svn_checksum_sha1, pool);
-  SVN_TEST_ASSERT(svn_checksum_is_empty_checksum(checksum));
-
-  SVN_ERR(svn_checksum(&checksum, svn_checksum_md5, &data, 0, pool));
-  SVN_TEST_ASSERT(svn_checksum_is_empty_checksum(checksum));
-
-  SVN_ERR(svn_checksum(&checksum, svn_checksum_sha1, &data, 0, pool));
-  SVN_TEST_ASSERT(svn_checksum_is_empty_checksum(checksum));
+  svn_checksum_kind_t kind;
+  for (kind = svn_checksum_md5; kind <= svn_checksum_sha1; ++kind)
+    {
+      svn_checksum_t *checksum;
+      char data = '\0';
+
+      checksum = svn_checksum_empty_checksum(kind, pool);
+      SVN_TEST_ASSERT(svn_checksum_is_empty_checksum(checksum));
+
+      SVN_ERR(svn_checksum(&checksum, kind, &data, 0, pool));
+      SVN_TEST_ASSERT(svn_checksum_is_empty_checksum(checksum));
+    }
 
   return SVN_NO_ERROR;
 }
@@ -113,44 +116,77 @@ test_pseudo_md5(apr_pool_t *pool)
   return SVN_NO_ERROR;
 }
 
+/* Verify that "zero" checksums work properly for the given checksum KIND.
+ */
 static svn_error_t *
-zero_match(apr_pool_t *pool)
+zero_match_kind(svn_checksum_kind_t kind, apr_pool_t *pool)
 {
-  svn_checksum_t *zero_md5;
-  svn_checksum_t *zero_sha1;
-  svn_checksum_t *A_md5;
-  svn_checksum_t *B_md5;
-  svn_checksum_t *A_sha1;
-  svn_checksum_t *B_sha1;
-
-
-  zero_md5 = svn_checksum_create(svn_checksum_md5, pool);
-  SVN_ERR(svn_checksum_clear(zero_md5));
-  SVN_ERR(svn_checksum(&A_md5, svn_checksum_md5, "A", 1, pool));
-  SVN_ERR(svn_checksum(&B_md5, svn_checksum_md5, "B", 1, pool));
-
-  zero_sha1 = svn_checksum_create(svn_checksum_sha1, pool);
-  SVN_ERR(svn_checksum_clear(zero_sha1));
-  SVN_ERR(svn_checksum(&A_sha1, svn_checksum_sha1, "A", 1, pool));
-  SVN_ERR(svn_checksum(&B_sha1, svn_checksum_sha1, "B", 1, pool));
+  svn_checksum_t *zero;
+  svn_checksum_t *A;
+  svn_checksum_t *B;
+
+  zero = svn_checksum_create(kind, pool);
+  SVN_ERR(svn_checksum_clear(zero));
+  SVN_ERR(svn_checksum(&A, kind, "A", 1, pool));
+  SVN_ERR(svn_checksum(&B, kind, "B", 1, pool));
 
   /* Different non-zero don't match. */
-  SVN_TEST_ASSERT(!svn_checksum_match(A_md5, B_md5));
-  SVN_TEST_ASSERT(!svn_checksum_match(A_sha1, B_sha1));
-  SVN_TEST_ASSERT(!svn_checksum_match(A_md5, A_sha1));
-  SVN_TEST_ASSERT(!svn_checksum_match(A_md5, B_sha1));
+  SVN_TEST_ASSERT(!svn_checksum_match(A, B));
 
   /* Zero matches anything of the same kind. */
-  SVN_TEST_ASSERT(svn_checksum_match(A_md5, zero_md5));
-  SVN_TEST_ASSERT(svn_checksum_match(zero_md5, B_md5));
-  SVN_TEST_ASSERT(svn_checksum_match(A_sha1, zero_sha1));
-  SVN_TEST_ASSERT(svn_checksum_match(zero_sha1, B_sha1));
-
-  /* Zero doesn't match anything of a different kind... */
-  SVN_TEST_ASSERT(!svn_checksum_match(zero_md5, A_sha1));
-  SVN_TEST_ASSERT(!svn_checksum_match(zero_sha1, A_md5));
-  /* ...even another zero. */
-  SVN_TEST_ASSERT(!svn_checksum_match(zero_md5, zero_sha1));
+  SVN_TEST_ASSERT(svn_checksum_match(A, zero));
+  SVN_TEST_ASSERT(svn_checksum_match(zero, B));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+zero_match(apr_pool_t *pool)
+{
+  svn_checksum_kind_t kind;
+  for (kind = svn_checksum_md5; kind <= svn_checksum_sha1; ++kind)
+    SVN_ERR(zero_match_kind(kind, pool));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+zero_cross_match(apr_pool_t *pool)
+{
+  svn_checksum_kind_t i_kind;
+  svn_checksum_kind_t k_kind;
+
+  for (i_kind = svn_checksum_md5; i_kind <= svn_checksum_sha1; ++i_kind)
+    {
+      svn_checksum_t *i_zero;
+      svn_checksum_t *i_A;
+    
+      i_zero = svn_checksum_create(i_kind, pool);
+      SVN_ERR(svn_checksum_clear(i_zero));
+      SVN_ERR(svn_checksum(&i_A, i_kind, "A", 1, pool));
+
+      for (k_kind = svn_checksum_md5; k_kind <= svn_checksum_sha1; ++k_kind)
+        {
+          svn_checksum_t *k_zero;
+          svn_checksum_t *k_A;
+          if (i_kind == k_kind)
+            continue;
+
+          k_zero = svn_checksum_create(k_kind, pool);
+          SVN_ERR(svn_checksum_clear(k_zero));
+          SVN_ERR(svn_checksum(&k_A, k_kind, "A", 1, pool));
+
+          /* Different non-zero don't match. */
+          SVN_TEST_ASSERT(!svn_checksum_match(i_A, k_A));
+
+          /* Zero doesn't match anything of a different kind... */
+          SVN_TEST_ASSERT(!svn_checksum_match(i_zero, k_A));
+          SVN_TEST_ASSERT(!svn_checksum_match(i_A, k_zero));
+
+          /* ...even another zero. */
+          SVN_TEST_ASSERT(!svn_checksum_match(i_zero, k_zero));
+        }
+    }
 
   return SVN_NO_ERROR;
 }
@@ -167,5 +203,7 @@ struct svn_test_descriptor_t test_funcs[
                    "pseudo-md5 compatibility"),
     SVN_TEST_PASS2(zero_match,
                    "zero checksum matching"),
+    SVN_TEST_PASS2(zero_cross_match,
+                   "zero checksum cross-type matching"),
     SVN_TEST_NULL
   };



Mime
View raw message