diff options
author | Olly Betts <olly@survex.com> | 2021-05-03 16:07:50 +1200 |
---|---|---|
committer | Olly Betts <olly@survex.com> | 2021-05-03 16:07:50 +1200 |
commit | 81d1618777a470548e0e2afcf0b0bbc4893b08c1 (patch) | |
tree | 477e7f2960ecdb09a5b7ef06774af8bdb46d25ea | |
parent | 04bacf689b5c9ddc5b6d3ef84c281c3a499a00ad (diff) | |
download | swig-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.php | 19 |
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(); |