A bc_num that is zero must carry PLUS, since bc_compare() orders by sign
first. The bc_divide() fast paths for a divisor of +/-1 or a power of ten,
bc_raise() with a positive exponent, and the Number add/sub/mul helpers
truncate to the requested scale and keep the operand sign, so
(new BcMath\Number('-0.001'))->div(1, 0) compares less than 0, is not
equal to 0, and makes sqrt() throw.
Closes GH-23967
Number::compare() may request a scale greater than the stored scale of a
zero result when the opposite operand has a larger scale. The helper then
walked past the shorter digit buffer.
Clamp the requested scale to the digits stored in the number.
Closes GH-23185
When a fraction is truncated to a caller-supplied scale and then re-trimmed of
trailing zeros, str_scale was reduced but fractional_end was not, so
bc_copy_and_toggle_bcd() copied more bytes than were reserved by
bc_new_num_nonzeroed(). With small numbers allocated from the 256-byte stack
arena this is a stack-based OOB write reachable via bccomp($num1, $num2,
$scale), e.g. bccomp("1.901", "0", 2).
Keep fractional_end in sync with str_scale so the copy length matches the
reserved length.
Fixes GHSA-x692-q9x7-8c3f
Fix ASAN issue withh entry points passed $precision to bc_round()
unchecked, allowing PHP_INT_MAX / PHP_INT_MIN to trigger oversized
allocations and signed overflow in libbcmath/src/round.c.
closes#22182
There are several issues with this macro:
- It is incorrectly named: It's not an empty default case. It's an unreachable
default case.
- It is hiding control flow in its definition, which can be confusing for
humans and tools (such as Coccinelle) alike, because it looks like it would
be a statement that belongs to the "current" case rather than opening a new
one.
Since this macro is exactly as long as explicitly spelling out its definition
(excluding the useless `break;`), it is not even making the code any more
succinct.
Update gen_stubs.php to generate C enums from internal enums, when the stub is annotated with @generate-c-enums. Enum values can be compared to the result of zend_enum_fetch_case_id(zend_object*).
The generated enums are added to separate files named {$extensionName}_decl.h, so that it's possible to include these from anywhere. _arginfo.h files would generate warnings if we tried to include them in a compilation unit that doesn't call the register_{$class} functions, for instance.
Introduce Z_PARAM_ENUM().
* Make ZEND_AST_CONST_ENUM_INIT a 4-children node
* Store enum case id in ZEND_AST_CONST_ENUM_INIT
* Store enum case id in instance
* Expose enum case_id internally
* Generate C enum for internal enums
* Introduce Z_PARAM_ENUM()
* Port extensions