diff --git a/lib/wx/api_gen/wx_gen_nif.erl b/lib/wx/api_gen/wx_gen_nif.erl index bf67205275f..dc77e53cfdb 100644 --- a/lib/wx/api_gen/wx_gen_nif.erl +++ b/lib/wx/api_gen/wx_gen_nif.erl @@ -388,6 +388,7 @@ gen_method(CName, M=#method{name=N,params=Ps0,type=T,method_type=MT,id=MethodId Opts = [Opt || Opt = #param{def=Def,in=In,where=Where} <- Ps2, Def =/= none, In =/= false, Where =/= c], decode_options(Opts, Argc), + case gen_util:get_hook(c, M#method.pre_hook) of ignore -> skip; Pre -> w(" ~s;~n", [Pre]) @@ -542,6 +543,23 @@ decode_opt(#param{name=Name,type=Type}) -> decode_arguments(Ps0) -> lists:mapfoldl(fun decode_arg/2,0,Ps0). +%% Postpone alloc and memcpy until after all Badarg execeptions +%% so we don't leak memory in case of later badarg +copy_arguments([#param{where=Where, in=In, def=none, name=N, type=Type}|Rest]) + when Where =/= erl, Where =/= c, In =/= false -> + case Type of + #type{base = binary, by_val=copy} -> + w(" ~s = (unsigned char *) malloc(~s_bin.size);\n", [N,N]), + w(" memcpy(~s,~s_bin.data,~s_bin.size);\n", [N,N,N]); + _ -> + ignore + end, + copy_arguments(Rest); +copy_arguments([_|Rest]) -> + copy_arguments(Rest); +copy_arguments([]) -> + ok. + store_free(N) -> case get(free_args) of undefined -> put(free_args, [N]); @@ -710,9 +728,10 @@ decode_arg(N,#type{name=Type,base=binary,mod=Mod0,by_val=Copy},Arg,Argc) -> w(" ErlNifBinary ~s_bin;~n",[N]), w(" if(!enif_inspect_binary(env, ~s, &~s_bin)) ~s;~n",[Argc, N, badarg(N)]), case Copy of - copy -> - w(" ~s = (unsigned char *) malloc(~s_bin.size);\n", [N,N]), - w(" memcpy(~s,~s_bin.data,~s_bin.size);\n", [N,N,N]); + copy -> %% postpone see copy_arguments + %% w(" ~s = (unsigned char *) malloc(~s_bin.size);\n", [N,N]), + %% w(" memcpy(~s,~s_bin.data,~s_bin.size);\n", [N,N,N]); + ok; _ -> w(" ~s = (~s~s*) ~s_bin.data;~n", [N,Mod,Type,N]) end; @@ -797,6 +816,8 @@ call_wx(_N,{constructor,_},#type{base={class,RClass}},Ps) -> false -> RClass end, + copy_arguments(Ps), + case [P || #param{type={merged,_}}=P <- Ps] of [] -> w(" ~s * Result = new ~s(~s);~n", @@ -838,6 +859,7 @@ call_wx(_N,{constructor,_},#type{base={class,RClass}},Ps) -> call_wx(N,{member,_},Type,Ps0) -> {Beg,End} = return_res(Type), w(" if(!This) throw wxe_badarg(\"This\");~n",[]), + copy_arguments(Ps0), Ps = filter(Ps0), case [P || #param{type={merged,_}}=P <- Ps] of [] -> @@ -858,6 +880,7 @@ call_wx(N,{member,_},Type,Ps0) -> call_wx(N,{static,Class},Type,Ps) -> {Beg,End} = return_res(Type), #class{parent=Parent} = get({class,Class}), + copy_arguments(Ps), case [P || #param{type={merged,_}}=P <- Ps] of [] when Parent =:= "static" -> w(" ~s::~s(~s)~s;~n",[Beg,N,args(fun call_arg/1, ",",filter(Ps)),End]); diff --git a/lib/wx/c_src/gen/wxe_wrapper_4.cpp b/lib/wx/c_src/gen/wxe_wrapper_4.cpp index ac8bf918e9e..45cbc77e490 100644 --- a/lib/wx/c_src/gen/wxe_wrapper_4.cpp +++ b/lib/wx/c_src/gen/wxe_wrapper_4.cpp @@ -1293,11 +1293,11 @@ void wxImage_new_4(WxeApp *app, wxeMemEnv *memenv, wxeCommand& Ecmd) unsigned char * data; ErlNifBinary data_bin; if(!enif_inspect_binary(env, argv[2], &data_bin)) Badarg("data"); - data = (unsigned char *) malloc(data_bin.size); - memcpy(data,data_bin.data,data_bin.size); unsigned char * alpha; ErlNifBinary alpha_bin; if(!enif_inspect_binary(env, argv[3], &alpha_bin)) Badarg("alpha"); + data = (unsigned char *) malloc(data_bin.size); + memcpy(data,data_bin.data,data_bin.size); alpha = (unsigned char *) malloc(alpha_bin.size); memcpy(alpha,alpha_bin.data,alpha_bin.size); wxImage * Result = new EwxImage(width,height,data,alpha); @@ -1323,11 +1323,11 @@ void wxImage_new_3_3(WxeApp *app, wxeMemEnv *memenv, wxeCommand& Ecmd) unsigned char * data; ErlNifBinary data_bin; if(!enif_inspect_binary(env, argv[1], &data_bin)) Badarg("data"); - data = (unsigned char *) malloc(data_bin.size); - memcpy(data,data_bin.data,data_bin.size); unsigned char * alpha; ErlNifBinary alpha_bin; if(!enif_inspect_binary(env, argv[2], &alpha_bin)) Badarg("alpha"); + data = (unsigned char *) malloc(data_bin.size); + memcpy(data,data_bin.data,data_bin.size); alpha = (unsigned char *) malloc(alpha_bin.size); memcpy(alpha,alpha_bin.data,alpha_bin.size); wxImage * Result = new EwxImage(sz,data,alpha); @@ -1658,9 +1658,9 @@ void wxImage_Create_3_0(WxeApp *app, wxeMemEnv *memenv, wxeCommand& Ecmd) unsigned char * data; ErlNifBinary data_bin; if(!enif_inspect_binary(env, argv[3], &data_bin)) Badarg("data"); + if(!This) throw wxe_badarg("This"); data = (unsigned char *) malloc(data_bin.size); memcpy(data,data_bin.data,data_bin.size); - if(!This) throw wxe_badarg("This"); bool Result = This->Create(width,height,data); wxeReturn rt = wxeReturn(memenv, Ecmd.caller, true); rt.send( rt.make_bool(Result)); @@ -1685,9 +1685,9 @@ void wxImage_Create_2_0(WxeApp *app, wxeMemEnv *memenv, wxeCommand& Ecmd) unsigned char * data; ErlNifBinary data_bin; if(!enif_inspect_binary(env, argv[2], &data_bin)) Badarg("data"); + if(!This) throw wxe_badarg("This"); data = (unsigned char *) malloc(data_bin.size); memcpy(data,data_bin.data,data_bin.size); - if(!This) throw wxe_badarg("This"); bool Result = This->Create(sz,data); wxeReturn rt = wxeReturn(memenv, Ecmd.caller, true); rt.send( rt.make_bool(Result)); @@ -1708,14 +1708,14 @@ void wxImage_Create_4(WxeApp *app, wxeMemEnv *memenv, wxeCommand& Ecmd) unsigned char * data; ErlNifBinary data_bin; if(!enif_inspect_binary(env, argv[3], &data_bin)) Badarg("data"); - data = (unsigned char *) malloc(data_bin.size); - memcpy(data,data_bin.data,data_bin.size); unsigned char * alpha; ErlNifBinary alpha_bin; if(!enif_inspect_binary(env, argv[4], &alpha_bin)) Badarg("alpha"); + if(!This) throw wxe_badarg("This"); + data = (unsigned char *) malloc(data_bin.size); + memcpy(data,data_bin.data,data_bin.size); alpha = (unsigned char *) malloc(alpha_bin.size); memcpy(alpha,alpha_bin.data,alpha_bin.size); - if(!This) throw wxe_badarg("This"); bool Result = This->Create(width,height,data,alpha); wxeReturn rt = wxeReturn(memenv, Ecmd.caller, true); rt.send( rt.make_bool(Result)); @@ -1740,14 +1740,14 @@ void wxImage_Create_3_2(WxeApp *app, wxeMemEnv *memenv, wxeCommand& Ecmd) unsigned char * data; ErlNifBinary data_bin; if(!enif_inspect_binary(env, argv[2], &data_bin)) Badarg("data"); - data = (unsigned char *) malloc(data_bin.size); - memcpy(data,data_bin.data,data_bin.size); unsigned char * alpha; ErlNifBinary alpha_bin; if(!enif_inspect_binary(env, argv[3], &alpha_bin)) Badarg("alpha"); + if(!This) throw wxe_badarg("This"); + data = (unsigned char *) malloc(data_bin.size); + memcpy(data,data_bin.data,data_bin.size); alpha = (unsigned char *) malloc(alpha_bin.size); memcpy(alpha,alpha_bin.data,alpha_bin.size); - if(!This) throw wxe_badarg("This"); bool Result = This->Create(sz,data,alpha); wxeReturn rt = wxeReturn(memenv, Ecmd.caller, true); rt.send( rt.make_bool(Result)); @@ -2675,9 +2675,9 @@ void wxImage_SetAlpha_1(WxeApp *app, wxeMemEnv *memenv, wxeCommand& Ecmd) unsigned char * alpha; ErlNifBinary alpha_bin; if(!enif_inspect_binary(env, argv[1], &alpha_bin)) Badarg("alpha"); + if(!This) throw wxe_badarg("This"); alpha = (unsigned char *) malloc(alpha_bin.size); memcpy(alpha,alpha_bin.data,alpha_bin.size); - if(!This) throw wxe_badarg("This"); This->SetAlpha(alpha); } @@ -2710,9 +2710,9 @@ void wxImage_SetData_1(WxeApp *app, wxeMemEnv *memenv, wxeCommand& Ecmd) unsigned char * data; ErlNifBinary data_bin; if(!enif_inspect_binary(env, argv[1], &data_bin)) Badarg("data"); + if(!This) throw wxe_badarg("This"); data = (unsigned char *) malloc(data_bin.size); memcpy(data,data_bin.data,data_bin.size); - if(!This) throw wxe_badarg("This"); This->SetData(data); } @@ -2727,13 +2727,13 @@ void wxImage_SetData_3(WxeApp *app, wxeMemEnv *memenv, wxeCommand& Ecmd) unsigned char * data; ErlNifBinary data_bin; if(!enif_inspect_binary(env, argv[1], &data_bin)) Badarg("data"); - data = (unsigned char *) malloc(data_bin.size); - memcpy(data,data_bin.data,data_bin.size); int new_width; if(!enif_get_int(env, argv[2], &new_width)) Badarg("new_width"); // int int new_height; if(!enif_get_int(env, argv[3], &new_height)) Badarg("new_height"); // int if(!This) throw wxe_badarg("This"); + data = (unsigned char *) malloc(data_bin.size); + memcpy(data,data_bin.data,data_bin.size); This->SetData(data,new_width,new_height); } diff --git a/lib/wx/c_src/wxe_gl.cpp b/lib/wx/c_src/wxe_gl.cpp index a0b13aae62a..12eed621f13 100644 --- a/lib/wx/c_src/wxe_gl.cpp +++ b/lib/wx/c_src/wxe_gl.cpp @@ -75,15 +75,19 @@ void setActiveGL(wxeMemEnv *memenv, ErlNifPid caller, wxGLCanvas *canvas, wxGLCo { ErlNifUInt64 callId = wxe_make_hash(memenv->tmp_env, &caller); wxe_glc * entry = glc[callId]; + gl_active_index = callId; gl_active_pid = caller; if(!entry) { - entry = (wxe_glc *) malloc(sizeof(wxe_glc)); - entry->canvas = NULL; - entry->context = NULL; + if(canvas && context) { + entry = (wxe_glc *) malloc(sizeof(wxe_glc)); + entry->canvas = NULL; + entry->context = NULL; + } + else // canvas or context are NULL ignore + return; } - if(entry->canvas == canvas && entry->context == context) return; diff --git a/lib/wx/c_src/wxe_return.cpp b/lib/wx/c_src/wxe_return.cpp index d2fd9b1b14d..f4c9ee5342e 100644 --- a/lib/wx/c_src/wxe_return.cpp +++ b/lib/wx/c_src/wxe_return.cpp @@ -233,7 +233,7 @@ ERL_NIF_TERM wxeReturn::make_array_objs(wxAuiPaneInfoArray& arr, WxeApp *app, co ERL_NIF_TERM head, tail; ERL_NIF_TERM class_name = enif_make_atom(env, cname); tail = enif_make_list(env, 0); - for(unsigned int i = arr.GetCount() -1; i >= 0; i--) { + for(ErlNifSInt64 i = arr.GetCount() -1; i >= 0; i--) { head = make_ref(app->getRef((void *) &arr.Item(i),memenv), class_name); tail = enif_make_list_cell(env, head, tail); } @@ -245,7 +245,7 @@ ERL_NIF_TERM wxeReturn::make_array_objs(wxArrayTreeItemIds& arr) { ERL_NIF_TERM head, tail; tail = enif_make_list(env, 0); - for(unsigned int i = arr.GetCount() -1; i >= 0; i--) { + for(ErlNifSInt64 i = arr.GetCount() -1; i >= 0; i--) { head = make((wxUIntPtr *) arr[i].m_pItem); tail = enif_make_list_cell(env, head, tail); } @@ -257,7 +257,7 @@ ERL_NIF_TERM wxeReturn::make_array_objs(wxGridCellCoordsArray& arr) { ERL_NIF_TERM head, tail; tail = enif_make_list(env, 0); - for(unsigned int i = arr.GetCount() -1; i >= 0; i--) { + for(ErlNifSInt64 i = arr.GetCount() -1; i >= 0; i--) { head = make(arr[i]); tail = enif_make_list_cell(env, head, tail); } diff --git a/lib/wx/test/wx_class_SUITE.erl b/lib/wx/test/wx_class_SUITE.erl index f18d2eefe04..70ee2f46ce3 100644 --- a/lib/wx/test/wx_class_SUITE.erl +++ b/lib/wx/test/wx_class_SUITE.erl @@ -150,6 +150,9 @@ treeCtrl(Config) -> ?m({0, _}, wxTreeCtrl:hitTest(Tree, {X0+W0+W0, Y0+H0+4*H0})), ?m(false, wxTreeCtrl:isTreeItemIdOk(0)), + {N, Sels} = wxTreeCtrl:getSelections(Tree), + N = length(Sels), + wxFrame:connect(Tree, command_tree_item_expanded), wxFrame:connect(Tree, command_tree_item_collapsed), wxFrame:connect(Frame, close_window),