Ruby opaque pointer handling regression fix
This bug was introduced in swig-3.0.8 in #146252 adding shared_ptr support. An ObjectPreviouslyDeleted error was incorrectly thrown when the pointer was used as a parameter after being set to zero via a call to 'DATA_PTR(self) = 0'. It isn't clear to me which approach is better in this corner case, so I've gone for backwards compatibility and restored the old behaviour. Closes #602
This commit is contained in:
parent
dc1fad3f9b
commit
763827c2e1
5 changed files with 131 additions and 5 deletions
|
|
@ -30,7 +30,8 @@ CPP_TEST_CASES = \
|
|||
# stl_new
|
||||
|
||||
C_TEST_CASES += \
|
||||
li_cstring
|
||||
li_cstring \
|
||||
ruby_manual_proxy \
|
||||
|
||||
include $(srcdir)/../common.mk
|
||||
|
||||
|
|
|
|||
49
Examples/test-suite/ruby/ruby_manual_proxy_runme.rb
Normal file
49
Examples/test-suite/ruby/ruby_manual_proxy_runme.rb
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
#!/usr/bin/env ruby
|
||||
#
|
||||
# The Subversion bindings use this manually written proxy class approach
|
||||
# to the Ruby bindings. Note that in C the struct svn_fs_t is an
|
||||
# opaque pointer and the Ruby FileSystem proxy class is hand written around it.
|
||||
# This testcase tests this and the C close function and subsequent error
|
||||
# handling.
|
||||
|
||||
require 'swig_assert'
|
||||
require 'ruby_manual_proxy'
|
||||
|
||||
module Svn
|
||||
module Fs
|
||||
module_function
|
||||
def create(path)
|
||||
f = Ruby_manual_proxy::svn_fs_create(path)
|
||||
return f
|
||||
end
|
||||
|
||||
FileSystem = SWIG::TYPE_p_svn_fs_t
|
||||
class FileSystem
|
||||
class << self
|
||||
def create(*args)
|
||||
Fs.create(*args)
|
||||
end
|
||||
end
|
||||
def path
|
||||
Ruby_manual_proxy::svn_fs_path(self)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
f = Svn::Fs::FileSystem.create("/tmp/myfile")
|
||||
path = f.path
|
||||
f.close
|
||||
begin
|
||||
# regression in swig-3.0.8 meant ObjectPreviouslyDeleted error was thrown instead
|
||||
path = f.path
|
||||
raise RuntimeError.new("IOError (1) not thrown")
|
||||
rescue IOError
|
||||
end
|
||||
|
||||
file = nil
|
||||
begin
|
||||
path = Ruby_manual_proxy::svn_fs_path(file)
|
||||
raise RuntimeError.new("IOError (2) not thrown")
|
||||
rescue IOError
|
||||
end
|
||||
66
Examples/test-suite/ruby_manual_proxy.i
Normal file
66
Examples/test-suite/ruby_manual_proxy.i
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
%module ruby_manual_proxy
|
||||
|
||||
|
||||
%typemap(in, numinputs=0) SWIGTYPE ** ($*1_ltype temp) "$1 = &temp;";
|
||||
|
||||
%typemap(argout) SWIGTYPE **OUTPARAM {
|
||||
$result = SWIG_Ruby_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0));
|
||||
}
|
||||
|
||||
%apply SWIGTYPE **OUTPARAM {
|
||||
svn_fs_t **
|
||||
};
|
||||
|
||||
%typemap(check) svn_fs_t * {
|
||||
if (!$1) {
|
||||
svn_swig_rb_raise_svn_fs_already_close();
|
||||
}
|
||||
}
|
||||
|
||||
%{
|
||||
typedef struct svn_fs_t {
|
||||
char path[256];
|
||||
} svn_fs_t;
|
||||
|
||||
void svn_fs_create(svn_fs_t **fs_p, const char *path) {
|
||||
svn_fs_t *fs = (svn_fs_t *)malloc(sizeof(svn_fs_t));
|
||||
strncpy(fs->path, path, 256);
|
||||
*fs_p = fs;
|
||||
}
|
||||
const char *svn_fs_path(svn_fs_t *fs) {
|
||||
return fs->path;
|
||||
}
|
||||
%}
|
||||
|
||||
typedef struct svn_fs_t svn_fs_t;
|
||||
void svn_fs_create(svn_fs_t **fs_p, const char *path);
|
||||
const char *svn_fs_path(svn_fs_t *fs);
|
||||
|
||||
%{
|
||||
static void svn_swig_rb_raise_svn_fs_already_close(void) {
|
||||
rb_raise(rb_eIOError, "already closed");
|
||||
}
|
||||
|
||||
static VALUE svn_fs_swig_rb_close(VALUE self) {
|
||||
if (!DATA_PTR(self)) {
|
||||
svn_swig_rb_raise_svn_fs_already_close();
|
||||
}
|
||||
|
||||
DATA_PTR(self) = NULL;
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE svn_fs_swig_rb_closed(VALUE self) {
|
||||
return DATA_PTR(self) ? Qfalse : Qtrue;
|
||||
}
|
||||
%}
|
||||
|
||||
%insert("init") %{
|
||||
{
|
||||
VALUE cSvnfs;
|
||||
cSvnfs = rb_const_get(_mSWIG, rb_intern("TYPE_p_svn_fs_t"));
|
||||
rb_define_method(cSvnfs, "close",
|
||||
VALUEFUNC(svn_fs_swig_rb_close), 0);
|
||||
}
|
||||
%}
|
||||
Loading…
Add table
Add a link
Reference in a new issue