Skip to content

Commit

Permalink
fix: prevent device node leaks and stale urlHandlers
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelfig committed Dec 15, 2020
1 parent 4b98e64 commit a2825ac
Showing 1 changed file with 14 additions and 25 deletions.
39 changes: 14 additions & 25 deletions packages/cosmic-swingset/lib/ag-solo/vats/vat-http.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ export function buildRootObject(vatPowers) {
obj || JSON.parse(JSON.stringify(obj)),
);

const registeredURLHandlers = new Map();
// Map an URL only to its latest handler.
const urlToHandler = new Map();

async function registerURLHandler(handler, url) {
const fallback = await E(handler)
Expand All @@ -66,12 +67,7 @@ export function buildRootObject(vatPowers) {
.catch(_e => undefined),
fallback,
);
let reg = registeredURLHandlers.get(url);
if (!reg) {
reg = [];
registeredURLHandlers.set(url, reg);
}
reg.push(commandHandler);
urlToHandler.set(url, commandHandler);
}

return harden({
Expand Down Expand Up @@ -145,12 +141,15 @@ export function buildRootObject(vatPowers) {
// devices.command invokes our inbound() because we passed to
// registerInboundHandler()
async inbound(count, rawObj) {
// Launder the data, since the command device tends to pass device nodes
// when there are empty objects, which screw things up for us.
const obj = JSON.parse(JSON.stringify(rawObj));
console.debug(
`vat-http.inbound (from browser) ${count}`,
JSON.stringify(rawObj, undefined, 2),
JSON.stringify(obj, undefined, 2),
);

const { type, meta: rawMeta = {} } = rawObj || {};
const { type, meta: rawMeta = {} } = obj || {};
const {
url = '/private/repl',
channelID: rawChannelID,
Expand All @@ -168,9 +167,6 @@ export function buildRootObject(vatPowers) {
channelHandleToId.delete(channelHandle);
}

const obj = {
...rawObj,
};
delete obj.meta;

const meta = {
Expand All @@ -179,19 +175,12 @@ export function buildRootObject(vatPowers) {
};
delete meta.channelID;

const urlHandlers = registeredURLHandlers.get(url);
if (urlHandlers) {
// todo fixme avoid the loop
// For now, go from the end to beginning so that handlers
// override.
for (let i = urlHandlers.length - 1; i >= 0; i -= 1) {
// eslint-disable-next-line no-await-in-loop
const res = await E(urlHandlers[i])[dispatcher](obj, meta);

if (res) {
sendResponse(count, false, res);
return;
}
const urlHandler = urlToHandler.get(url);
if (urlHandler) {
const res = await E(urlHandler)[dispatcher](obj, meta);
if (res) {
sendResponse(count, false, res);
return;
}
}

Expand Down

0 comments on commit a2825ac

Please sign in to comment.