From e91713d909740d35e162a120a635b3d09775a4cd Mon Sep 17 00:00:00 2001 From: David Glasser Date: Thu, 10 Apr 2014 14:48:29 -0700 Subject: [PATCH] Clone various parameter lists in livedata Specifically: - On client, clone parameters to sub and methods (so that if they're modified outside before the method message is actually sent, before the sub params are used for de-duping, or before resending messages on reconnect, this doesn't affect what we do) - On server, ensure that method bodies mutating their arguments does not affect callers of Meteor.call (executing locally) Fixes #2025. --- packages/livedata/livedata_connection.js | 7 ++++++- packages/livedata/livedata_server.js | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/livedata/livedata_connection.js b/packages/livedata/livedata_connection.js index ed1e8accca..e32a39e3fa 100644 --- a/packages/livedata/livedata_connection.js +++ b/packages/livedata/livedata_connection.js @@ -519,7 +519,7 @@ _.extend(Connection.prototype, { self._subscriptions[id] = { id: id, name: name, - params: params, + params: EJSON.clone(params), inactive: false, ready: false, readyDeps: (typeof Deps !== "undefined") && new Deps.Dependency, @@ -644,6 +644,10 @@ _.extend(Connection.prototype, { ); } + // Keep our args safe from mutation (eg if we don't send the message for a + // while because of a wait method). + args = EJSON.clone(args); + // Lazily allocate method ID once we know that it'll be needed. var methodId = (function () { var id; @@ -691,6 +695,7 @@ _.extend(Connection.prototype, { // Because saveOriginals and retrieveOriginals aren't reentrant, // don't allow stubs to yield. return Meteor._noYieldsAllowed(function () { + // re-clone, so that the stub can't affect our caller's values return stub.apply(invocation, EJSON.clone(args)); }); } else { diff --git a/packages/livedata/livedata_server.js b/packages/livedata/livedata_server.js index d133e648c0..74d4206db1 100644 --- a/packages/livedata/livedata_server.js +++ b/packages/livedata/livedata_server.js @@ -1399,7 +1399,8 @@ _.extend(Server.prototype, { try { var result = DDP._CurrentInvocation.withValue(invocation, function () { return maybeAuditArgumentChecks( - handler, invocation, args, "internal call to '" + name + "'"); + handler, invocation, EJSON.clone(args), "internal call to '" + + name + "'"); }); } catch (e) { exception = e;