stdlib-js / stdlib-js/stdlib

[Bug]: unvalidated ndarray argument in few `blas/ext` packages

オープン
#15,124 コメント 0 件 リアクション 0 件 担当者 1 名 @0PrashantYadav0 が担当を希望しています GitHub で見る
BLAS Bug Needs Discussion
主要言語
JavaScript
スター
6k
フォーク
1.3k
平均マージ
1日 3時間
マージ済み PR(30日)
611

説明

### Description

Encountered an error when passing a non-broadcast-compatible ndarray as the second argument to `blas/ext/circshift`, `blas/ext/sort`, and `blas/ext/sorthp` without an `options.dims` property. Instead of throwing, all three functions accept the argument and return a result.

I came across this through a CI failure on an unrelated pull request of mine, which touched only TypeScript declaration files under `ndarray/array/docs/types`. Because `ndarray/array` is referenced in the READMEs, `docs/repl.txt`, and JSDoc examples of these packages, they fall into the affected-package set, and the `test-javascript-files-min` job ran their suites and reported the failures below. The failures are unrelated to that pull request: the sources involved are byte-identical to `develop`, and the same assertions fail on a clean checkout.

Each package documents the contract it fails to enforce. From `blas/ext/sort/docs/repl.txt`:

> If provided an ndarray, the value must have a shape which is broadcast compatible with the complement of the shape defined by `options.dims`.

When `dims` is absent, the complement is the empty shape `[]`, so the argument must be zero-dimensional. The implementations never check this. In each `lib/main.js`, the two-argument form returns `base( x, k )` directly, and the three-argument form assigns the argument unchanged when `opts` has no `dims` property. Only the `dims` branch calls `maybeBroadcastArray`, so only that path validates.

The affected argument and each package's own failing assertion count:

| Package | Argument | Failing assertions |
| --- | --- | --- |
| `blas/ext/circshift` | `k` | 6 |
| `blas/ext/sort` | `sortOrder` | 6 |
| `blas/ext/sorthp` | `sortOrder` | 6 |

Each package's test suite already asserts the correct behavior, so all three suites fail on a clean `develop` checkout: `circshift` 264/270, `sort` 344/350, `sorthp` 344/350. The relevant blocks are "the function throws an error if provided a `k` argument which is not broadcast-compatible" and its `(options)` counterpart, at `test/test.js:248` and `test/test.js:278` for `circshift`.

Routing both unvalidated paths through the same check the `dims` branch already uses resolves it. For a valid zero-dimensional argument `maybeBroadcastArray( k, [] )` returns the same reference, so valid input is unaffected:

```javascript
// Two-argument form:
return base( x, maybeBroadcastArray( k, [] ) );

// Three-argument form, mirroring the shape selection the scalar branch already uses:
if ( hasOwnProp( opts, 'dims' ) ) {
sh = nonCoreShape( getShape( x ), opts.dims );
} else {
sh = [];
}
ka = maybeBroadcastArray( k, sh );
```

`maybeBroadcastArray` is already required in all three files, so no new dependencies are needed.

### Related Issues

Related issues # , # , and # .

### Questions

Should this be one issue covering all three packages, or split per package? The root cause and the fix are identical in each.

### Demo

N/A

### Reproduction

- Check out `develop` and install dependencies.
- Run the snippet below with Node.js, or run `node lib/node_modules/@stdlib/blas/ext/circshift/test/test.js` to see the six failing assertions directly.

```javascript
var zeros = require( '@stdlib/ndarray/zeros' );
var circshift = require( '@stdlib/blas/ext/circshift' );

var x = zeros( [ 2, 2 ], {
'dtype': 'generic'
});
var k = zeros( [ 4 ], {
'dtype': 'int32'
});

// `k` has shape [4], which is not broadcast compatible with the empty shape:
circshift( x, k );
circshift( x, k, {} );
```

The same reproduction applies to `blas/ext/sort` and `blas/ext/sorthp` by substituting the `sortOrder` argument.

### Expected Results

```shell
Error: invalid argument. Cannot broadcast an array to a shape having fewer dimensions. Arrays can only be broadcasted to shapes having the same or more dimensions.
```

### Actual Results

```shell
# No error is thrown. Both calls return an ndarray.

Reported by the test suites as:

not ok 83 throws an error when provided ndarray( 'int32', new Int32Array( [ 0, 0, 0, 0 ] ), [ 4 ], [ 1 ], 0, 'row-major' )
---
operator: throws
expected: '[Function: Error]'
actual: 'undefined'
...
```

### Version

0.4.1

### Environments

Node.js

### Browser Version

N/A

### Node.js / npm Version

Node.js v26.5.0, npm 11.17.0

### Platform

macOS 26.5.2 (arm64). Not platform specific.

### Checklist

- [x] Read and understood the [Code of Conduct](https://github.com/stdlib-js/stdlib/blob/develop/CODE_OF_CONDUCT.md).
- [x] Searched for existing issues and pull requests.

コントリビューションガイド

コントリビューションガイドを開く

評価

この issue はまだ評価されていません。

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。