Skip to content

Commit abe1cd2

Browse files
authored
fix(ext/node): validate a diagnostics_channel subscription before activation (#35)
Channel#subscribe() activated the channel before it validated the subscription. An invalid subscription threw ERR_INVALID_ARG_TYPE, but the channel stayed active, so hasSubscribers returned true without a subscriber. Validate first, as nodejs/node#65313 does.
1 parent 1999c9a commit abe1cd2

2 files changed

Lines changed: 36 additions & 0 deletions

File tree

‎ext/node/polyfills/diagnostics_channel.js‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,9 @@ class Channel {
216216
}
217217

218218
subscribe(subscription) {
219+
// Validate before activation so that an invalid subscription does not
220+
// leave the channel active without a subscriber (nodejs/node#65313).
221+
validateFunction(subscription, "subscription");
219222
markActive(this);
220223
this.subscribe(subscription);
221224
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright 2018-2026 the Deno authors. MIT license.
2+
3+
import dc from "node:diagnostics_channel";
4+
import { assert, assertFalse, assertThrows } from "@std/assert";
5+
6+
Deno.test("[diagnostics_channel] an invalid subscription does not activate the channel", () => {
7+
const name = "diagnostics-channel-invalid-subscription";
8+
const channel = dc.channel(name);
9+
10+
assertThrows(
11+
// deno-lint-ignore no-explicit-any
12+
() => dc.subscribe(name, null as any),
13+
TypeError,
14+
'The "subscription" argument must be of type function',
15+
);
16+
assertFalse(channel.hasSubscribers);
17+
assertFalse(dc.hasSubscribers(name));
18+
19+
assertThrows(
20+
// deno-lint-ignore no-explicit-any
21+
() => channel.subscribe(null as any),
22+
TypeError,
23+
'The "subscription" argument must be of type function',
24+
);
25+
assertFalse(channel.hasSubscribers);
26+
assertFalse(dc.hasSubscribers(name));
27+
28+
const subscriber = () => {};
29+
channel.subscribe(subscriber);
30+
assert(channel.hasSubscribers);
31+
assert(channel.unsubscribe(subscriber));
32+
assertFalse(channel.hasSubscribers);
33+
});

0 commit comments

Comments
 (0)