mark rpc protocol and proxies with symbols and try to find them from an API test (with success...)

This commit is contained in:
Johannes Rieken 2021-01-29 12:12:06 +01:00
parent b08c1eb5bc
commit 1ecf01b9c7
2 changed files with 64 additions and 3 deletions

View file

@ -0,0 +1,53 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import * as vscode from 'vscode';
suite('vscode', function () {
test('rpc protocol, proxies not reachable', function () {
const symProxy = Symbol.for('rpcProxy');
const symProtocol = Symbol.for('rpcProtocol');
const proxyPaths: string[] = [];
const rpcPaths: string[] = [];
function walk(obj: any, path: string, seen: Set<any>) {
if (!obj) {
return;
}
if (typeof obj !== 'object' && typeof obj !== 'function') {
return;
}
if (seen.has(obj)) {
return;
}
seen.add(obj);
if (obj[symProtocol]) {
rpcPaths.push(`PROTOCOL via ${path}`);
}
if (obj[symProxy]) {
proxyPaths.push(`PROXY '${obj[symProxy]}' via ${path}`);
}
for (const key in obj) {
walk(obj[key], `${path}.${String(key)}`, seen);
}
}
try {
walk(vscode, 'vscode', new Set());
} catch (err) {
assert.fail(err);
}
assert.strictEqual(rpcPaths.length, 0);
// assert.strictEqual(proxyPaths.length, 0); // proxies are accessible...
});
});

View file

@ -60,8 +60,13 @@ export interface IRPCProtocolLogger {
const noop = () => { };
const _RPCProtocolSymbol = Symbol.for('rpcProtocol');
const _RPCProxySymbol = Symbol.for('rpcProxy');
export class RPCProtocol extends Disposable implements IRPCProtocol {
[_RPCProtocolSymbol] = true;
private static readonly UNRESPONSIVE_TIME = 3 * 1000; // 3s
private readonly _onDidChangeResponsiveState: Emitter<ResponsiveState> = this._register(new Emitter<ResponsiveState>());
@ -182,14 +187,14 @@ export class RPCProtocol extends Disposable implements IRPCProtocol {
}
public getProxy<T>(identifier: ProxyIdentifier<T>): T {
const rpcId = identifier.nid;
const { nid: rpcId, sid } = identifier;
if (!this._proxies[rpcId]) {
this._proxies[rpcId] = this._createProxy(rpcId);
this._proxies[rpcId] = this._createProxy(rpcId, sid);
}
return this._proxies[rpcId];
}
private _createProxy<T>(rpcId: number): T {
private _createProxy<T>(rpcId: number, debugName: string): T {
let handler = {
get: (target: any, name: PropertyKey) => {
if (typeof name === 'string' && !target[name] && name.charCodeAt(0) === CharCode.DollarSign) {
@ -197,6 +202,9 @@ export class RPCProtocol extends Disposable implements IRPCProtocol {
return this._remoteCall(rpcId, name, myArgs);
};
}
if (name === _RPCProxySymbol) {
return debugName;
}
return target[name];
}
};