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 2011/03/05 11:25:33 UTC

svn commit: r1078256 - /subversion/trunk/subversion/libsvn_subr/svn_temp_serializer.c

Author: stefan2
Date: Sat Mar  5 10:25:33 2011
New Revision: 1078256

URL: http://svn.apache.org/viewvc?rev=1078256&view=rev
Log:
An attempt to fix the issue reported by John Beranek in 
http://svn.haxx.se/dev/archive-2011-03/0111.shtml.
Reformulate the pointer update code to make it less likely
to be broken by "no pointer aliasing" and similar optimizations.

* subversion/libsvn_subr/svn_temp_serializer.c
  (svn_temp_deserializer__resolve): Reformulate and extensively comment.

Modified:
    subversion/trunk/subversion/libsvn_subr/svn_temp_serializer.c

Modified: subversion/trunk/subversion/libsvn_subr/svn_temp_serializer.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/svn_temp_serializer.c?rev=1078256&r1=1078255&r2=1078256&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/svn_temp_serializer.c (original)
+++ subversion/trunk/subversion/libsvn_subr/svn_temp_serializer.c Sat Mar  5 10:25:33 2011
@@ -275,11 +275,22 @@ svn_temp_serializer__get(svn_temp_serial
 void
 svn_temp_deserializer__resolve(void *buffer, void **ptr)
 {
-  if ((apr_size_t)*ptr)
+  /* All pointers are stored as offsets to the buffer start
+   * (of the respective serialized sub-struct). */
+  apr_size_t ptr_offset = *(apr_size_t *)ptr;
+  if (ptr_offset)
     {
-      /* replace the offset in *ptr with the pointer to buffer[*ptr] */
-      (*(const char **)ptr) = (const char*)buffer + (apr_size_t)*ptr;
-      assert(*ptr > buffer);
+      /* Reconstruct the original pointer value */
+      const char *target = (const char *)buffer + ptr_offset;
+
+      /* All sub-structs are written _after_ their respective parent.
+       * Thus, all offsets are > 0. If the following assertion is not met,
+       * the data is either corrupt or you tried to resolve the pointer
+       * more than once. */
+      assert(target > buffer);
+
+      /* replace the PTR_OFFSET in *ptr with the pointer to TARGET */
+      (*(const char **)ptr) = target;
     }
   else
     {