Fix zero handling in BCMath division and power operations#31
Conversation
- Fix checkDivisionByZero to handle decimal zero formats ('0.00', '-0.00')
- Add zero base handling for BCMath::pow to prevent infinite loops with negative exponents
- Add comprehensive test coverage for bcdiv division by zero cases
- Add parameterized tests for BCMath::pow zero base scenarios using DataProvider
- Remove bcpow from CI skip list to enable php-src compatibility tests
Fixes phpseclib internal errors and infinite loops when processing
zero values in various decimal formats.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <[email protected]>
Updated the `bcpowZeroBaseProvider` method to `provideBcpowZeroBaseCases` and changed its return type from `array` to `iterable` for better flexibility. Adjusted the corresponding test annotation to reflect the new method name.
Code Review: Fix zero handling in BCMath division and power operationsOverall Assessment ✅This is a well-implemented fix that addresses critical zero-handling bugs in the BCMath polyfill. The changes are focused, thoroughly tested, and maintain backward compatibility. Strengths 🎯1. Robust Zero Detection LogicThe enhanced zero detection in both
2. Excellent Test Coverage
3. Performance Considerations
Code Quality Observations 📋1. Code Duplication OpportunityThe zero normalization logic is duplicated between // Duplicated in both methods:
$normalized = ltrim($divisor, '+-');
$normalized = ltrim($normalized, '0');
$normalized = ltrim($normalized, '.');
$normalized = rtrim($normalized, '0');Recommendation: Consider extracting this to a private helper method: private static function isZero(string $number): bool
{
$normalized = ltrim($number, '+-');
$normalized = ltrim($normalized, '0');
$normalized = ltrim($normalized, '.');
$normalized = rtrim($normalized, '0');
return $normalized === '' || $normalized === '.';
}2. Edge Case ConsiderationThe normalization handles most cases well, but consider these edge cases:
3. DocumentationThe inline comments are clear and explain the logic well. The PR description is exemplary in its thoroughness. Security & Safety ✅
Performance Analysis 🚀
Compatibility Assessment 🔧
Minor Suggestions 💡
Test Plan Verification ✅The test plan is comprehensive:
Recommendation: APPROVE ✅This PR successfully fixes critical bugs while maintaining high code quality standards. The implementation is robust, well-tested, and follows the project's coding conventions as outlined in CLAUDE.md. Impact: Resolves infinite loops and crashes → Improves library reliability significantly. |
Summary
This PR addresses critical zero handling issues in
BCMath::div()andBCMath::pow()that were causing infinite loops and phpseclib internal errors when processing various zero formats.Issues Fixed
🐛 Division by Zero Detection
checkDivisionByZero()only detected'0', missing decimal formats like'0.00','-0.00'bcdiv_error1.phpfailed with infinite loops and phpseclib errors🔄 Power Operation Infinite Loops
BCMath::pow()with zero base and negative exponents caused infinite loopsbcpow('0', '-1')hung indefinitely with phpseclib internal errorsChanges Made
Core Fixes
checkDivisionByZero(): Now properly detects'0','0.00','-0.00','+0.000', etc.BCMath::pow(): Prevents infinite loops with negative exponentsTest Coverage
bcdiv_error1.phpCI Integration
bcpowfrom CI skip listTechnical Details
Zero Detection Algorithm
Zero Base Power Handling
Test Results
Before
docker run bcmath-test-without php tests/php-src/bcdiv_error1.php→ Infinite loop with phpseclib errorsBCMath::pow('0', '-1', 2)→ Hung indefinitelyAfter
bcdiv_error1.phpoutputs:Division by zero× 3 (as expected)BCMath::pow('0', '-1', 2)returns:0.00Compatibility
bcdiv_error1.phpandbcpow.phptests passTest plan
docker run --rm -v $PWD:/app bcmath-test-without php tests/php-src/bcdiv_error1.php- outputs 3 "Division by zero" messagesdocker run --rm -v $PWD:/app bcmath-test-without php tests/php-src/bcpow.php- completes without errorsvendor/bin/phpunit --filter="testBcdiv.*Zero"- 3/3 tests passvendor/bin/phpunit --filter="testBcpow.*Zero"- 12/12 tests passvendor/bin/phpstan analyse- No errors🤖 Generated with Claude Code