Skip to content

Commit ff09692

Browse files
committed
Replace DATA_PTR and Data_Get_Struct by SWIG_ConvertPtr
Mixing ruby functions and SWIG functions to access Ruby/C++ objects is bad practice. It relies on a particular expectation of how SWIG maps C++ objects to Ruby objects. This commit changes the code to use SWIG functions only and to not use raw Ruby functions to access SWIG mapped objects. Also change the flag of ConvertPtr to the SWIG provided constant SWIG_POINTER_DISOWN, to make it more clear, that the object will be deleted by the object it was assigned to. The compiler deprecation warning is re-enabled, since they do no longer appear when built with SWIG with the following patch: swig/swig#3326 Fix type conversions of Array<FXPoint>, Array<FXRectangle>, Array<FXSegment> and Array<FXArc> to raise an error on type mismatch. This wasn't checked before and could lead to invalid memory access.
1 parent 09aa024 commit ff09692

File tree

17 files changed

+117
-55
lines changed

17 files changed

+117
-55
lines changed

ext/fox16_c/FXRbApp.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
* $Id: FXRbApp.cpp 2902 2008-12-11 14:09:20Z lyle $
2525
***********************************************************************/
2626

27+
#include "swigruby.h"
2728
#include "FXRbCommon.h"
2829

2930
#ifdef HAVE_SYS_TIME_H

ext/fox16_c/FXRbDataTarget.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
* $Id: FXRbDataTarget.cpp 2713 2007-11-14 15:27:36Z lyle $
2525
***********************************************************************/
2626

27+
#include "swigruby.h"
2728
#include "FXRbCommon.h"
2829

2930
/**

ext/fox16_c/FXRbGLViewer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
* $Id: FXRbGLViewer.cpp 2190 2005-08-24 07:58:47Z lyle $
2525
***********************************************************************/
2626

27+
#include "swigruby.h"
2728
#include "FXRbCommon.h"
2829

2930
// Process picks

ext/fox16_c/FXRbObjRegistry.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@
2020
* at "lars@greiz-reinsdorf.de".
2121
***********************************************************************/
2222

23+
#include "swigruby.h"
2324
#include "FXRbCommon.h"
2425
#include "FXRbObjRegistry.h"
25-
#include "swigruby.h"
2626

2727
FXRbObjRegistry::FXRbObjRegistry(){
2828
FXRuby_Objects=st_init_numtable();
@@ -84,7 +84,7 @@ void FXRbObjRegistry::RegisterRubyObj(VALUE rubyObj,const void* foxObj) {
8484
* To avoid double references to the same foxObj from different Ruby objects,
8585
* we decouple the foxObj from previoius ruby object and point to the new one.
8686
*/
87-
DATA_PTR(desc->obj) = 0;
87+
FXRbConvertPtr(desc->obj, NULL, SWIG_POINTER_RELEASE);
8888
desc->obj = rubyObj;
8989
desc->type = own;
9090
} else {
@@ -107,7 +107,14 @@ void FXRbObjRegistry::UnregisterRubyObj(const void* foxObj, bool alsoOwned){
107107
if(st_lookup(FXRuby_Objects,reinterpret_cast<st_data_t>(const_cast<void*>(foxObj)),reinterpret_cast<st_data_t *>(&desc))!=0){
108108
if( !alsoOwned && desc->type!=borrowed ) return;
109109
FXTRACE((1,"FXRbUnregisterRubyObj(rubyObj=%p (%s),foxObj=%p)\n",(void *)desc->obj,safe_rb_obj_classname(desc->obj),foxObj));
110-
DATA_PTR(desc->obj)=0;
110+
111+
if(RB_TYPE_P(desc->obj, RUBY_T_DATA)) {
112+
/* Release unless it's already T_ZOMBIE */
113+
int res = SWIG_ConvertPtr(desc->obj, NULL, NULL, SWIG_POINTER_RELEASE);
114+
if (res != SWIG_OK){
115+
rb_bug( "UnregisterRubyObj(rubyObj=%p) error: %d", (void*)desc->obj, res);
116+
}
117+
}
111118
FXFREE(&desc);
112119
st_delete(FXRuby_Objects,reinterpret_cast<st_data_t *>(const_cast<void**>(&foxObj)),reinterpret_cast<st_data_t *>(0));
113120
FXASSERT(st_lookup(FXRuby_Objects,reinterpret_cast<st_data_t>(const_cast<void*>(foxObj)),reinterpret_cast<st_data_t *>(0))==0);

ext/fox16_c/FXRuby.cpp

Lines changed: 46 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@
2828
#pragma warning (disable : 4786)
2929
#endif
3030

31+
// SWIG runtime functions we need
32+
#include "swigruby.h"
33+
3134
#include "FXRbCommon.h"
3235
#include "FXRbObjRegistry.h"
3336
#include "impl.h"
3437

35-
// SWIG runtime functions we need
36-
#include "swigruby.h"
37-
3838
#ifdef __CYGWIN__
3939
#include <io.h> // for get_osf_handle()
4040
#endif
@@ -842,8 +842,7 @@ void* FXRbGetExpectedData(VALUE recv,FXSelector key,VALUE value){
842842
FXushort id=FXSELID(key);
843843

844844
// Extract the FOX object (the receiver) from this Ruby instance
845-
FXObject* obj;
846-
Data_Get_Struct(recv,FXObject,obj);
845+
FXObject *obj = (FXObject*)FXRbConvertPtr(recv, NULL, 0);
847846

848847
FXASSERT(type!=SEL_NONE);
849848
FXASSERT(type!=SEL_LAST);
@@ -896,7 +895,7 @@ void* FXRbGetExpectedData(VALUE recv,FXSelector key,VALUE value){
896895
case SEL_DND_MOTION:
897896
case SEL_DND_REQUEST:
898897
case SEL_PICKED:
899-
SWIG_ConvertPtr(value,&ptr,FXRbTypeQuery("FXEvent *"),1);
898+
SWIG_ConvertPtr(value,&ptr,FXRbTypeQuery("FXEvent *"),SWIG_POINTER_DISOWN);
900899
return ptr;
901900
case SEL_IO_READ:
902901
case SEL_IO_WRITE:
@@ -1072,7 +1071,7 @@ void* FXRbGetExpectedData(VALUE recv,FXSelector key,VALUE value){
10721071

10731072
if(type==SEL_CHANGED){
10741073
if(obj->isMemberOf(FXMETACLASS(FXPicker))){
1075-
SWIG_ConvertPtr(value,&ptr,FXRbTypeQuery("FXPoint *"),1);
1074+
SWIG_ConvertPtr(value,&ptr,FXRbTypeQuery("FXPoint *"),SWIG_POINTER_DISOWN);
10761075
return ptr;
10771076
}
10781077
if(obj->isMemberOf(FXMETACLASS(FXWindow))){
@@ -1086,7 +1085,7 @@ void* FXRbGetExpectedData(VALUE recv,FXSelector key,VALUE value){
10861085
}
10871086

10881087
if(type==SEL_DRAGGED){
1089-
SWIG_ConvertPtr(value,&ptr,FXRbTypeQuery("FXEvent *"),1);
1088+
SWIG_ConvertPtr(value,&ptr,FXRbTypeQuery("FXEvent *"),SWIG_POINTER_DISOWN);
10901089
return ptr;
10911090
}
10921091

@@ -1300,21 +1299,21 @@ FXGLObject* FXRbCallGLObjectMethod_gvlcb(FXGLObject* recv,const char *func){
13001299
VALUE obj=FXRbGetRubyObj(recv,false);
13011300
FXASSERT(!NIL_P(obj));
13021301
VALUE result=rb_funcall(obj,rb_intern(func),0);
1303-
return NIL_P(result) ? 0 : reinterpret_cast<FXGLObject*>(DATA_PTR(result));
1302+
return (FXGLObject*)FXRbConvertPtr(result, NULL, 0);
13041303
}
13051304

13061305
FXGLObject* FXRbCallGLObjectMethod_gvlcb(FXGLViewer* recv,const char *func,FXint x,FXint y){
13071306
VALUE obj=FXRbGetRubyObj(recv,false);
13081307
FXASSERT(!NIL_P(obj));
13091308
VALUE result=rb_funcall(obj,rb_intern(func),2,INT2NUM(x),INT2NUM(y));
1310-
return NIL_P(result) ? 0 : reinterpret_cast<FXGLObject*>(DATA_PTR(result));
1309+
return (FXGLObject*)FXRbConvertPtr(result, NULL, 0);
13111310
}
13121311

13131312
FXGLObject* FXRbCallGLObjectMethod_gvlcb(FXGLObject* recv,const char *func,FXuint* path,FXint n){
13141313
VALUE obj=FXRbGetRubyObj(recv,false);
13151314
FXASSERT(!NIL_P(obj));
13161315
VALUE result=rb_funcall(obj,rb_intern(func),1,FXRbMakeArray(path,n));
1317-
return NIL_P(result) ? 0 : reinterpret_cast<FXGLObject*>(DATA_PTR(result));
1316+
return (FXGLObject*)FXRbConvertPtr(result, NULL, 0);
13181317
}
13191318

13201319
//----------------------------------------------------------------------
@@ -1329,7 +1328,8 @@ FXGLObject** FXRbCallGLObjectArrayMethod_gvlcb(FXGLViewer* recv,const char *func
13291328
Check_Type(result,T_ARRAY);
13301329
if(FXMALLOC(&objects,FXGLObject*,RARRAY_LEN(result)+1)){
13311330
for(long i=0; i<RARRAY_LEN(result); i++){
1332-
objects[i]=reinterpret_cast<FXGLObject*>(DATA_PTR(rb_ary_entry(result,i)));
1331+
VALUE entry = rb_ary_entry(result,i);
1332+
objects[i]=(FXGLObject*)FXRbConvertPtr(entry, NULL, 0);
13331333
}
13341334
objects[RARRAY_LEN(result)]=0;
13351335
}
@@ -1344,14 +1344,14 @@ FXTableItem* FXRbCallTableItemMethod_gvlcb(FXTable* recv,const char *func,const
13441344
VALUE obj=FXRbGetRubyObj(recv,false);
13451345
FXASSERT(!NIL_P(obj));
13461346
VALUE result=rb_funcall(obj,rb_intern(func),3,to_ruby(text),to_ruby_cb(icon),itemData);
1347-
return NIL_P(result)?0:reinterpret_cast<FXTableItem*>(DATA_PTR(result));
1347+
return (FXTableItem*)FXRbConvertPtr(result, NULL, 0);
13481348
}
13491349

13501350
FXTableItem* FXRbCallTableItemMethod_gvlcb(FXTable* recv,const char *func,FXint row,FXint col,FXbool notify){
13511351
VALUE obj=FXRbGetRubyObj(recv,false);
13521352
FXASSERT(!NIL_P(obj));
13531353
VALUE result=rb_funcall(obj,rb_intern(func),3,to_ruby(row),to_ruby(col),to_ruby(notify));
1354-
return NIL_P(result)?0:reinterpret_cast<FXTableItem*>(DATA_PTR(result));
1354+
return (FXTableItem*)FXRbConvertPtr(result, NULL, 0);
13551355
}
13561356

13571357
//----------------------------------------------------------------------
@@ -1360,7 +1360,7 @@ FXTreeItem* FXRbCallTreeItemMethod_gvlcb(const FXTreeList* recv,const char *func
13601360
VALUE obj=FXRbGetRubyObj(recv,false);
13611361
FXASSERT(!NIL_P(obj));
13621362
VALUE result=rb_funcall(obj,rb_intern(func),2,INT2NUM(x),INT2NUM(y));
1363-
return NIL_P(result) ? 0 : reinterpret_cast<FXTreeItem*>(DATA_PTR(result));
1363+
return (FXTreeItem*)FXRbConvertPtr(result, NULL, 0);
13641364
}
13651365

13661366
//----------------------------------------------------------------------
@@ -1369,7 +1369,7 @@ FXFoldingItem* FXRbCallFoldingItemMethod_gvlcb(const FXFoldingList* recv,const c
13691369
VALUE obj=FXRbGetRubyObj(recv,false);
13701370
FXASSERT(!NIL_P(obj));
13711371
VALUE result=rb_funcall(obj,rb_intern(func),2,INT2NUM(x),INT2NUM(y));
1372-
return NIL_P(result) ? 0 : reinterpret_cast<FXFoldingItem*>(DATA_PTR(result));
1372+
return (FXFoldingItem*)FXRbConvertPtr(result, NULL, 0);
13731373
}
13741374

13751375
//----------------------------------------------------------------------
@@ -1378,7 +1378,7 @@ FXFileAssoc* FXRbCallFileAssocMethod_gvlcb(const FXFileDict* recv,const char *fu
13781378
VALUE obj=FXRbGetRubyObj(recv,false);
13791379
FXASSERT(!NIL_P(obj));
13801380
VALUE result=rb_funcall(obj,rb_intern(func),1,to_ruby(pathname));
1381-
return NIL_P(result) ? 0 : reinterpret_cast<FXFileAssoc*>(DATA_PTR(result));
1381+
return (FXFileAssoc*)FXRbConvertPtr(result, NULL, 0);
13821382
}
13831383

13841384
//----------------------------------------------------------------------
@@ -1388,7 +1388,7 @@ FXIcon* FXRbCallIconMethod_gvlcb(const FXTableItem* recv,const char *func){
13881388
FXASSERT(!NIL_P(obj));
13891389
if(!NIL_P(obj)){
13901390
VALUE result=rb_funcall(obj,rb_intern(func),0);
1391-
return NIL_P(result) ? 0 : reinterpret_cast<FXIcon*>(DATA_PTR(result));
1391+
return (FXIcon*)FXRbConvertPtr(result, NULL, 0);
13921392
}
13931393
else{
13941394
return 0;
@@ -1401,7 +1401,7 @@ FXWindow* FXRbCallWindowMethod_gvlcb(const FXTableItem* recv,const char *func,FX
14011401
VALUE obj=FXRbGetRubyObj(recv,false);
14021402
FXASSERT(!NIL_P(obj));
14031403
VALUE result=rb_funcall(obj,rb_intern(func),1,to_ruby_cb(table));
1404-
return NIL_P(result) ? 0 : reinterpret_cast<FXWindow*>(DATA_PTR(result));
1404+
return (FXWindow*)FXRbConvertPtr(result, NULL, 0);
14051405
}
14061406

14071407
//----------------------------------------------------------------------
@@ -1411,7 +1411,7 @@ FXRangef FXRbCallRangeMethod_gvlcb(FXObject* recv,const char *func){
14111411
VALUE obj=FXRbGetRubyObj(recv,false);
14121412
FXASSERT(!NIL_P(obj));
14131413
VALUE result=rb_funcall(obj,rb_intern(func),0);
1414-
return *reinterpret_cast<FXRangef*>(DATA_PTR(result));
1414+
return *(FXRangef*)FXRbConvertPtr(result, NULL, 0);
14151415
}
14161416

14171417
//----------------------------------------------------------------------
@@ -1606,11 +1606,34 @@ FXbool FXRbGLViewer::sortProc(FXfloat*& buffer,FXint& used,FXint& size){
16061606
* FXRbConvertPtr() is just a wrapper around SWIG_ConvertPtr().
16071607
*/
16081608

1609-
void* FXRbConvertPtr(VALUE obj,swig_type_info* ty){
1609+
void* FXRbConvertPtr(VALUE obj,swig_type_info* ty, int flags){
16101610
void *ptr;
1611-
SWIG_ConvertPtr(obj,&ptr,ty,1);
1612-
return ptr;
1611+
int res = SWIG_ConvertPtr(obj,&ptr,ty,flags);
1612+
if( res == SWIG_OK ) return ptr;
1613+
#ifdef HAVE_RB_DURING_GC
1614+
if( rb_during_gc() ){
1615+
rb_bug( "FXRbConvertPtr got wrong argument type rubyObj=%p", (void*)obj);
16131616
}
1617+
#endif
1618+
if( res == SWIG_ERROR_RELEASE_NOT_OWNED ){
1619+
rb_raise( rb_eTypeError, "clean and disown of non-owned object is not allowed: %" PRIsVALUE, obj);
1620+
}
1621+
if( res == SWIG_NullReferenceError ){
1622+
rb_raise( rb_eTypeError, "object can not be NULL: %" PRIsVALUE, obj);
1623+
}
1624+
if( res == SWIG_ObjectPreviouslyDeletedError ){
1625+
if(ty){
1626+
rb_raise( rb_eTypeError, "the object has already been deleted: %" PRIsVALUE, ((swig_class *) (ty->clientdata))->klass);
1627+
} else {
1628+
rb_raise( rb_eTypeError, "the object has already been deleted");
1629+
}
1630+
}
1631+
if(ty){
1632+
rb_raise( rb_eTypeError, "wrong argument type %" PRIsVALUE ", expected kind of %" PRIsVALUE, rb_obj_class(obj), ((swig_class *) (ty->clientdata))->klass );
1633+
} else {
1634+
rb_raise( rb_eTypeError, "wrong argument type %" PRIsVALUE, rb_obj_class(obj) );
1635+
}
1636+
}
16141637

16151638

16161639
// Returns an FXInputHandle for this Ruby file object

ext/fox16_c/extconf.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ def install
366366
if RbConfig::MAKEFILE_CONFIG['CC'] =~ /gcc/
367367
$CXXFLAGS += " -Wno-unused-function"
368368
$CXXFLAGS += " -Wno-maybe-uninitialized"
369-
$CXXFLAGS += " -Wno-attribute-warning -Wno-deprecated-declarations"
369+
$CXXFLAGS += " -Wno-attribute-warning"
370370
end
371371

372372
# Last step: build the makefile

ext/fox16_c/gvl_wrappers.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*
44
*/
55

6+
#include "swigruby.h"
67
#include "FXRbCommon.h"
78

89
#ifdef HAVE___THREAD

ext/fox16_c/impl.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include "swigruby.h"
12
#include "FXRbCommon.h"
23
/* Start stub implementations for class FXMemoryBuffer */
34

ext/fox16_c/include/FXRbDCWindow.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class FXRbDCWindow : public FXDCWindow {
4444

4545
// Helper for FXDCWindow initialization block
4646
static VALUE endit(VALUE obj){
47-
FXDCWindow* dc=reinterpret_cast<FXDCWindow*>(DATA_PTR(obj));
47+
FXDCWindow* dc=(FXDCWindow*)FXRbConvertPtr(obj, NULL, 0);
4848
FXASSERT(dc!=0);
4949
dc->end();
5050
return Qnil;

ext/fox16_c/include/FXRuby.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ static int FXSWIG_ConvertPtr(VALUE obj, void **ptr, swig_type_info *ty, int flag
4848
template <class TYPE>
4949
VALUE showHelper(VALUE self, int argc, VALUE *argv, TYPE *p, swig_type_info *typeinfo) {
5050
TYPE *win;
51-
FXSWIG_ConvertPtr(self,(void**)&win,typeinfo,1);
51+
FXSWIG_ConvertPtr(self,(void**)&win,typeinfo,SWIG_POINTER_DISOWN);
5252
if (argc == 0) {
5353
win->_show();
5454
}
@@ -73,7 +73,7 @@ bool FXRbIsInGC(const void* ptr);
7373
swig_type_info *FXRbTypeQuery(const char *name);
7474

7575
// Wrapper around SWIG_ConvertPtr()
76-
void* FXRbConvertPtr(VALUE obj,swig_type_info* typeinfo);
76+
void* FXRbConvertPtr(VALUE obj,swig_type_info* typeinfo, int flags);
7777

7878
// Returns an FXInputHandle for this Ruby file object
7979
FXInputHandle FXRbGetReadFileHandle(VALUE obj,FXuint mode);
@@ -694,15 +694,15 @@ FXIcon* FXRbCallIconMethod_gvlcb(const FXIconSource *recv,const char *func,TYPE1
694694
VALUE obj=FXRbGetRubyObj(recv,false);
695695
FXASSERT(!NIL_P(obj));
696696
VALUE result=rb_funcall(obj,rb_intern(func),2,to_ruby(arg1),to_ruby(arg2));
697-
return NIL_P(result) ? 0 : reinterpret_cast<FXIcon*>(DATA_PTR(result));
697+
return (FXIcon*)FXRbConvertPtr(result, NULL, 0);
698698
}
699699

700700
template<class TYPE1, class TYPE2, class TYPE3, class TYPE4>
701701
FXIcon* FXRbCallIconMethod_gvlcb(const FXIconSource *recv,const char *func,TYPE1& arg1,TYPE2 arg2,TYPE3 arg3,const TYPE4& arg4){
702702
VALUE obj=FXRbGetRubyObj(recv,false);
703703
FXASSERT(!NIL_P(obj));
704704
VALUE result=rb_funcall(obj,rb_intern(func),4,to_ruby(arg1),to_ruby(arg2),to_ruby(arg3),to_ruby(arg4));
705-
return NIL_P(result) ? 0 : reinterpret_cast<FXIcon*>(DATA_PTR(result));
705+
return (FXIcon*)FXRbConvertPtr(result, NULL, 0);
706706
}
707707

708708
// Call functions with FXImage* return value
@@ -711,15 +711,15 @@ FXImage* FXRbCallImageMethod_gvlcb(const FXIconSource *recv,const char *func,TYP
711711
VALUE obj=FXRbGetRubyObj(recv,false);
712712
FXASSERT(!NIL_P(obj));
713713
VALUE result=rb_funcall(obj,rb_intern(func),2,to_ruby(arg1),to_ruby(arg2));
714-
return NIL_P(result) ? 0 : reinterpret_cast<FXImage*>(DATA_PTR(result));
714+
return (FXImage*)FXRbConvertPtr(result, NULL, 0);
715715
}
716716

717717
template<class TYPE1, class TYPE2, class TYPE3, class TYPE4>
718718
FXImage* FXRbCallImageMethod_gvlcb(const FXIconSource *recv,const char *func,TYPE1& arg1,TYPE2 arg2,TYPE3 arg3,const TYPE4& arg4){
719719
VALUE obj=FXRbGetRubyObj(recv,false);
720720
FXASSERT(!NIL_P(obj));
721721
VALUE result=rb_funcall(obj,rb_intern(func),4,to_ruby(arg1),to_ruby(arg2),to_ruby(arg3),to_ruby(arg4));
722-
return NIL_P(result) ? 0 : reinterpret_cast<FXImage*>(DATA_PTR(result));
722+
return (FXImage*)FXRbConvertPtr(result, NULL, 0);
723723
}
724724

725725
// Call functions with "FXWindow*" return value

0 commit comments

Comments
 (0)