Skip to content

Commit f46679a

Browse files
authored
fix: Reject "multi" as the kind of an individual context (#272)
Refs SDK-2383. ## Summary The string `"multi"` is reserved as the LaunchDarkly multi-context discriminator. An individual context must not use `"multi"` as its kind. The internal `_validKind` helper in `packages/common/lib/src/ld_context.dart` was only rejecting `"kind"`; building with `.kind("multi", ...)` was producing a *valid* `LDContext`, and a multi-context that included `"multi"` as one of its sub-kinds was also valid. ```dart bool _validKind(String kind) { - return kind != 'kind' && _kindExp.hasMatch(kind); + return kind != 'kind' && kind != 'multi' && _kindExp.hasMatch(kind); } ``` This propagates the kind validation Flutter SDK already implements for `"kind"` to also cover `"multi"`. Both single-kind and multi-context build paths run every sub-kind through `_validKind`, so a single change covers both. ## Test plan - [x] `flutter test test/ld_context_test.dart` — 36 tests pass (new + existing) - [x] `flutter test` (full common package) — 437 tests pass - [x] `dart analyze --fatal-infos lib test` — no issues - [x] `dart format` — no changes - [x] Manual: `LDContextBuilder().kind('multi', 'alice').build().valid` is now `false`; previously `true` - [x] Manual: a multi-context that includes a `"multi"` sub-kind builds as invalid <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: a small validation tightening that only changes behavior for previously-accepted invalid input (kind == "multi"). Main risk is backward incompatibility for callers incorrectly using "multi" as a kind, now producing invalid contexts. > > **Overview** > Reserves `"multi"` by updating kind validation so an individual context cannot use `kind == "multi"`, causing such contexts (and multi-contexts that include a `"multi"` sub-kind) to build as invalid. > > Updates tests to treat `"multi"` as an invalid kind and adds coverage ensuring invalid contexts return empty `canonicalKey` and `keys`. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit a2abb8f. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent 74ee884 commit f46679a

2 files changed

Lines changed: 14 additions & 3 deletions

File tree

packages/common/lib/src/ld_context.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ String _encodeKey(String key) {
2020
}
2121

2222
bool _validKind(String kind) {
23-
return kind != 'kind' && _kindExp.hasMatch(kind);
23+
return kind != 'kind' && kind != 'multi' && _kindExp.hasMatch(kind);
2424
}
2525

2626
bool _referenceIs(AttributeReference reference, String value) {

packages/common/test/ld_context_test.dart

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,22 @@ void main() {
5252
});
5353

5454
group('given invalid kinds', () {
55-
for (var kind in ['', 'kind', '#*%']) {
56-
test('invalid kinds produce invalid contexts', () {
55+
for (var kind in ['', 'kind', 'multi', '#*%']) {
56+
test('kind "$kind" produces an invalid context', () {
5757
expect(LDContextBuilder().kind(kind, 'my-key').build().valid, false);
5858
});
5959
}
60+
61+
test('a multi-context containing an individual "multi" kind is invalid',
62+
() {
63+
final context = LDContextBuilder()
64+
.kind('user', 'user-key')
65+
.kind('multi', 'other-key')
66+
.build();
67+
expect(context.valid, false);
68+
expect(context.canonicalKey, '');
69+
expect(context.keys, isEmpty);
70+
});
6071
});
6172

6273
test('can get the canonical key for an invalid context', () {

0 commit comments

Comments
 (0)