summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Bagnall <douglas.bagnall@catalyst.net.nz>2019-10-29 11:58:32 +1300
committerNoel Power <npower@samba.org>2019-11-14 16:12:40 +0000
commit1261894ecaebc1a3340c42e818be25caa69f6364 (patch)
tree173178f02f390700f653a95b4bb7e7262ce401ac
parent7e19779b66d7329e4208eaa5801cec0b6feb3754 (diff)
downloadsamba-1261894ecaebc1a3340c42e818be25caa69f6364.tar.gz
pidl/python: allocate objects with ref pointers
Struct members that are marked as ref pointers need to have an object allocated for them. Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> Pair-programmed-with: Andrew Bartlett <abartlet@samba.org> Signed-off-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Noel Power <npower@samba.org>
-rw-r--r--pidl/lib/Parse/Pidl/Samba4/Python.pm57
-rw-r--r--selftest/knownfail.d/python-segfaults2
2 files changed, 56 insertions, 3 deletions
diff --git a/pidl/lib/Parse/Pidl/Samba4/Python.pm b/pidl/lib/Parse/Pidl/Samba4/Python.pm
index 8d5de31e7bb..fbb61c33580 100644
--- a/pidl/lib/Parse/Pidl/Samba4/Python.pm
+++ b/pidl/lib/Parse/Pidl/Samba4/Python.pm
@@ -499,7 +499,62 @@ sub PythonFunctionStruct($$$$)
$self->pidl("static PyObject *py_$name\_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)");
$self->pidl("{");
$self->indent;
- $self->pidl("return pytalloc_new($cname, type);");
+
+ # This creates a new, zeroed C structure and python object.
+ # Thse may not be valid or sensible values, but this is as
+ # well as we can do.
+
+ $self->pidl("PyObject *self = pytalloc_new($cname, type);");
+
+ # If there are any children that are ref pointers, we need to
+ # allocate something for them to point to just as the pull
+ # routine will when parsing the stucture from NDR.
+ #
+ # We then make those pointers point to zeroed memory
+ #
+ # A ref pointer is a pointer in the C structure but a scalar
+ # on the wire. It is for a remote function like:
+ #
+ # int foo(int *i)
+ #
+ # This may be called with the pointer by reference eg foo(&i)
+ #
+ # That is why this only goes as far as the next level; deeply
+ # nested pointer chains will end in a NULL.
+
+ my @ref_elements;
+ foreach my $e (@{$fn->{ELEMENTS}}) {
+ if (has_property($e, "ref") && ! has_property($e, "charset")) {
+ if (!has_property($e, 'in') && !has_property($e, 'out')) {
+ die "ref pointer that is not in or out";
+ }
+ push @ref_elements, $e;
+ }
+ }
+ if (@ref_elements) {
+ $self->pidl("$cname *_self = ($cname *)pytalloc_get_ptr(self);");
+ $self->pidl("TALLOC_CTX *mem_ctx = pytalloc_get_mem_ctx(self);");
+ foreach my $e (@ref_elements) {
+ my $ename = $e->{NAME};
+ my $t = mapTypeName($e->{TYPE});
+ my $p = $e->{ORIGINAL}->{POINTERS} // 1;
+ if ($p > 1) {
+ $self->pidl("/* a pointer to a NULL pointer */");
+ $t .= ' ' . '*' x ($p - 1);
+ }
+
+ # We checked in the loop above that each ref
+ # pointer is in or out (or both)
+ if (has_property($e, 'in')) {
+ $self->pidl("_self->in.$ename = talloc_zero(mem_ctx, $t);");
+ }
+
+ if (has_property($e, 'out')) {
+ $self->pidl("_self->out.$ename = talloc_zero(mem_ctx, $t);");
+ }
+ }
+ }
+ $self->pidl("return self;");
$self->deindent;
$self->pidl("}");
$self->pidl("");
diff --git a/selftest/knownfail.d/python-segfaults b/selftest/knownfail.d/python-segfaults
index 671de9be4a2..e100356553d 100644
--- a/selftest/knownfail.d/python-segfaults
+++ b/selftest/knownfail.d/python-segfaults
@@ -1,4 +1,2 @@
samba.tests.segfault.samba.tests.segfault.SegfaultTests.test_net_replicate_init__3
-samba.tests.segfault.samba.tests.segfault.SegfaultTests.test_dcerpc_idl_ref_elements
-samba.tests.segfault.samba.tests.segfault.SegfaultTests.test_dcerpc_idl_unixinfo_elements
samba.tests.segfault.samba.tests.segfault.SegfaultTests.test_dcerpc_idl_inline_arrays