Project

Profile

Help

Bug #6338

closed

Segmentation fault in PHP when calling getHead() twice on XdmValue

Added by O'Neil Delpratt 10 months ago. Updated 5 months ago.

Status:
Closed
Priority:
Normal
Category:
PHP API
Start date:
2024-02-05
Due date:
% Done:

100%

Estimated time:
Applies to branch:
Fix Committed on Branch:
12
Fixed in Maintenance Release:
Found in version:
12.4.2
Fixed in version:
12.5
SaxonC Languages:
SaxonC Platforms:
SaxonC Architecture:

Description

The following PHPUnit test case:

...
        if ($result->getHead() != NULL) {
            $this->assertStringContainsString("[]", $result->getHead()->getStringValue());
        }

Throws the following error under gdb:

Thread 1 "php" received signal SIGSEGV, Segmentation fault.
0x00007ffff31a8e69 in zim_XdmValue_getHead(_zend_execute_data*, _zval_struct*) () from /usr/lib/php/20220829/saxon.so
Actions #1

Updated by O'Neil Delpratt 10 months ago

  • Category set to PHP API
  • Status changed from New to In Progress

In the C++ code to avoid the dangling pointer issue we introduced some new logic to relinquish items from the XdmValue to the caller once they have been accessed. If we do not assign to a variable the calls to methods such as getHead() PHP may call the GC therefore calling the getHead() method again will cause a segmentation fault because the XdmItem object has been deleted.

The workaroun is to assign the above example to a variable:

        $head1 =  $result->getHead();
        if ($head1 != NULL) {
            $this->assertStringContainsString("[]", $head1->getStringValue());
        }

It is possible this affects Python too.

Actions #2

Updated by O'Neil Delpratt 10 months ago

  • Status changed from In Progress to Resolved
  • % Done changed from 0 to 100

Confirmed that this issue affect python. I have pushed a similar fix in the Python code. Fix available in the maintenance release.

Added some pytest tests.

Actions #3

Updated by O'Neil Delpratt 10 months ago

  • Status changed from Resolved to In Progress

Discovered similar problem when creating a PyXdmValue from items:

from saxoncee import *

saxonproc = PySaxonProcessor(license=True)

xdm_value = PyXdmValue()

xdm_value.add_xdm_item(saxonproc.make_string_value('foo'))

print(xdm_value)
xdm_value.add_xdm_item(saxonproc.make_string_value('bar'))

print(xdm_value)

This issue has been resolved. The next problem is when we assign the created PyXdmAtomicValue to a variable before we add it to PyXdmValue the ref count does not go to zero and therefore does not get garbage collected:

xdm_value = PyXdmValue()

item1 = saxonproc.make_string_value('foo')
xdm_value.add_xdm_item(item1)


print(xdm_value)
Actions #4

Updated by O'Neil Delpratt 10 months ago

  • Status changed from In Progress to Resolved

Bug now fixed.

Actions #5

Updated by O'Neil Delpratt 5 months ago

  • Status changed from Resolved to Closed
  • Fixed in version set to 12.5

Bug fix applied in the Saxon 12.5 Maintenance release.

Actions #6

Updated by Community Admin 5 months ago

  • Fix Committed on Branch 12 added

Please register to edit this issue

Also available in: Atom PDF