Luabind 0.9.1 cast graph cache bug
Peter Colberg <[email protected]> Sat, 30 Jul 2011 13:37:56 -0400
| Newsgroups | gmane.comp.lang.lua.bind.user |
|---|---|
| Message-ID | <[email protected]> |
Hi, I came across a bug in the Luabind cast graph cache, which had already been discovered by Eduard Mueller. In case someone else stumbles upon this bug, maybe you will find the attached patch, which includes a detailed explanation, useful. @Daniel: Could you include the attached fix in a Luabind 0.9.2 release, along with the fix for Clang in commit 3044a905? Anyhow, thank you for a very useful and mature library! Peter ------------------------------------------------------------------------------ Got Input? Slashdot Needs You. Take our quick survey online. Come on, we don't ask for help often. Plus, you'll get a chance to win $100 to spend on ThinkGeek. http://p.sf.net/sfu/slashdot-survey _______________________________________________ luabind-user mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/luabind-user
luabind_cast_graph_cache_invalid_cast_fix.patch
(text/x-diff, 3.2 KB)
From: Peter Colberg <[email protected]> Date: Sat, 30 Jul 2011 12:33:42 -0400 This patch fixes a bug in the cast graph cache in Luabind 0.9.1. The problem did not manifest itself in earlier versions, but only became apparent with Luabind commit 8e9bb9c7, which fixed a different cast cache bug. When a cast from a Lua value to a C++ object fails due to mismatching types, e.g. upon function overload resolution, or explicit object_cast, Luabind stores a bogus entry in the cast graph cache. A second cast to the same C++ type will then erroneously yield a successful cast despite the mismatching types. This results in e.g. ambiguous overload errors for overloaded functions despite non-ambiguity, or segmentation faults due to access of a C++ object through a pointer with the wrong type. The bug has first been discovered and fixed by Eduard Mueller: http://old.nabble.com/inheritance-cast_graph-cache-bug-fix-p29936577.html # diff --git a/src/inheritance.cpp b/src/inheritance.cpp # index 2e2ec90..b8467ad 100644 # --- a/src/inheritance.cpp # +++ b/src/inheritance.cpp # @@ -190,7 +190,7 @@ std::pair<void*, int> cast_graph::impl::cast( # } # } # # - m_cache.put(src, target, dynamic_id, object_offset, cache::invalid, -1); # + m_cache.put(src, target, dynamic_id, object_offset, 0, cache::invalid); # # return std::pair<void*, int>((void*)0, -1); # } The above patch switches the arguments to store a correct cache entry with offset equal to cache::invalid. The distance value is irrelevant, as it is discarded in cast_graph::impl::cast(). Presumably the above patch changes it from -1 to 0 to account for the std::size_t type used in the signature of cache::put. The patch below takes a different approach, as already suggested by the author of the above patch. We swap the offset and distance arguments of cache::put to match the order of the cache entry pair. Further, we change the distance type in the cache::put signature from std::size_t to int, to be consistent with the cache entry type. This inconsistency stems from the changes in Luabind commit cf37774. Note that under GNU/Linux, the cast graph cache bug manifests itself on the x86 platform, but does not seem to affect Luabind on x86_64. --- luabind-0.9.1.orig/src/inheritance.cpp +++ luabind-0.9.1/src/inheritance.cpp @@ -64,7 +64,7 @@ void put( class_id src, class_id target, class_id dynamic_id , std::ptrdiff_t object_offset - , std::size_t distance, std::ptrdiff_t offset); + , std::ptrdiff_t offset, int distance); void invalidate(); @@ -90,7 +90,7 @@ void cache::put( class_id src, class_id target, class_id dynamic_id - , std::ptrdiff_t object_offset, std::size_t distance, std::ptrdiff_t offset) + , std::ptrdiff_t object_offset, std::ptrdiff_t offset, int distance) { m_cache.insert(std::make_pair( key_type(src, target, dynamic_id, object_offset) @@ -175,7 +175,7 @@ { m_cache.put( src, target, dynamic_id, object_offset - , qe.distance, (char*)qe.p - (char*)p + , (char*)qe.p - (char*)p, qe.distance ); return std::make_pair(qe.p, qe.distance);