Skip to content

Commit 6e1ceff

Browse files
committed
prettyPrint: do not call legacy toString for Uint8Arrays
Certain Uint8Arrays returned from introspected functions fail to print with the pretty printer and log deprecated warnings. This is because for those Uint8Arrays we override its toString as a compatibility shim to warn users of legacy behaviour. However, this makes its toString own property nonstandard. Detect TypedArrays explicitly when pretty printing so it can be printed in an array-like format. Fixes https://gitlab.gnome.org/GNOME/gjs/-/issues/434
1 parent 97ab82e commit 6e1ceff

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

installed-tests/js/testPrint.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
imports.gi.versions.Gdk = '3.0';
66
const Gdk = imports.gi.Gdk;
7+
const ByteArray = imports.byteArray;
78
const {getPrettyPrintFunction} = imports._print;
89
let prettyPrint = getPrettyPrintFunction(globalThis);
910

@@ -211,4 +212,38 @@ describe('prettyPrint', function () {
211212
expect(prettyPrint({'foo': imports}))
212213
.toEqual('{ foo: [GjsFileImporter root] }');
213214
});
215+
216+
describe('TypedArrays', () => {
217+
[
218+
Int8Array,
219+
Uint8Array,
220+
Uint16Array,
221+
Uint8ClampedArray,
222+
Int16Array,
223+
Uint16Array,
224+
Int32Array,
225+
Uint32Array,
226+
Float32Array,
227+
Float64Array,
228+
].forEach(constructor => {
229+
it(constructor.name, function () {
230+
const arr = new constructor([1, 2, 3]);
231+
expect(prettyPrint(arr))
232+
.toEqual('[1, 2, 3]');
233+
});
234+
});
235+
236+
[BigInt64Array, BigUint64Array].forEach(constructor => {
237+
it(constructor.name, function () {
238+
const arr = new constructor([1n, 2n, 3n]);
239+
expect(prettyPrint(arr))
240+
.toEqual('[1, 2, 3]');
241+
});
242+
});
243+
});
244+
245+
it('Uint8Array returned from introspected function', function () {
246+
let a = ByteArray.fromString('⅜');
247+
expect(prettyPrint(a)).toEqual('[226, 133, 156]');
248+
});
214249
});

modules/script/_bootstrap/default.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,18 @@
2323
return nativeLogError(e, args.map(arg => typeof arg === 'string' ? arg : prettyPrint(arg)).join(' '));
2424
}
2525

26+
// compare against the %TypedArray% intrinsic object all typed array constructors inherit from
27+
function _isTypedArray(value) {
28+
return value instanceof Object.getPrototypeOf(Uint8Array);
29+
}
30+
2631
function _hasStandardToString(value) {
2732
return value.toString === Object.prototype.toString ||
2833
value.toString === Array.prototype.toString ||
34+
// although TypedArrays have a standard Array.prototype.toString, we currently enforce an override to warn
35+
// for legacy behaviour, making the toString non-standard for
36+
// "any Uint8Array instances created in situations where previously a ByteArray would have been created"
37+
_isTypedArray(value) ||
2938
value.toString === Date.prototype.toString;
3039
}
3140

@@ -64,7 +73,7 @@
6473

6574
function formatObject(obj, printedObjects) {
6675
printedObjects.add(obj);
67-
if (Array.isArray(obj))
76+
if (Array.isArray(obj) || _isTypedArray(obj))
6877
return formatArray(obj, printedObjects).toString();
6978

7079
if (obj instanceof Date)

0 commit comments

Comments
 (0)