stdlib-js / stdlib-js/stdlib

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

Abierto
#15,124 0 comentarios 0 reacciones 1 asignado Reclamado por @0PrashantYadav0 Ver en GitHub
BLAS Bug Needs Discussion
Lenguaje dominante
JavaScript
Estrellas
6k
Forks
1.3k
Merge medio
1 d 3 h
PR fusionados (30 d)
611

Descripción

### 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.

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.