Skip to content

Commit d0192f2

Browse files
committed
fix(console): find custom toString on deep prototype chains
findCustomToString capped the prototype walk at 8 targets, but core view hierarchies run deeper: a GridLayout instance is 10 hops from ViewBase.prototype (which holds toString), a Page is 9. Those views fell through to the structural property dump instead of printing their debug names (e.g. GridLayout(7)). Raise the cap to 32 - it exists only to bound Proxy getPrototypeOf traps, not real chains.
1 parent 98eea99 commit d0192f2

2 files changed

Lines changed: 17 additions & 2 deletions

File tree

test-app/app/src/main/assets/app/tests/testInspect.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,19 @@ describe("inspect", function () {
180180
expect(__inspect(broken).indexOf("a: 1")).toBeGreaterThan(-1);
181181
});
182182

183+
it("finds toString deep in the prototype chain (core layout depth)", function () {
184+
// Core view chains run ~10 prototypes deep (GridLayout -> ... -> ViewBase,
185+
// which holds toString); the walk cap must clear them.
186+
function ViewBase() {}
187+
ViewBase.prototype.toString = function () { return "GridLayout(7)"; };
188+
var proto = ViewBase.prototype;
189+
for (var i = 0; i < 9; i++) {
190+
proto = Object.create(proto);
191+
}
192+
var deep = Object.create(proto);
193+
expect(__inspect(deep)).toBe("GridLayout(7)");
194+
});
195+
183196
it("formats under tampered prototypes", function () {
184197
var savedSlice = Array.prototype.slice;
185198
var savedIndexOf = Array.prototype.indexOf;

test-app/runtime/src/main/cpp/js/inspect.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,10 +252,12 @@ function formatObject(ctx, value, depth) {
252252

253253
// A toString override that is NOT Object.prototype's: own property first, then
254254
// up the chain, stopping at Object.prototype. Data properties only — a
255-
// toString defined as an accessor is not worth invoking a getter for.
255+
// toString defined as an accessor is not worth invoking a getter for. The hop
256+
// cap only bounds Proxy getPrototypeOf traps fabricating endless chains; it
257+
// must clear real hierarchies (core layout views sit ~10 prototypes deep).
256258
function findCustomToString(value) {
257259
let target = value;
258-
for (let i = 0; target !== null && target !== ObjectPrototype && i < 8; i++) {
260+
for (let i = 0; target !== null && target !== ObjectPrototype && i < 32; i++) {
259261
const desc = ObjectGetOwnPropertyDescriptor(target, "toString");
260262
if (desc !== undefined) {
261263
return typeof desc.value === "function" ? desc.value : undefined;

0 commit comments

Comments
 (0)