Skip to content

Commit 79280be

Browse files
committed
Fixes microsoft#81424: Throw when a request is made with invalid arguments
1 parent b2b488f commit 79280be

2 files changed

Lines changed: 36 additions & 5 deletions

File tree

src/vs/workbench/services/extensions/common/rpcProtocol.ts

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ function safeStringify(obj: any, replacer: JSONStringifyReplacer | null): string
2727
}
2828
}
2929

30+
function stringify(obj: any, replacer: JSONStringifyReplacer | null): string {
31+
return JSON.stringify(obj, <(key: string, value: any) => any>replacer);
32+
}
33+
3034
function createURIReplacer(transformer: IURITransformer | null): JSONStringifyReplacer | null {
3135
if (!transformer) {
3236
return null;
@@ -412,6 +416,8 @@ export class RPCProtocol extends Disposable implements IRPCProtocol {
412416
return Promise.reject<any>(errors.canceled());
413417
}
414418

419+
const serializedRequestArguments = MessageIO.serializeRequestArguments(args, this._uriReplacer);
420+
415421
const req = ++this._lastMessageId;
416422
const callId = String(req);
417423
const result = new LazyPromise();
@@ -428,7 +434,7 @@ export class RPCProtocol extends Disposable implements IRPCProtocol {
428434

429435
this._pendingRPCReplies[callId] = result;
430436
this._onWillSendRequest(req);
431-
const msg = MessageIO.serializeRequest(req, rpcId, methodName, args, !!cancellationToken, this._uriReplacer);
437+
const msg = MessageIO.serializeRequest(req, rpcId, methodName, serializedRequestArguments, !!cancellationToken);
432438
if (this._logger) {
433439
this._logger.logOutgoing(msg.byteLength, req, RequestInitiator.LocalSide, `request: ${getStringIdentifierForProxy(rpcId)}.${methodName}(`, args);
434440
}
@@ -600,6 +606,8 @@ class MessageBuffer {
600606
}
601607
}
602608

609+
type SerializedRequestArguments = { type: 'mixed'; args: VSBuffer[]; argsType: ArgType[]; } | { type: 'simple'; args: string; };
610+
603611
class MessageIO {
604612

605613
private static _arrayContainsBufferOrUndefined(arr: any[]): boolean {
@@ -614,7 +622,7 @@ class MessageIO {
614622
return false;
615623
}
616624

617-
public static serializeRequest(req: number, rpcId: number, method: string, args: any[], usesCancellationToken: boolean, replacer: JSONStringifyReplacer | null): VSBuffer {
625+
public static serializeRequestArguments(args: any[], replacer: JSONStringifyReplacer | null): SerializedRequestArguments {
618626
if (this._arrayContainsBufferOrUndefined(args)) {
619627
let massagedArgs: VSBuffer[] = [];
620628
let massagedArgsType: ArgType[] = [];
@@ -627,13 +635,27 @@ class MessageIO {
627635
massagedArgs[i] = VSBuffer.alloc(0);
628636
massagedArgsType[i] = ArgType.Undefined;
629637
} else {
630-
massagedArgs[i] = VSBuffer.fromString(safeStringify(arg, replacer));
638+
massagedArgs[i] = VSBuffer.fromString(stringify(arg, replacer));
631639
massagedArgsType[i] = ArgType.String;
632640
}
633641
}
634-
return this._requestMixedArgs(req, rpcId, method, massagedArgs, massagedArgsType, usesCancellationToken);
642+
return {
643+
type: 'mixed',
644+
args: massagedArgs,
645+
argsType: massagedArgsType
646+
};
647+
}
648+
return {
649+
type: 'simple',
650+
args: stringify(args, replacer)
651+
};
652+
}
653+
654+
public static serializeRequest(req: number, rpcId: number, method: string, serializedArgs: SerializedRequestArguments, usesCancellationToken: boolean): VSBuffer {
655+
if (serializedArgs.type === 'mixed') {
656+
return this._requestMixedArgs(req, rpcId, method, serializedArgs.args, serializedArgs.argsType, usesCancellationToken);
635657
}
636-
return this._requestJSONArgs(req, rpcId, method, safeStringify(args, replacer), usesCancellationToken);
658+
return this._requestJSONArgs(req, rpcId, method, serializedArgs.args, usesCancellationToken);
637659
}
638660

639661
private static _requestJSONArgs(req: number, rpcId: number, method: string, args: string, usesCancellationToken: boolean): VSBuffer {

src/vs/workbench/services/extensions/test/common/rpcProtocol.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,4 +212,13 @@ suite('RPCProtocol', () => {
212212
assert.equal(res, 7);
213213
});
214214
});
215+
216+
test('issue #81424: SerializeRequest should throw if an argument can not be serialized', () => {
217+
let badObject = {};
218+
(<any>badObject).loop = badObject;
219+
220+
assert.throws(() => {
221+
bProxy.$m(badObject, '2');
222+
});
223+
});
215224
});

0 commit comments

Comments
 (0)