You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2015/01/27 02:47:46 UTC

svn commit: r1654932 - /subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c

Author: stefan2
Date: Tue Jan 27 01:47:45 2015
New Revision: 1654932

URL: http://svn.apache.org/r1654932
Log:
Main fix for issue #4554:  Correctly report the file length through
svn_fs_file_length() in cases the expanded length has not been stored
explicitly in FSFS.

* subversion/libsvn_fs_fs/fs_fs.c
  (svn_fs_fs__file_length): Check whether the file is actually empty;
                            return the correct size otherwise.

Modified:
    subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c

Modified: subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c?rev=1654932&r1=1654931&r2=1654932&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c Tue Jan 27 01:47:45 2015
@@ -26,6 +26,7 @@
 
 #include "svn_private_config.h"
 
+#include "svn_checksum.h"
 #include "svn_hash.h"
 #include "svn_props.h"
 #include "svn_time.h"
@@ -1370,10 +1371,45 @@ svn_fs_fs__file_length(svn_filesize_t *l
                        node_revision_t *noderev,
                        apr_pool_t *pool)
 {
-  if (noderev->data_rep)
-    *length = noderev->data_rep->expanded_size;
+  representation_t *data_rep = noderev->data_rep;
+  if (!data_rep)
+    {
+      /* Treat "no representation" as "empty file". */
+      *length = 0;
+    }
+  else if (data_rep->expanded_size)
+    {
+      /* Standard case: a non-empty file. */
+      *length = data_rep->expanded_size;
+    }
   else
-    *length = 0;
+    {
+      /* Work around a FSFS format quirk (see issue #4554).
+
+         A plain representation may specify its EXPANDED LENGTH as "0"
+         in which case, the SIZE value is what we want.
+
+         Because EXPANDED_LENGTH will also be 0 for empty files, while
+         SIZE is non-null, we need to check wether the content is
+         actually empty.  We simply compare with the MD5 checksum of
+         empty content (sha-1 is not always available).
+       */
+      svn_checksum_t *empty_md5
+        = svn_checksum_empty_checksum(svn_checksum_md5, pool);
+
+      if (memcmp(empty_md5->digest, data_rep->md5_digest,
+                 sizeof(data_rep->md5_digest)))
+        {
+          /* Contents is not empty, i.e. EXPANDED_LENGTH cannot be the
+             actual file length. */
+          *length = data_rep->size;
+        }
+      else
+        {
+          /* Contents is empty. */
+          *length = 0;
+        }
+    }
 
   return SVN_NO_ERROR;
 }