Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unary operators on ranges no longer allow coercion of non-numeric array elements #3389

Closed
1 of 8 tasks
martinf55 opened this issue Feb 21, 2023 · 1 comment · Fixed by #3392
Closed
1 of 8 tasks

Unary operators on ranges no longer allow coercion of non-numeric array elements #3389

martinf55 opened this issue Feb 21, 2023 · 1 comment · Fixed by #3392

Comments

@martinf55
Copy link

martinf55 commented Feb 21, 2023

This is:

- [x] a bug report
- [ ] a feature request
- [ ] **not** a usage question (ask them on https://stackoverflow.com/questions/tagged/phpspreadsheet or https://gitter.im/PHPOffice/PhpSpreadsheet)

What is the expected behavior?

Unary operators on arrays used to allow coercible non-numeric array elements such as boolean. This is the case in the replaced Shared/JAMA code, mirroring behaviour in Excel.

What is the current behavior?

Any array elements which are non-numeric are replaced with a #VALUE error.

The simplified code which replaced JAMA in #3260 requires all array elements to be is_numeric. The old behaviour was similar to validateBinaryOperand() in that it assumed non-strings would coerce to numeric and only did further validation on strings.

What are the steps to reproduce?

Please provide a Minimal, Complete, and Verifiable example of code that exhibits the issue without relying on an external Excel file or a web server:

<?php

require __DIR__ . '/vendor/autoload.php';

$inputFileName = './UnaryOperatorIssue.xlsx';

/** Load $inputFileName to a Spreadsheet object **/
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($inputFileName);

$spreadsheet->getCalculationEngine()->getDebugLog()->setWriteDebugLog(true);

$blueResultCell = $spreadsheet->getActiveSheet()->getCell('E3');
$redResultCell = $spreadsheet->getActiveSheet()->getCell('F3');

$blueResultValueOld = $blueResultCell->getOldCalculatedValue();
$redResultValueOld = $redResultCell->getOldCalculatedValue();

$blueResultValue = $blueResultCell->getCalculatedValue(false);
$redResultValue = $redResultCell->getCalculatedValue(false);

print_r("Blue matches: Old {$blueResultValueOld} vs Calculated {$blueResultValue}\n");
print_r("Red matches:  Old {$redResultValueOld} vs Calculated {$redResultValue}\n");

$log = $spreadsheet->getCalculationEngine()->getDebugLog()->getLog();

print_r($log);

Running this produces:

Blue matches: Old 3 vs Calculated 0
Red matches:  Old 2 vs Calculated 0
(log omitted)

What features do you think are causing the issue

  • Reader
  • Writer
  • Styles
  • Data Validations
  • Formula Calculations
  • Charts
  • AutoFilter
  • Form Elements

Does an issue affect all spreadsheet file formats? If not, which formats are affected?

All formats.

Which versions of PhpSpreadsheet and PHP are affected?

PhpSpreadsheet 1.26
PHP 8.1

UnaryOperatorIssue.xlsx

@oleibman
Copy link
Collaborator

Thank you for the file and the excellent documentation. I believe your suggestion to add an is_bool test is sufficient. I should have a PR tonight.

oleibman added a commit to oleibman/PhpSpreadsheet that referenced this issue Feb 22, 2023
Fix PHPOffice#3389. It seems some functionality was left behind when JAMA was eliminated (PR PHPOffice#3260). In particular, it is apparently a known trick to use double negation on boolean values as arguments to functions like SUMPRODUCT.
oleibman added a commit that referenced this issue Feb 24, 2023
* Coerce Bool to Int for Unary Operation on Arrays

Fix #3389. It seems some functionality was left behind when JAMA was eliminated (PR #3260). In particular, it is apparently a known trick to use double negation on boolean values as arguments to functions like SUMPRODUCT.

* Fix 3396

Treat booleans in arrays as int for mathematical operators as well.

* Edge Case

When array operand was neither numeric nor boolean, PhpSpreadsheet had always been evaluating the operand as #NUM!. It will now propagate an error string like #DIV/0!, and treat non-error strings as #VALUE!, consistent with Excel.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

2 participants