Skip to content
8 changes: 8 additions & 0 deletions packages/devextreme/js/__internal/core/utils/m_object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ const clone = (function () {
};
})();

const isBlobLike = function (value: unknown): boolean {
return typeof Blob !== 'undefined' && value instanceof Blob;
};

const orderEach = function (map, func) {
const keys: string[] = [];
let key;
Expand Down Expand Up @@ -93,6 +97,10 @@ const deepExtendArraySafe = function (target, changes, extendComplexObject?, ass
let newValue;
const assignFunc = useNewAssign ? newAssign : legacyAssign;

if (isBlobLike(changes)) {
return changes;
}

for (const name in changes) {
prevValue = target[name];
newValue = changes[name];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,3 +221,18 @@ QUnit.test('deepExtendArraySafe preserves custom object instances in arrays', fu
assert.ok(result.items[0] instanceof CustomClass, 'First item preserves custom type');
assert.ok(result.items[1] instanceof CustomClass, 'Second item preserves custom type');
});

QUnit.test('deepExtendArraySafe assigns Blob/File by reference without throwing (nested newAssign)', function(assert) {
const file = new File(['x'], 'test.txt', { type: 'text/plain' });
const blob = new Blob(['y']);

const target = { id: 1, file: null, data: null };

objectUtils.deepExtendArraySafe(target, { file: file, data: blob }, true, false, true, objectUtils.newAssign);

assert.strictEqual(target.file, file);
assert.strictEqual(target.data, blob);

const merged = objectUtils.deepExtendArraySafe({}, file, true, false, true, objectUtils.newAssign);
assert.strictEqual(merged, file);
});
Loading