Fix segfault in do_operation handler (ext-decimal 2.0.x)#96
Fix segfault in do_operation handler (ext-decimal 2.0.x)#96rtheunissen merged 1 commit intophp-decimal:masterfrom
Conversation
|
Using it to make pass https://gitlab.alpinelinux.org/alpine/aports/-/merge_requests/100779 |
This is not a PHP 8.5-only issueAfter further investigation, the The bug is in ext-decimal 2.0.x, introduced in commit b8b4420 (Jan 2019, "Alpha implementation of Number and Rational") when the unsupported-operator handling was changed from the 1.x behavior:
The |
|
Tested other branches and since PHP 8.2 all extension needs this patch |
Bug was introduced in commit b8b4420 ("Alpha implementation of Number and Rational", Jan 2019) which changed unsupported-operator handling from return FAILURE (1.x) to throw ArithmeticError + return SUCCESS with result zval left uninitialized. The ZEND_TRY_BINARY_OBJECT_OPERATION macro in Zend engine has called do_operation for all operator types (including CONCAT, BW_OR) since PHP 5.6 (commit 089f4967997, Oct 2014). When do_operation throws an exception but returns SUCCESS without initializing result, the VM's exception handler crashes in zval_delref_p. This affects all PHP versions (8.2+), not only PHP 8.5. Fix by setting result to UNDEF before returning SUCCESS for unsupported operators, so the exception handler safely skips cleanup. Co-Authored-By: GLM-5.1 <noreply@z.ai>
|
Thanks @andypost! |
Summary
do_operationhandler segfaults when encountering unsupported opcodes (ZEND_CONCAT,ZEND_BW_OR, etc.)ArithmeticErrorand returnsSUCCESSwithout initializing theresultzval, causing the VM's exception handler to crash inzval_delref_pZVAL_UNDEF(result)before returningSUCCESSfor unsupported operatorsRoot Cause
This bug was introduced in commit
b8b4420(Jan 2019, "Alpha implementation of Number and Rational") when the unsupported-operator handling was changed from the 1.x behavior:return FAILURE;— engine falls through to type juggling (casting object to string/int)ArithmeticError+return SUCCESS+resultleft uninitialized — engine skips type juggling but crashes cleaning up the garbageresultzvalThis affects all PHP versions (8.2+), not only PHP 8.5. The
concat_function→do_operation(ZEND_CONCAT)call path has existed since PHP 5.6 (commit089f4967997, Oct 2014). TheZEND_TRY_BINARY_OBJECT_OPERATIONmacro is identical between PHP 8.4 and 8.5.Test Plan
Decimal/operators.phpt,Number/operators.phpt,Rational/operators.phptnow pass+,-,*,/,%,**,<<,>>)