MCPcopy
hub / github.com/cloudflare/capnweb / followPath

Function followPath

src/core.ts:1487–1622  ·  view source on GitHub ↗
(value: unknown, parent: object | undefined,
                    path: PropertyPath, owner: RpcPayload | null)

Source from the content-addressed store, hash-verified

1485};
1486
1487function followPath(value: unknown, parent: object | undefined,
1488 path: PropertyPath, owner: RpcPayload | null): FollowPathResult {
1489 for (let i = 0; i < path.length; i++) {
1490 parent = <object>value;
1491
1492 let part = path[i];
1493 if (part in Object.prototype) {
1494 // Don't allow messing with Object.prototype properties over RPC. We block these even if
1495 // the specific object has overridden them for consistency with the deserialization code,
1496 // which will refuse to deserialize an object containing such properties. Anyway, it's
1497 // impossible for a normal client to even request these because accessing Object prototype
1498 // properties on a stub will resolve to the local prototype property, not making an RPC at
1499 // all.
1500 value = undefined;
1501 continue;
1502 }
1503
1504 let kind = typeForRpc(value);
1505 switch (kind) {
1506 case "object":
1507 case "function":
1508 // Must be own property, NOT inherited from a prototype.
1509 if (Object.hasOwn(<object>value, part)) {
1510 value = (<any>value)[part];
1511 } else {
1512 value = undefined;
1513 }
1514 break;
1515
1516 case "array":
1517 // For arrays, restrict specifically to numeric indexes, to be consistent with
1518 // serialization, which only sends a flat list.
1519 if (Number.isInteger(part) && <number>part >= 0) {
1520 value = (<any>value)[part];
1521 } else {
1522 value = undefined;
1523 }
1524 break;
1525
1526 case "rpc-target":
1527 case "rpc-thenable": {
1528 // Must be prototype property, and must NOT be inherited from `Object`.
1529 if (Object.hasOwn(<object>value, part)) {
1530 // We throw an error in this case, rather than return undefined, because otherwise
1531 // people tend to get confused about this. If you don't want it to be possible to
1532 // probe the existence of your instance properties, make them properly private (prefix
1533 // with #).
1534 throw new TypeError(
1535 `Attempted to access property '${part}', which is an instance property of the ` +
1536 `RpcTarget. To avoid leaking private internals, instance properties cannot be ` +
1537 `accessed over RPC. If you want to make this property available over RPC, define ` +
1538 `it as a method or getter on the class, instead of an instance property.`);
1539 } else {
1540 value = (<any>value)[part];
1541 }
1542
1543 // Since we're descending into the RpcTarget, the rest of the path is not "owned" by any
1544 // RpcPayload.

Callers 3

callFunction · 0.85
mapFunction · 0.85
getFunction · 0.85

Calls 2

typeForRpcFunction · 0.85
unwrapStubAndPathFunction · 0.85

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…