summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlly Betts <olly@survex.com>2021-05-03 16:07:50 +1200
committerOlly Betts <olly@survex.com>2021-05-03 16:07:50 +1200
commit81d1618777a470548e0e2afcf0b0bbc4893b08c1 (patch)
tree477e7f2960ecdb09a5b7ef06774af8bdb46d25ea
parent04bacf689b5c9ddc5b6d3ef84c281c3a499a00ad (diff)
downloadswig-81d1618777a470548e0e2afcf0b0bbc4893b08c1.tar.gz
Adjust director_finalizer_runme.php
Without inventing a SWIG/PHP-specific mechanism, we can't really finalise objects in the way the testcase expects, so adjust the testcase minimally so we avoid triggering C++ undefined behaviour (use-after-free).
-rw-r--r--Examples/test-suite/php/director_finalizer_runme.php19
1 files changed, 14 insertions, 5 deletions
diff --git a/Examples/test-suite/php/director_finalizer_runme.php b/Examples/test-suite/php/director_finalizer_runme.php
index cd5f23d1d..c149fd318 100644
--- a/Examples/test-suite/php/director_finalizer_runme.php
+++ b/Examples/test-suite/php/director_finalizer_runme.php
@@ -12,7 +12,12 @@ check::globals(array());
class MyFoo extends Foo {
function __destruct() {
- $this->orStatus(2);
+ # It's not safe to call methods on the C++ object from the PHP destructor
+ # if the object has been disowned, since the C++ object will already have
+ # been destroyed by the time the PHP destructor runs.
+ if ($this->thisown) {
+ $this->orStatus(2);
+ }
if (method_exists(get_parent_class(), "__destruct")) {
parent::__destruct();
}
@@ -41,19 +46,23 @@ resetStatus();
$a = new MyFoo();
$a->thisown = 0;
+check::equal(getStatus(), 0, "shadow release does not fire destructor of disowned object");
+
deleteFoo($a);
unset($a);
-check::equal(getStatus(), 3, "getStatus() failed #4");
+# getStatus() would ideally return 3 here.
+check::equal(getStatus(), 1, "getStatus() failed #4");
resetStatus();
$a = new MyFoo();
$a->thisown = 0;
-deleteFoo(launder($a));
+$g = launder($a);
unset($a);
-
-check::equal(getStatus(), 3, "getStatus() failed #5");
+deleteFoo($g);
+# getStatus() would ideally return 3 here.
+check::equal(getStatus(), 1, "getStatus() failed #5");
resetStatus();