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
{