Skip to content

Commit ce6908d

Browse files
fix(audience): init does not mutate caller's AudienceConfig
Init auto-fills PersistentDataPath from DefaultPersistentDataPathProvider. The old code wrote that back onto the caller's config object — a surprising side-effect for callers who reuse the config. Clone via MemberwiseClone before the fill-in. Reference-typed properties (OnError, HttpHandler) are intentionally shared — cloning delegates and handlers would break them. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent ac0125a commit ce6908d

2 files changed

Lines changed: 7 additions & 0 deletions

File tree

src/Packages/Audience/Runtime/AudienceConfig.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,10 @@ public class AudienceConfig
4040

4141
// Test seam for HttpTransport; not part of the public API.
4242
internal System.Net.Http.HttpMessageHandler? HttpHandler { get; set; }
43+
44+
// Shallow copy so Init can populate PersistentDataPath without mutating
45+
// the caller's object. Reference-typed properties (OnError, HttpHandler)
46+
// are intentionally shared — cloning delegates/handlers is wrong.
47+
internal AudienceConfig Clone() => (AudienceConfig)MemberwiseClone();
4348
}
4449
}

src/Packages/Audience/Runtime/ImmutableAudience.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ public static void Init(AudienceConfig config)
5050
if (string.IsNullOrEmpty(config.PublishableKey))
5151
throw new ArgumentException("PublishableKey is required", nameof(config));
5252

53+
// Clone so Init's PersistentDataPath fill-in does not mutate the caller's object.
54+
config = config.Clone();
5355
if (string.IsNullOrEmpty(config.PersistentDataPath))
5456
config.PersistentDataPath = DefaultPersistentDataPathProvider?.Invoke();
5557
if (string.IsNullOrEmpty(config.PersistentDataPath))

0 commit comments

Comments
 (0)