From 976112afab4832420d9fe3497db01b02b2abe14d Mon Sep 17 00:00:00 2001 From: sarthakkaushik927 Date: Thu, 29 Oct 2026 11:02:27 +0530 Subject: [PATCH 1/2] fix: avoid mutating source array in `array/fixed-endian-factory#with` Co-Authored-By: Claude Opus 5.5 Signed-off-by: sarthakkaushik927 --- .../array/fixed-endian-factory/lib/main.js | 6 +- .../fixed-endian-factory/test/test.with.js | 56 +++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/lib/node_modules/@stdlib/array/fixed-endian-factory/lib/main.js b/lib/node_modules/@stdlib/array/fixed-endian-factory/lib/main.js index f65f1ee85488..ed8e52c1939e 100644 --- a/lib/node_modules/@stdlib/array/fixed-endian-factory/lib/main.js +++ b/lib/node_modules/@stdlib/array/fixed-endian-factory/lib/main.js @@ -1144,6 +1144,7 @@ function factory( dtype ) { // eslint-disable-line max-lines-per-function, stdli var buf; var out; var len; + var i; if ( !isTypedArray( this ) ) { throw new TypeError( format( 'invalid invocation. `this` is not %s %s.', CHAR2ARTICLE[ dtype[0] ], CTOR_NAME ) ); @@ -1159,8 +1160,11 @@ function factory( dtype ) { // eslint-disable-line max-lines-per-function, stdli if ( index < 0 || index >= len ) { throw new RangeError( format( 'invalid argument. Index argument is out-of-bounds. Value: `%s`.', index ) ); } - out = new this.constructor( flag2byteOrder( this._isLE ), buf.buffer ); + out = new this.constructor( flag2byteOrder( this._isLE ), len ); outbuf = out._buffer; // eslint-disable-line no-underscore-dangle + for ( i = 0; i < len; i++ ) { + outbuf[ SETTER ]( i*BYTES_PER_ELEMENT, buf[ GETTER ]( i*BYTES_PER_ELEMENT, this._isLE ), this._isLE ); + } outbuf[ SETTER ]( index * BYTES_PER_ELEMENT, value, this._isLE ); return out; }); diff --git a/lib/node_modules/@stdlib/array/fixed-endian-factory/test/test.with.js b/lib/node_modules/@stdlib/array/fixed-endian-factory/test/test.with.js index df6fa9201321..3540e0888823 100644 --- a/lib/node_modules/@stdlib/array/fixed-endian-factory/test/test.with.js +++ b/lib/node_modules/@stdlib/array/fixed-endian-factory/test/test.with.js @@ -24,6 +24,7 @@ var tape = require( 'tape' ); var hasSameValues = require( '@stdlib/array/base/assert/has-same-values' ); var hasOwnProp = require( '@stdlib/assert/has-own-property' ); var isFunction = require( '@stdlib/assert/is-function' ); +var ArrayBuffer = require( '@stdlib/array/buffer' ); var factory = require( './../lib' ); @@ -187,3 +188,58 @@ tape( 'the method supports negative indices', function test( t ) { t.notEqual( actual, arr, 'returns new instance' ); t.end(); }); + +tape( 'the method does not mutate the original array', function test( t ) { + var expected; + var actual; + var ctor; + var arr; + + ctor = factory( 'float64' ); + arr = new ctor( 'little-endian', [ 1.0, 2.0, 3.0, 4.0, 5.0 ] ); + expected = new ctor( 'little-endian', [ 1.0, 2.0, 3.0, 4.0, 5.0 ] ); + actual = arr.with( 0, 0.0 ); + + t.notEqual( actual.buffer, arr.buffer, 'returns expected value' ); + t.strictEqual( hasSameValues( arr, expected ), true, 'returns expected value' ); + t.end(); +}); + +tape( 'the method supports typed arrays which are views on an underlying buffer', function test( t ) { + var expected; + var actual; + var ctor; + var arr; + var buf; + + ctor = factory( 'float64' ); + buf = new ArrayBuffer( 40 ); + arr = new ctor( 'little-endian', buf, 8, 3 ); + arr.set( [ 1.0, 2.0, 3.0 ] ); + + expected = new ctor( 'little-endian', [ 1.0, 0.0, 3.0 ] ); + actual = arr.with( 1, 0.0 ); + + t.strictEqual( actual.length, 3, 'returns expected value' ); + t.strictEqual( hasSameValues( actual, expected ), true, 'returns expected value' ); + + expected = new ctor( 'little-endian', [ 1.0, 2.0, 3.0 ] ); + t.strictEqual( hasSameValues( arr, expected ), true, 'returns expected value' ); + t.end(); +}); + +tape( 'the method returns a typed array having the same byte order as the original array', function test( t ) { + var expected; + var actual; + var ctor; + var arr; + + ctor = factory( 'float64' ); + arr = new ctor( 'big-endian', [ 1.0, 2.0, 3.0 ] ); + expected = new ctor( 'big-endian', [ 1.0, 2.0, 0.0 ] ); + actual = arr.with( 2, 0.0 ); + + t.strictEqual( hasSameValues( actual, expected ), true, 'returns expected value' ); + t.strictEqual( actual._isLE, false, 'returns expected value' ); // eslint-disable-line no-underscore-dangle + t.end(); +}); From 004dd6e1249b1d743e2674c065a6b3bb37cd9501 Mon Sep 17 00:00:00 2001 From: sarthakkaushik927 Date: Thu, 29 Oct 2026 16:27:35 +0530 Subject: [PATCH 2/2] chore: address review feedback Copy the underlying bytes directly instead of copying element-by-element via accessors, and avoid testing private properties. Co-Authored-By: Claude Opus 5.5 Signed-off-by: sarthakkaushik927 --- .../@stdlib/array/fixed-endian-factory/lib/main.js | 14 +++++++++----- .../array/fixed-endian-factory/test/test.with.js | 1 - 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/node_modules/@stdlib/array/fixed-endian-factory/lib/main.js b/lib/node_modules/@stdlib/array/fixed-endian-factory/lib/main.js index ed8e52c1939e..192aa58e47c8 100644 --- a/lib/node_modules/@stdlib/array/fixed-endian-factory/lib/main.js +++ b/lib/node_modules/@stdlib/array/fixed-endian-factory/lib/main.js @@ -37,6 +37,7 @@ var setReadOnly = require( '@stdlib/utils/define-nonenumerable-read-only-propert var isPrototypeOf = require( '@stdlib/assert/is-prototype-of' ); // eslint-disable-line stdlib/no-redeclare var setReadOnlyAccessor = require( '@stdlib/utils/define-nonenumerable-read-only-accessor' ); var ArrayBuffer = require( '@stdlib/array/buffer' ); +var Uint8Array = require( '@stdlib/array/uint8' ); var DataView = require( '@stdlib/array/dataview' ); var getter = require( '@stdlib/array/base/getter' ); var accessorGetter = require( '@stdlib/array/base/accessor-getter' ); @@ -1141,10 +1142,12 @@ function factory( dtype ) { // eslint-disable-line max-lines-per-function, stdli */ setReadOnly( TypedArray.prototype, 'with', function copyWith( index, value ) { var outbuf; + var nbytes; + var dest; + var src; var buf; var out; var len; - var i; if ( !isTypedArray( this ) ) { throw new TypeError( format( 'invalid invocation. `this` is not %s %s.', CHAR2ARTICLE[ dtype[0] ], CTOR_NAME ) ); @@ -1160,11 +1163,12 @@ function factory( dtype ) { // eslint-disable-line max-lines-per-function, stdli if ( index < 0 || index >= len ) { throw new RangeError( format( 'invalid argument. Index argument is out-of-bounds. Value: `%s`.', index ) ); } - out = new this.constructor( flag2byteOrder( this._isLE ), len ); + nbytes = len * BYTES_PER_ELEMENT; + src = new Uint8Array( buf.buffer, buf.byteOffset, nbytes ); + dest = new Uint8Array( new ArrayBuffer( nbytes ) ); + dest.set( src ); + out = new this.constructor( flag2byteOrder( this._isLE ), dest.buffer ); outbuf = out._buffer; // eslint-disable-line no-underscore-dangle - for ( i = 0; i < len; i++ ) { - outbuf[ SETTER ]( i*BYTES_PER_ELEMENT, buf[ GETTER ]( i*BYTES_PER_ELEMENT, this._isLE ), this._isLE ); - } outbuf[ SETTER ]( index * BYTES_PER_ELEMENT, value, this._isLE ); return out; }); diff --git a/lib/node_modules/@stdlib/array/fixed-endian-factory/test/test.with.js b/lib/node_modules/@stdlib/array/fixed-endian-factory/test/test.with.js index 3540e0888823..f5a5ea14427d 100644 --- a/lib/node_modules/@stdlib/array/fixed-endian-factory/test/test.with.js +++ b/lib/node_modules/@stdlib/array/fixed-endian-factory/test/test.with.js @@ -240,6 +240,5 @@ tape( 'the method returns a typed array having the same byte order as the origin actual = arr.with( 2, 0.0 ); t.strictEqual( hasSameValues( actual, expected ), true, 'returns expected value' ); - t.strictEqual( actual._isLE, false, 'returns expected value' ); // eslint-disable-line no-underscore-dangle t.end(); });