Merge pull request #4574 from dumganhar/hash_code-fix

closed #3463: Potential hash collision by using typeid(T).hash_code() in JSB and LuaBinding.
This commit is contained in:
James Chen 2013-12-20 01:27:50 -08:00
commit 5751995e2e
9 changed files with 150 additions and 164 deletions

View File

@ -67,7 +67,7 @@ static void serverEntryPoint(void);
js_proxy_t *_native_js_global_ht = NULL;
js_proxy_t *_js_native_global_ht = NULL;
std::unordered_map<long, js_type_class_t*> _js_global_type_map;
std::unordered_map<std::string, js_type_class_t*> _js_global_type_map;
static char *_js_log_buf = NULL;

View File

@ -42,8 +42,8 @@ static JSBool dummy_constructor(JSContext *cx, uint32_t argc, jsval *vp) {
T* cobj = new T();
cobj->autorelease();
js_type_class_t *p;
long typeId = t.s_id();
auto typeMapIter = _js_global_type_map.find(typeId);
std::string typeName = t.s_name();
auto typeMapIter = _js_global_type_map.find(typeName);
CCASSERT(typeMapIter != _js_global_type_map.end(), "Can't find the class type!");
p = typeMapIter->second;
@ -184,8 +184,8 @@ JSBool JSB_CCPhysicsDebugNode_debugNodeForCPSpace__static(JSContext *cx, uint32_
if (ret) {
TypeTest<PhysicsDebugNode> t;
js_type_class_t *typeClass = nullptr;
long typeId = t.s_id();
auto typeMapIter = _js_global_type_map.find(typeId);
std::string typeName = t.s_name();
auto typeMapIter = _js_global_type_map.find(typeName);
CCASSERT(typeMapIter != _js_global_type_map.end(), "Can't find the class type!");
typeClass = typeMapIter->second;
@ -274,8 +274,8 @@ void JSB_CCPhysicsDebugNode_createClass(JSContext *cx, JSObject* globalObj, cons
TypeTest<cocos2d::DrawNode> t1;
js_type_class_t *typeClass = nullptr;
long typeId = t1.s_id();
auto typeMapIter = _js_global_type_map.find(typeId);
std::string typeName = t1.s_name();
auto typeMapIter = _js_global_type_map.find(typeName);
CCASSERT(typeMapIter != _js_global_type_map.end(), "Can't find the class type!");
typeClass = typeMapIter->second;
@ -285,15 +285,15 @@ void JSB_CCPhysicsDebugNode_createClass(JSContext *cx, JSObject* globalObj, cons
TypeTest<PhysicsDebugNode> t;
js_type_class_t *p;
typeId = t.s_id();
typeName = t.s_name();
if (_js_global_type_map.find(typeId) == _js_global_type_map.end())
if (_js_global_type_map.find(typeName) == _js_global_type_map.end())
{
p = (js_type_class_t *)malloc(sizeof(js_type_class_t));
p->jsclass = JSB_CCPhysicsDebugNode_class;
p->proto = JSB_CCPhysicsDebugNode_object;
p->parentProto = typeClass->proto;
_js_global_type_map.insert(std::make_pair(typeId, p));
_js_global_type_map.insert(std::make_pair(typeName, p));
}
}
@ -317,8 +317,8 @@ JSBool JSPROXY_CCPhysicsSprite_spriteWithFile_rect__static(JSContext *cx, uint32
if (ret) {
TypeTest<PhysicsSprite> t;
js_type_class_t *typeClass = nullptr;
long typeId = t.s_id();
auto typeMapIter = _js_global_type_map.find(typeId);
std::string typeName = t.s_name();
auto typeMapIter = _js_global_type_map.find(typeName);
CCASSERT(typeMapIter != _js_global_type_map.end(), "Can't find the class type!");
typeClass = typeMapIter->second;
CCASSERT(typeClass, "The value is null.");
@ -346,8 +346,8 @@ JSBool JSPROXY_CCPhysicsSprite_spriteWithFile_rect__static(JSContext *cx, uint32
if (ret) {
TypeTest<PhysicsSprite> t;
js_type_class_t *typeClass = nullptr;
long typeId = t.s_id();
auto typeMapIter = _js_global_type_map.find(typeId);
std::string typeName = t.s_name();
auto typeMapIter = _js_global_type_map.find(typeName);
CCASSERT(typeMapIter != _js_global_type_map.end(), "Can't find the class type!");
typeClass = typeMapIter->second;
CCASSERT(typeClass, "The value is null.");
@ -387,8 +387,8 @@ JSBool JSPROXY_CCPhysicsSprite_spriteWithSpriteFrame__static(JSContext *cx, uint
if (ret) {
TypeTest<PhysicsSprite> t;
js_type_class_t *typeClass = nullptr;
long typeId = t.s_id();
auto typeMapIter = _js_global_type_map.find(typeId);
std::string typeName = t.s_name();
auto typeMapIter = _js_global_type_map.find(typeName);
CCASSERT(typeMapIter != _js_global_type_map.end(), "Can't find the class type!");
typeClass = typeMapIter->second;
CCASSERT(typeClass, "The value is null.");
@ -421,8 +421,8 @@ JSBool JSPROXY_CCPhysicsSprite_spriteWithSpriteFrameName__static(JSContext *cx,
if (ret) {
TypeTest<PhysicsSprite> t;
js_type_class_t *typeClass = nullptr;
long typeId = t.s_id();
auto typeMapIter = _js_global_type_map.find(typeId);
std::string typeName = t.s_name();
auto typeMapIter = _js_global_type_map.find(typeName);
CCASSERT(typeMapIter != _js_global_type_map.end(), "Can't find the class type!");
typeClass = typeMapIter->second;
CCASSERT(typeClass, "The value is null.");
@ -475,8 +475,8 @@ void JSPROXY_CCPhysicsSprite_createClass(JSContext *cx, JSObject* globalObj)
TypeTest<cocos2d::Sprite> t1;
js_type_class_t *typeClass = nullptr;
long typeId = t1.s_id();
auto typeMapIter = _js_global_type_map.find(typeId);
std::string typeName = t1.s_name();
auto typeMapIter = _js_global_type_map.find(typeName);
CCASSERT(typeMapIter != _js_global_type_map.end(), "Can't find the class type!");
typeClass = typeMapIter->second;
CCASSERT(typeClass, "The value is null.");
@ -485,14 +485,14 @@ void JSPROXY_CCPhysicsSprite_createClass(JSContext *cx, JSObject* globalObj)
TypeTest<PhysicsSprite> t;
js_type_class_t *p;
typeId = t.s_id();
if (_js_global_type_map.find(typeId) == _js_global_type_map.end())
typeName = t.s_name();
if (_js_global_type_map.find(typeName) == _js_global_type_map.end())
{
p = (js_type_class_t *)malloc(sizeof(js_type_class_t));
p->jsclass = JSPROXY_CCPhysicsSprite_class;
p->proto = JSPROXY_CCPhysicsSprite_object;
p->parentProto = typeClass->proto;
_js_global_type_map.insert(std::make_pair(typeId, p));
_js_global_type_map.insert(std::make_pair(typeName, p));
}
}

View File

@ -40,12 +40,12 @@ extern callfuncTarget_proxy_t *_callfuncTarget_native_ht;
template <class T>
inline js_type_class_t *js_get_type_from_native(T* native_obj) {
bool found = false;
long typeId = typeid(*native_obj).hash_code();
auto typeProxyIter = _js_global_type_map.find(typeId);
std::string typeName = typeid(*native_obj).name();
auto typeProxyIter = _js_global_type_map.find(typeName);
if (typeProxyIter == _js_global_type_map.end())
{
typeId = typeid(T).hash_code();
typeProxyIter = _js_global_type_map.find(typeId);
typeName = typeid(T).name();
typeProxyIter = _js_global_type_map.find(typeName);
if (typeProxyIter != _js_global_type_map.end())
{
found = true;

View File

@ -39,8 +39,8 @@ JSBool js_cocos2dx_GLNode_constructor(JSContext *cx, uint32_t argc, jsval *vp)
TypeTest<GLNode> t;
js_type_class_t *typeClass = nullptr;
long typeId = t.s_id();
auto typeMapIter = _js_global_type_map.find(typeId);
std::string typeName = t.s_name();
auto typeMapIter = _js_global_type_map.find(typeName);
CCASSERT(typeMapIter != _js_global_type_map.end(), "Can't find the class type!");
typeClass = typeMapIter->second;
@ -134,13 +134,13 @@ void js_register_cocos2dx_GLNode(JSContext *cx, JSObject *global) {
// add the proto and JSClass to the type->js info hash table
TypeTest<GLNode> t;
js_type_class_t *p;
long typeId = t.s_id();
if (_js_global_type_map.find(typeId) == _js_global_type_map.end())
std::string typeName = t.s_name();
if (_js_global_type_map.find(typeName) == _js_global_type_map.end())
{
p = (js_type_class_t *)malloc(sizeof(js_type_class_t));
p->jsclass = js_cocos2dx_GLNode_class;
p->proto = js_cocos2dx_GLNode_prototype;
p->parentProto = jsb_Node_prototype;
_js_global_type_map.insert(std::make_pair(typeId, p));
_js_global_type_map.insert(std::make_pair(typeName, p));
}
}

View File

@ -20,26 +20,12 @@ typedef struct js_type_class {
JSObject *parentProto;
} js_type_class_t;
extern std::unordered_map<long, js_type_class_t*> _js_global_type_map;
extern std::unordered_map<std::string, js_type_class_t*> _js_global_type_map;
template< typename DERIVED >
class TypeTest
{
public:
static long s_id()
{
// return id unique for DERIVED
// NOT SURE IT WILL BE REALLY UNIQUE FOR EACH CLASS!!
/* Commented by James Chen
Using 'getHashCodeByString(typeid(*native_obj).name())' instead of 'reinterpret_cast<long>(typeid(*native_obj).name());'.
Since on win32 platform, 'reinterpret_cast<long>(typeid(*native_obj).name());' invoking in cocos2d.dll and outside cocos2d.dll(in TestJavascript.exe) will return different address.
But the return string from typeid(*native_obj).name() is the same string, so we must convert the string to hash id to make sure we can get unique id.
*/
// static const long id = reinterpret_cast<long>(typeid( DERIVED ).name());
static const long id = typeid( DERIVED ).hash_code();
return id;
}
static const char* s_name()
{
// return id unique for DERIVED

View File

@ -32,7 +32,7 @@ extern "C" {
}
#endif
std::map<long, std::string> g_luaType;
std::unordered_map<std::string, std::string> g_luaType;
#if COCOS2D_DEBUG >=1
void luaval_to_native_err(lua_State* L,const char* msg,tolua_Error* err)
@ -1640,8 +1640,8 @@ void array_to_luaval(lua_State* L,Array* inValue)
if (nullptr == obj)
continue;
long typeId = typeid(*obj).hash_code();
auto iter = g_luaType.find(typeId);
std::string typeName = typeid(*obj).name();
auto iter = g_luaType.find(typeName);
if (g_luaType.end() != iter)
{
className = iter->second;
@ -1729,9 +1729,9 @@ void dictionary_to_luaval(lua_State* L, Dictionary* dict)
if (NULL == element)
continue;
long typeId = typeid(element->getObject()).hash_code();
std::string typeName = typeid(element->getObject()).name();
auto iter = g_luaType.find(typeId);
auto iter = g_luaType.find(typeName);
if (g_luaType.end() != iter)
{
className = iter->second;

View File

@ -11,7 +11,7 @@ extern "C" {
using namespace cocos2d;
extern std::map<long, std::string> g_luaType;
extern std::unordered_map<std::string, std::string> g_luaType;
#if COCOS2D_DEBUG >=1
void luaval_to_native_err(lua_State* L,const char* msg,tolua_Error* err);
@ -160,8 +160,8 @@ void ccvector_to_luaval(lua_State* L,const cocos2d::Vector<T>& inValue)
if (nullptr != dynamic_cast<cocos2d::Object *>(obj))
{
long typeId = typeid(*obj).hash_code();
auto iter = g_luaType.find(typeId);
std::string typeName = typeid(*obj).name();
auto iter = g_luaType.find(typeName);
if (g_luaType.end() != iter)
{
lua_pushnumber(L, (lua_Number)indexTable);

View File

@ -694,8 +694,8 @@ int register_cocos2dx_extension_CCBProxy(lua_State* tolua_S)
tolua_endmodule(tolua_S);
tolua_endmodule(tolua_S);
long typeId = typeid(CCBProxy).hash_code();
g_luaType[typeId] = "CCBProxy";
std::string typeName = typeid(CCBProxy).name();
g_luaType[typeName] = "CCBProxy";
return 1;
}

@ -1 +1 @@
Subproject commit f0b6cc8dd3d375f0999ec4e49dd90dbe1938c460
Subproject commit ad532012457e2eaff15d73d9ba28a638fa748d2d