Fix MAXPOOL and MEDIANPOOL throwing on non-tiling dimensions - #1718
Draft
sequba wants to merge 2 commits into
Draft
Fix MAXPOOL and MEDIANPOOL throwing on non-tiling dimensions#1718sequba wants to merge 2 commits into
sequba wants to merge 2 commits into
Conversation
MAXPOOL and MEDIANPOOL computed the output array size without checking that the pooling window actually tiles the input range. When the range dimensions, reduced by the window size, were not whole multiples of the stride, the kernel read past the last row of the input and an uncaught TypeError escaped the interpreter and the public API. - Validate the window size and the stride against the range dimensions and return #VALUE! (ErrorMessage.PoolDimensions) instead. - Require the window size and the stride to be positive integers, so that a zero, negative or fractional value returns #NUM! instead of throwing. - Reuse the new predicate in maxpoolArraySize to keep the predicted array size and the runtime validation in sync. - Document the constraint in the built-in functions guide and in the method JSDoc.
✅ Deploy Preview for hyperformula-dev-docs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
The browser test suite runs under Karma and Jasmine, which has no describe.each, so the Jest-only helper made the whole Karma run fail with "TypeError: describe.each is not a function". A plain forEach over the function names works in both runners.
Performance comparison of head (725b84d) vs base (ad142ba) |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #1718 +/- ##
========================================
Coverage 97.22% 97.22%
========================================
Files 178 178
Lines 15612 15624 +12
Branches 3430 3434 +4
========================================
+ Hits 15178 15191 +13
+ Misses 426 425 -1
Partials 8 8
🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context
MAXPOOLandMEDIANPOOLcomputed the output array size without checking that the pooling window actually tiles the input range. When the range dimensions, reduced by the window size, were not whole multiples of the stride, the kernel read past the last row of the input, and an uncaughtTypeErrorescaped the interpreter and the public API:The same exception escaped
setCellContents().maxpoolArraySize()already rejected such arguments, butArraySize.error()is(1, 1, isRef: true), whichisScalar()reports as scalar, so the formula was evaluated as an ordinary scalar formula and the invalid arguments reached the kernel anyway.Related failure modes found while reproducing: a window larger than the range, a stride that makes the last window overshoot, and a zero, negative or fractional window size or stride all threw as well (
TypeErrororRangeError: Invalid array length).Changes:
MatrixPlugin.maxpool()/MatrixPlugin.medianpool()now validate the window size and the stride against the range dimensions and return#VALUE!with a newErrorMessage.PoolDimensions('Range dimensions are not compatible with the window size and the stride.') instead of running the kernel out of bounds.#VALUE!matches howMMULTreports incompatible dimensions.FunctionArgumentType.INTEGERwithminValue: 1, so a zero, negative or fractional value returns#NUM!(Value too small./Value needs to be an integer.) instead of throwing.isPoolWindowFittingInputArray()predicate is shared withmaxpoolArraySize(), so the predicted array size and the runtime validation stay in sync.src/interpreter/functionMetadata/categories/matrix-functions.ts) do not exist ondevelop— the parameter metadata lives inMatrixPlugin.implementedFunctions— so the prose went todocs/guide/built-in-functions.mdinstead.How did you test your changes?
Added
test/unit/interpreter/matrix-plugin-pooling.spec.ts(20 tests). The error cases are shared betweenMAXPOOLandMEDIANPOOLvia aforEachloop over the function names — deliberately notdescribe.each, which exists only in Jest and breaks the Jasmine-based browser suite (see the second commit below). Coverage:calculateFormula()andsetCellContents();Verified that the 14 validation tests fail with the original
TypeError/RangeErrorwhen theMatrixPluginchange is reverted, and that the 6 regression guards pass both before and after the fix.Ran locally in both test runners, since the spec is picked up by each:
npx jest(24 passed) and Karma/Jasmine under Chromium (Executed 24 of 24 SUCCESS).npm run lint(0 errors) andnpm run compilealso pass.Commits
describe.eachwith a loop in the pooling tests —karma.starter.tsloads everytest/**/*.spec.tsunder Jasmine, which has nodescribe.each, so the first commit made the whole Karma run fail withTypeError: describe.each is not a function(Executed 6080 of 6083 ... ERRORin both Chrome and Firefox). A plainforEachworks in both runners.Types of changes
Related issues:
Checklist:
MAXPOOLandMEDIANPOOLare HyperFormula-specific functions, not covered by the standard.