From 9a1c3960850758f807f4552ca0b8ecc268ea2077 Mon Sep 17 00:00:00 2001 From: AR Abdul Azeez Date: Tue, 22 Sep 2026 15:35:34 -0500 Subject: [PATCH 1/6] fix: [SDK-5335] reject null and empty identity strings Blank login, app id, language, alias, email, sms, tag key, trigger key, and custom event names were forwarded to native. One helper now drops those calls on Android and iOS. Co-authored-by: Cursor --- .../Runtime/AndroidInAppMessagesManager.cs | 27 +++++- .../Runtime/AndroidUserManager.cs | 86 ++++++++++++++++--- .../Runtime/InputGuard.cs | 42 +++++++++ com.onesignal.unity.core/Runtime/OneSignal.cs | 2 + .../Runtime/iOSInAppMessagesManager.cs | 27 +++++- .../Runtime/iOSUserManager.cs | 81 ++++++++++++++--- 6 files changed, 230 insertions(+), 35 deletions(-) create mode 100644 com.onesignal.unity.core/Runtime/InputGuard.cs diff --git a/com.onesignal.unity.android/Runtime/AndroidInAppMessagesManager.cs b/com.onesignal.unity.android/Runtime/AndroidInAppMessagesManager.cs index 741f760ac..45d6df26f 100644 --- a/com.onesignal.unity.android/Runtime/AndroidInAppMessagesManager.cs +++ b/com.onesignal.unity.android/Runtime/AndroidInAppMessagesManager.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; +using OneSignalSDK; using OneSignalSDK.Android.Utilities; using OneSignalSDK.InAppMessages; using OneSignalSDK.InAppMessages.Internal; @@ -56,16 +57,34 @@ public bool Paused set => _inAppMessages.Call("setPaused", value); } - public void AddTrigger(string key, string value) => + public void AddTrigger(string key, string value) + { + if (InputGuard.Missing(key, "addTrigger: key")) return; + if (value == null) + { + UnityEngine.Debug.LogError("OneSignal: addTrigger: value is required"); + return; + } _inAppMessages.Call("addTrigger", key, value); + } - public void AddTriggers(Dictionary triggers) => + public void AddTriggers(Dictionary triggers) + { + if (InputGuard.MissingEntries(triggers, "addTriggers", true)) return; _inAppMessages.Call("addTriggers", triggers.ToMap()); + } - public void RemoveTrigger(string key) => _inAppMessages.Call("removeTrigger", key); + public void RemoveTrigger(string key) + { + if (InputGuard.Missing(key, "removeTrigger: key")) return; + _inAppMessages.Call("removeTrigger", key); + } - public void RemoveTriggers(params string[] keys) => + public void RemoveTriggers(params string[] keys) + { + if (InputGuard.MissingAny(keys, "removeTriggers: key")) return; _inAppMessages.Call("removeTriggers", keys.ToArrayList()); + } public void ClearTriggers() => _inAppMessages.Call("clearTriggers"); diff --git a/com.onesignal.unity.android/Runtime/AndroidUserManager.cs b/com.onesignal.unity.android/Runtime/AndroidUserManager.cs index 1b7242a67..008061148 100644 --- a/com.onesignal.unity.android/Runtime/AndroidUserManager.cs +++ b/com.onesignal.unity.android/Runtime/AndroidUserManager.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; +using OneSignalSDK; using OneSignalSDK.Android.User.Models; using OneSignalSDK.Android.Utilities; using OneSignalSDK.User; @@ -73,7 +74,11 @@ public IPushSubscription PushSubscription public string Language { - set => _user.Call("setLanguage", value); + set + { + if (InputGuard.Missing(value, "setLanguage: language")) return; + _user.Call("setLanguage", value); + } } public Dictionary GetTags() @@ -82,35 +87,88 @@ public Dictionary GetTags() return obj.MapToDictionary(); } - public void AddTag(string key, string value) => _user.Call("addTag", key, value); + public void AddTag(string key, string value) + { + if (InputGuard.Missing(key, "addTag: key")) return; + if (value == null) + { + UnityEngine.Debug.LogError("OneSignal: addTag: value is required"); + return; + } + _user.Call("addTag", key, value); + } - public void AddTags(Dictionary tags) => _user.Call("addTags", tags.ToMap()); + public void AddTags(Dictionary tags) + { + if (InputGuard.MissingEntries(tags, "addTags", true)) return; + _user.Call("addTags", tags.ToMap()); + } - public void RemoveTag(string key) => _user.Call("removeTag", key); + public void RemoveTag(string key) + { + if (InputGuard.Missing(key, "removeTag: key")) return; + _user.Call("removeTag", key); + } - public void RemoveTags(params string[] keys) => + public void RemoveTags(params string[] keys) + { + if (InputGuard.MissingAny(keys, "removeTags: key")) return; _user.Call("removeTags", keys.ToArrayList()); + } - public void AddAlias(string label, string id) => _user.Call("addAlias", label, id); + public void AddAlias(string label, string id) + { + if (InputGuard.Missing(label, "addAlias: label") || InputGuard.Missing(id, "addAlias: id")) return; + _user.Call("addAlias", label, id); + } - public void AddAliases(Dictionary aliases) => + public void AddAliases(Dictionary aliases) + { + if (InputGuard.MissingEntries(aliases, "addAliases", false)) return; _user.Call("addAliases", aliases.ToMap()); + } - public void RemoveAlias(string label) => _user.Call("removeAlias", label); + public void RemoveAlias(string label) + { + if (InputGuard.Missing(label, "removeAlias: label")) return; + _user.Call("removeAlias", label); + } - public void RemoveAliases(params string[] labels) => + public void RemoveAliases(params string[] labels) + { + if (InputGuard.MissingAny(labels, "removeAliases: label")) return; _user.Call("removeAliases", labels.ToArrayList()); + } - public void AddEmail(string email) => _user.Call("addEmail", email); + public void AddEmail(string email) + { + if (InputGuard.Missing(email, "addEmail: email")) return; + _user.Call("addEmail", email); + } - public void RemoveEmail(string email) => _user.Call("removeEmail", email); + public void RemoveEmail(string email) + { + if (InputGuard.Missing(email, "removeEmail: email")) return; + _user.Call("removeEmail", email); + } - public void AddSms(string sms) => _user.Call("addSms", sms); + public void AddSms(string sms) + { + if (InputGuard.Missing(sms, "addSms: sms")) return; + _user.Call("addSms", sms); + } - public void RemoveSms(string sms) => _user.Call("removeSms", sms); + public void RemoveSms(string sms) + { + if (InputGuard.Missing(sms, "removeSms: sms")) return; + _user.Call("removeSms", sms); + } - public void TrackEvent(string name, Dictionary properties = null) => + public void TrackEvent(string name, Dictionary properties = null) + { + if (InputGuard.Missing(name, "trackEvent: name")) return; _user.Call("trackEvent", name, properties?.ToMap()); + } public void Initialize() { diff --git a/com.onesignal.unity.core/Runtime/InputGuard.cs b/com.onesignal.unity.core/Runtime/InputGuard.cs new file mode 100644 index 000000000..cba115dfa --- /dev/null +++ b/com.onesignal.unity.core/Runtime/InputGuard.cs @@ -0,0 +1,42 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace OneSignalSDK +{ + internal static class InputGuard + { + public static bool Missing(string value, string api) + { + if (!string.IsNullOrEmpty(value)) return false; + Debug.LogError("OneSignal: " + api + " is required"); + return true; + } + + public static bool MissingAny(string[] values, string api) + { + if (values == null) return Missing(null, api); + foreach (var value in values) + { + if (Missing(value, api)) return true; + } + return false; + } + + public static bool MissingEntries(IDictionary values, string api, bool allowEmptyValue) + { + if (values == null) return Missing(null, api); + foreach (var pair in values) + { + if (Missing(pair.Key, api + ": key")) return true; + if (allowEmptyValue) + { + if (pair.Value != null) continue; + Debug.LogError("OneSignal: " + api + ": value is required"); + return true; + } + if (Missing(pair.Value, api + ": value")) return true; + } + return false; + } + } +} diff --git a/com.onesignal.unity.core/Runtime/OneSignal.cs b/com.onesignal.unity.core/Runtime/OneSignal.cs index a4b905fa9..987091fa4 100755 --- a/com.onesignal.unity.core/Runtime/OneSignal.cs +++ b/com.onesignal.unity.core/Runtime/OneSignal.cs @@ -145,6 +145,7 @@ public static bool ConsentRequired /// Your application id from the OneSignal dashboard public static void Initialize(string appId) { + if (InputGuard.Missing(appId, "initialize: appId")) return; OneSignal.Default.Initialize(appId); } @@ -172,6 +173,7 @@ public static void Initialize(string appId) /// public static void Login(string externalId, string jwtBearerToken = null) { + if (InputGuard.Missing(externalId, "login: externalId")) return; OneSignal.Default.Login(externalId, jwtBearerToken); } diff --git a/com.onesignal.unity.ios/Runtime/iOSInAppMessagesManager.cs b/com.onesignal.unity.ios/Runtime/iOSInAppMessagesManager.cs index 43f0b446d..281412cc3 100644 --- a/com.onesignal.unity.ios/Runtime/iOSInAppMessagesManager.cs +++ b/com.onesignal.unity.ios/Runtime/iOSInAppMessagesManager.cs @@ -28,6 +28,7 @@ using System; using System.Collections.Generic; using System.Runtime.InteropServices; +using OneSignalSDK; using OneSignalSDK.InAppMessages; using OneSignalSDK.InAppMessages.Internal; using OneSignalSDK.InAppMessages.Models; @@ -105,16 +106,34 @@ public bool Paused set => _oneSignalInAppMessagesSetPaused(value); } - public void AddTrigger(string key, string value) => + public void AddTrigger(string key, string value) + { + if (InputGuard.Missing(key, "addTrigger: key")) return; + if (value == null) + { + Debug.LogError("OneSignal: addTrigger: value is required"); + return; + } _oneSignalInAppMessagesAddTrigger(key, value.ToString()); + } - public void AddTriggers(Dictionary triggers) => + public void AddTriggers(Dictionary triggers) + { + if (InputGuard.MissingEntries(triggers, "addTriggers", true)) return; _oneSignalInAppMessagesAddTriggers(Json.Serialize(triggers)); + } - public void RemoveTrigger(string key) => _oneSignalInAppMessagesRemoveTrigger(key); + public void RemoveTrigger(string key) + { + if (InputGuard.Missing(key, "removeTrigger: key")) return; + _oneSignalInAppMessagesRemoveTrigger(key); + } - public void RemoveTriggers(params string[] keys) => + public void RemoveTriggers(params string[] keys) + { + if (InputGuard.MissingAny(keys, "removeTriggers: key")) return; _oneSignalInAppMessagesRemoveTriggers(Json.Serialize(keys)); + } public void ClearTriggers() => _oneSignalInAppMessagesClearTriggers(); diff --git a/com.onesignal.unity.ios/Runtime/iOSUserManager.cs b/com.onesignal.unity.ios/Runtime/iOSUserManager.cs index 66ddd3449..2c55d9bbc 100644 --- a/com.onesignal.unity.ios/Runtime/iOSUserManager.cs +++ b/com.onesignal.unity.ios/Runtime/iOSUserManager.cs @@ -28,6 +28,7 @@ using System; using System.Collections.Generic; using System.Runtime.InteropServices; +using OneSignalSDK; using OneSignalSDK.iOS.User.Models; using OneSignalSDK.User; using OneSignalSDK.User.Internal; @@ -125,7 +126,11 @@ public IPushSubscription PushSubscription public string Language { - set => _oneSignalUserSetLanguage(value); + set + { + if (InputGuard.Missing(value, "setLanguage: language")) return; + _oneSignalUserSetLanguage(value); + } } public Dictionary GetTags() @@ -138,36 +143,86 @@ public Dictionary GetTags() return dict; } - public void AddTag(string key, string value) => _oneSignalUserAddTag(key, value); + public void AddTag(string key, string value) + { + if (InputGuard.Missing(key, "addTag: key")) return; + if (value == null) + { + Debug.LogError("OneSignal: addTag: value is required"); + return; + } + _oneSignalUserAddTag(key, value); + } - public void AddTags(Dictionary tags) => + public void AddTags(Dictionary tags) + { + if (InputGuard.MissingEntries(tags, "addTags", true)) return; _oneSignalUserAddTags(Json.Serialize(tags)); + } - public void RemoveTag(string key) => _oneSignalUserRemoveTag(key); + public void RemoveTag(string key) + { + if (InputGuard.Missing(key, "removeTag: key")) return; + _oneSignalUserRemoveTag(key); + } - public void RemoveTags(params string[] keys) => + public void RemoveTags(params string[] keys) + { + if (InputGuard.MissingAny(keys, "removeTags: key")) return; _oneSignalUserRemoveTags(Json.Serialize(keys)); + } - public void AddAlias(string label, string id) => _oneSignalUserAddAlias(label, id); + public void AddAlias(string label, string id) + { + if (InputGuard.Missing(label, "addAlias: label") || InputGuard.Missing(id, "addAlias: id")) return; + _oneSignalUserAddAlias(label, id); + } - public void AddAliases(Dictionary aliases) => + public void AddAliases(Dictionary aliases) + { + if (InputGuard.MissingEntries(aliases, "addAliases", false)) return; _oneSignalUserAddAliases(Json.Serialize(aliases)); + } - public void RemoveAlias(string label) => _oneSignalUserRemoveAlias(label); + public void RemoveAlias(string label) + { + if (InputGuard.Missing(label, "removeAlias: label")) return; + _oneSignalUserRemoveAlias(label); + } - public void RemoveAliases(params string[] labels) => + public void RemoveAliases(params string[] labels) + { + if (InputGuard.MissingAny(labels, "removeAliases: label")) return; _oneSignalUserRemoveAliases(Json.Serialize(labels)); + } - public void AddEmail(string email) => _oneSignalUserAddEmail(email); + public void AddEmail(string email) + { + if (InputGuard.Missing(email, "addEmail: email")) return; + _oneSignalUserAddEmail(email); + } - public void RemoveEmail(string email) => _oneSignalUserRemoveEmail(email); + public void RemoveEmail(string email) + { + if (InputGuard.Missing(email, "removeEmail: email")) return; + _oneSignalUserRemoveEmail(email); + } - public void AddSms(string sms) => _oneSignalUserAddSms(sms); + public void AddSms(string sms) + { + if (InputGuard.Missing(sms, "addSms: sms")) return; + _oneSignalUserAddSms(sms); + } - public void RemoveSms(string sms) => _oneSignalUserRemoveSms(sms); + public void RemoveSms(string sms) + { + if (InputGuard.Missing(sms, "removeSms: sms")) return; + _oneSignalUserRemoveSms(sms); + } public void TrackEvent(string name, Dictionary properties = null) { + if (InputGuard.Missing(name, "trackEvent: name")) return; if (properties != null) _oneSignalUserTrackEvent(name, Json.Serialize(properties)); else From bded5fa7ab2c503923beef1f1d67b0b205d67852 Mon Sep 17 00:00:00 2001 From: AR Abdul Azeez Date: Thu, 24 Sep 2026 12:28:44 -0500 Subject: [PATCH 2/6] fix: [SDK-5335] keep setLanguage("") as the device language reset Empty language is the only reset path. Null is still rejected. Co-authored-by: Cursor --- com.onesignal.unity.android/Runtime/AndroidUserManager.cs | 7 ++++++- com.onesignal.unity.ios/Runtime/iOSUserManager.cs | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/com.onesignal.unity.android/Runtime/AndroidUserManager.cs b/com.onesignal.unity.android/Runtime/AndroidUserManager.cs index 008061148..9e5bdc6d8 100644 --- a/com.onesignal.unity.android/Runtime/AndroidUserManager.cs +++ b/com.onesignal.unity.android/Runtime/AndroidUserManager.cs @@ -76,7 +76,12 @@ public string Language { set { - if (InputGuard.Missing(value, "setLanguage: language")) return; + // Empty string is the reset to the device language. Null is not. + if (value == null) + { + Debug.LogError("OneSignal: setLanguage: language is required"); + return; + } _user.Call("setLanguage", value); } } diff --git a/com.onesignal.unity.ios/Runtime/iOSUserManager.cs b/com.onesignal.unity.ios/Runtime/iOSUserManager.cs index 2c55d9bbc..0298d21bd 100644 --- a/com.onesignal.unity.ios/Runtime/iOSUserManager.cs +++ b/com.onesignal.unity.ios/Runtime/iOSUserManager.cs @@ -128,7 +128,12 @@ public string Language { set { - if (InputGuard.Missing(value, "setLanguage: language")) return; + // Empty string is the reset to the device language. Null is not. + if (value == null) + { + Debug.LogError("OneSignal: setLanguage: language is required"); + return; + } _oneSignalUserSetLanguage(value); } } From a456f04c700b7a647cb3f9d1a6692e0daed6d087 Mon Sep 17 00:00:00 2001 From: AR Abdul Azeez Date: Fri, 25 Sep 2026 12:47:23 -0500 Subject: [PATCH 3/6] fix: [SDK-5335] format input guards for csharpier CI rejects the single-line returns the formatter wants expanded. Co-authored-by: Cursor --- .../Runtime/AndroidInAppMessagesManager.cs | 12 ++++-- .../Runtime/AndroidUserManager.cs | 42 +++++++++++++------ .../Runtime/InputGuard.cs | 27 ++++++++---- com.onesignal.unity.core/Runtime/OneSignal.cs | 6 ++- .../Runtime/iOSInAppMessagesManager.cs | 12 ++++-- .../Runtime/iOSUserManager.cs | 42 +++++++++++++------ 6 files changed, 97 insertions(+), 44 deletions(-) diff --git a/com.onesignal.unity.android/Runtime/AndroidInAppMessagesManager.cs b/com.onesignal.unity.android/Runtime/AndroidInAppMessagesManager.cs index 45d6df26f..62467df3e 100644 --- a/com.onesignal.unity.android/Runtime/AndroidInAppMessagesManager.cs +++ b/com.onesignal.unity.android/Runtime/AndroidInAppMessagesManager.cs @@ -59,7 +59,8 @@ public bool Paused public void AddTrigger(string key, string value) { - if (InputGuard.Missing(key, "addTrigger: key")) return; + if (InputGuard.Missing(key, "addTrigger: key")) + return; if (value == null) { UnityEngine.Debug.LogError("OneSignal: addTrigger: value is required"); @@ -70,19 +71,22 @@ public void AddTrigger(string key, string value) public void AddTriggers(Dictionary triggers) { - if (InputGuard.MissingEntries(triggers, "addTriggers", true)) return; + if (InputGuard.MissingEntries(triggers, "addTriggers", true)) + return; _inAppMessages.Call("addTriggers", triggers.ToMap()); } public void RemoveTrigger(string key) { - if (InputGuard.Missing(key, "removeTrigger: key")) return; + if (InputGuard.Missing(key, "removeTrigger: key")) + return; _inAppMessages.Call("removeTrigger", key); } public void RemoveTriggers(params string[] keys) { - if (InputGuard.MissingAny(keys, "removeTriggers: key")) return; + if (InputGuard.MissingAny(keys, "removeTriggers: key")) + return; _inAppMessages.Call("removeTriggers", keys.ToArrayList()); } diff --git a/com.onesignal.unity.android/Runtime/AndroidUserManager.cs b/com.onesignal.unity.android/Runtime/AndroidUserManager.cs index 9e5bdc6d8..8e8e3d47d 100644 --- a/com.onesignal.unity.android/Runtime/AndroidUserManager.cs +++ b/com.onesignal.unity.android/Runtime/AndroidUserManager.cs @@ -94,7 +94,8 @@ public Dictionary GetTags() public void AddTag(string key, string value) { - if (InputGuard.Missing(key, "addTag: key")) return; + if (InputGuard.Missing(key, "addTag: key")) + return; if (value == null) { UnityEngine.Debug.LogError("OneSignal: addTag: value is required"); @@ -105,73 +106,88 @@ public void AddTag(string key, string value) public void AddTags(Dictionary tags) { - if (InputGuard.MissingEntries(tags, "addTags", true)) return; + if (InputGuard.MissingEntries(tags, "addTags", true)) + return; _user.Call("addTags", tags.ToMap()); } public void RemoveTag(string key) { - if (InputGuard.Missing(key, "removeTag: key")) return; + if (InputGuard.Missing(key, "removeTag: key")) + return; _user.Call("removeTag", key); } public void RemoveTags(params string[] keys) { - if (InputGuard.MissingAny(keys, "removeTags: key")) return; + if (InputGuard.MissingAny(keys, "removeTags: key")) + return; _user.Call("removeTags", keys.ToArrayList()); } public void AddAlias(string label, string id) { - if (InputGuard.Missing(label, "addAlias: label") || InputGuard.Missing(id, "addAlias: id")) return; + if ( + InputGuard.Missing(label, "addAlias: label") + || InputGuard.Missing(id, "addAlias: id") + ) + return; _user.Call("addAlias", label, id); } public void AddAliases(Dictionary aliases) { - if (InputGuard.MissingEntries(aliases, "addAliases", false)) return; + if (InputGuard.MissingEntries(aliases, "addAliases", false)) + return; _user.Call("addAliases", aliases.ToMap()); } public void RemoveAlias(string label) { - if (InputGuard.Missing(label, "removeAlias: label")) return; + if (InputGuard.Missing(label, "removeAlias: label")) + return; _user.Call("removeAlias", label); } public void RemoveAliases(params string[] labels) { - if (InputGuard.MissingAny(labels, "removeAliases: label")) return; + if (InputGuard.MissingAny(labels, "removeAliases: label")) + return; _user.Call("removeAliases", labels.ToArrayList()); } public void AddEmail(string email) { - if (InputGuard.Missing(email, "addEmail: email")) return; + if (InputGuard.Missing(email, "addEmail: email")) + return; _user.Call("addEmail", email); } public void RemoveEmail(string email) { - if (InputGuard.Missing(email, "removeEmail: email")) return; + if (InputGuard.Missing(email, "removeEmail: email")) + return; _user.Call("removeEmail", email); } public void AddSms(string sms) { - if (InputGuard.Missing(sms, "addSms: sms")) return; + if (InputGuard.Missing(sms, "addSms: sms")) + return; _user.Call("addSms", sms); } public void RemoveSms(string sms) { - if (InputGuard.Missing(sms, "removeSms: sms")) return; + if (InputGuard.Missing(sms, "removeSms: sms")) + return; _user.Call("removeSms", sms); } public void TrackEvent(string name, Dictionary properties = null) { - if (InputGuard.Missing(name, "trackEvent: name")) return; + if (InputGuard.Missing(name, "trackEvent: name")) + return; _user.Call("trackEvent", name, properties?.ToMap()); } diff --git a/com.onesignal.unity.core/Runtime/InputGuard.cs b/com.onesignal.unity.core/Runtime/InputGuard.cs index cba115dfa..383825784 100644 --- a/com.onesignal.unity.core/Runtime/InputGuard.cs +++ b/com.onesignal.unity.core/Runtime/InputGuard.cs @@ -7,34 +7,45 @@ internal static class InputGuard { public static bool Missing(string value, string api) { - if (!string.IsNullOrEmpty(value)) return false; + if (!string.IsNullOrEmpty(value)) + return false; Debug.LogError("OneSignal: " + api + " is required"); return true; } public static bool MissingAny(string[] values, string api) { - if (values == null) return Missing(null, api); + if (values == null) + return Missing(null, api); foreach (var value in values) { - if (Missing(value, api)) return true; + if (Missing(value, api)) + return true; } return false; } - public static bool MissingEntries(IDictionary values, string api, bool allowEmptyValue) + public static bool MissingEntries( + IDictionary values, + string api, + bool allowEmptyValue + ) { - if (values == null) return Missing(null, api); + if (values == null) + return Missing(null, api); foreach (var pair in values) { - if (Missing(pair.Key, api + ": key")) return true; + if (Missing(pair.Key, api + ": key")) + return true; if (allowEmptyValue) { - if (pair.Value != null) continue; + if (pair.Value != null) + continue; Debug.LogError("OneSignal: " + api + ": value is required"); return true; } - if (Missing(pair.Value, api + ": value")) return true; + if (Missing(pair.Value, api + ": value")) + return true; } return false; } diff --git a/com.onesignal.unity.core/Runtime/OneSignal.cs b/com.onesignal.unity.core/Runtime/OneSignal.cs index 987091fa4..6bb2176fc 100755 --- a/com.onesignal.unity.core/Runtime/OneSignal.cs +++ b/com.onesignal.unity.core/Runtime/OneSignal.cs @@ -145,7 +145,8 @@ public static bool ConsentRequired /// Your application id from the OneSignal dashboard public static void Initialize(string appId) { - if (InputGuard.Missing(appId, "initialize: appId")) return; + if (InputGuard.Missing(appId, "initialize: appId")) + return; OneSignal.Default.Initialize(appId); } @@ -173,7 +174,8 @@ public static void Initialize(string appId) /// public static void Login(string externalId, string jwtBearerToken = null) { - if (InputGuard.Missing(externalId, "login: externalId")) return; + if (InputGuard.Missing(externalId, "login: externalId")) + return; OneSignal.Default.Login(externalId, jwtBearerToken); } diff --git a/com.onesignal.unity.ios/Runtime/iOSInAppMessagesManager.cs b/com.onesignal.unity.ios/Runtime/iOSInAppMessagesManager.cs index 281412cc3..9bef50cff 100644 --- a/com.onesignal.unity.ios/Runtime/iOSInAppMessagesManager.cs +++ b/com.onesignal.unity.ios/Runtime/iOSInAppMessagesManager.cs @@ -108,7 +108,8 @@ public bool Paused public void AddTrigger(string key, string value) { - if (InputGuard.Missing(key, "addTrigger: key")) return; + if (InputGuard.Missing(key, "addTrigger: key")) + return; if (value == null) { Debug.LogError("OneSignal: addTrigger: value is required"); @@ -119,19 +120,22 @@ public void AddTrigger(string key, string value) public void AddTriggers(Dictionary triggers) { - if (InputGuard.MissingEntries(triggers, "addTriggers", true)) return; + if (InputGuard.MissingEntries(triggers, "addTriggers", true)) + return; _oneSignalInAppMessagesAddTriggers(Json.Serialize(triggers)); } public void RemoveTrigger(string key) { - if (InputGuard.Missing(key, "removeTrigger: key")) return; + if (InputGuard.Missing(key, "removeTrigger: key")) + return; _oneSignalInAppMessagesRemoveTrigger(key); } public void RemoveTriggers(params string[] keys) { - if (InputGuard.MissingAny(keys, "removeTriggers: key")) return; + if (InputGuard.MissingAny(keys, "removeTriggers: key")) + return; _oneSignalInAppMessagesRemoveTriggers(Json.Serialize(keys)); } diff --git a/com.onesignal.unity.ios/Runtime/iOSUserManager.cs b/com.onesignal.unity.ios/Runtime/iOSUserManager.cs index 0298d21bd..a6246e93c 100644 --- a/com.onesignal.unity.ios/Runtime/iOSUserManager.cs +++ b/com.onesignal.unity.ios/Runtime/iOSUserManager.cs @@ -150,7 +150,8 @@ public Dictionary GetTags() public void AddTag(string key, string value) { - if (InputGuard.Missing(key, "addTag: key")) return; + if (InputGuard.Missing(key, "addTag: key")) + return; if (value == null) { Debug.LogError("OneSignal: addTag: value is required"); @@ -161,73 +162,88 @@ public void AddTag(string key, string value) public void AddTags(Dictionary tags) { - if (InputGuard.MissingEntries(tags, "addTags", true)) return; + if (InputGuard.MissingEntries(tags, "addTags", true)) + return; _oneSignalUserAddTags(Json.Serialize(tags)); } public void RemoveTag(string key) { - if (InputGuard.Missing(key, "removeTag: key")) return; + if (InputGuard.Missing(key, "removeTag: key")) + return; _oneSignalUserRemoveTag(key); } public void RemoveTags(params string[] keys) { - if (InputGuard.MissingAny(keys, "removeTags: key")) return; + if (InputGuard.MissingAny(keys, "removeTags: key")) + return; _oneSignalUserRemoveTags(Json.Serialize(keys)); } public void AddAlias(string label, string id) { - if (InputGuard.Missing(label, "addAlias: label") || InputGuard.Missing(id, "addAlias: id")) return; + if ( + InputGuard.Missing(label, "addAlias: label") + || InputGuard.Missing(id, "addAlias: id") + ) + return; _oneSignalUserAddAlias(label, id); } public void AddAliases(Dictionary aliases) { - if (InputGuard.MissingEntries(aliases, "addAliases", false)) return; + if (InputGuard.MissingEntries(aliases, "addAliases", false)) + return; _oneSignalUserAddAliases(Json.Serialize(aliases)); } public void RemoveAlias(string label) { - if (InputGuard.Missing(label, "removeAlias: label")) return; + if (InputGuard.Missing(label, "removeAlias: label")) + return; _oneSignalUserRemoveAlias(label); } public void RemoveAliases(params string[] labels) { - if (InputGuard.MissingAny(labels, "removeAliases: label")) return; + if (InputGuard.MissingAny(labels, "removeAliases: label")) + return; _oneSignalUserRemoveAliases(Json.Serialize(labels)); } public void AddEmail(string email) { - if (InputGuard.Missing(email, "addEmail: email")) return; + if (InputGuard.Missing(email, "addEmail: email")) + return; _oneSignalUserAddEmail(email); } public void RemoveEmail(string email) { - if (InputGuard.Missing(email, "removeEmail: email")) return; + if (InputGuard.Missing(email, "removeEmail: email")) + return; _oneSignalUserRemoveEmail(email); } public void AddSms(string sms) { - if (InputGuard.Missing(sms, "addSms: sms")) return; + if (InputGuard.Missing(sms, "addSms: sms")) + return; _oneSignalUserAddSms(sms); } public void RemoveSms(string sms) { - if (InputGuard.Missing(sms, "removeSms: sms")) return; + if (InputGuard.Missing(sms, "removeSms: sms")) + return; _oneSignalUserRemoveSms(sms); } public void TrackEvent(string name, Dictionary properties = null) { - if (InputGuard.Missing(name, "trackEvent: name")) return; + if (InputGuard.Missing(name, "trackEvent: name")) + return; if (properties != null) _oneSignalUserTrackEvent(name, Json.Serialize(properties)); else From 5762f1959a7dc809f9b439b7671b3997e078f28b Mon Sep 17 00:00:00 2001 From: AR Abdul Azeez Date: Tue, 29 Sep 2026 14:57:59 -0700 Subject: [PATCH 4/6] fix: [SDK-5335] rename input guards to isMissing The checks read as predicates: isMissing, isMissingAny, and hasMissingEntries. --- .../Runtime/AndroidInAppMessagesManager.cs | 8 +++--- .../Runtime/AndroidUserManager.cs | 28 +++++++++---------- .../Runtime/InputGuard.cs | 16 +++++------ com.onesignal.unity.core/Runtime/OneSignal.cs | 4 +-- .../Runtime/iOSInAppMessagesManager.cs | 8 +++--- .../Runtime/iOSUserManager.cs | 28 +++++++++---------- 6 files changed, 46 insertions(+), 46 deletions(-) diff --git a/com.onesignal.unity.android/Runtime/AndroidInAppMessagesManager.cs b/com.onesignal.unity.android/Runtime/AndroidInAppMessagesManager.cs index 62467df3e..33cc4f424 100644 --- a/com.onesignal.unity.android/Runtime/AndroidInAppMessagesManager.cs +++ b/com.onesignal.unity.android/Runtime/AndroidInAppMessagesManager.cs @@ -59,7 +59,7 @@ public bool Paused public void AddTrigger(string key, string value) { - if (InputGuard.Missing(key, "addTrigger: key")) + if (InputGuard.IsMissing(key, "addTrigger: key")) return; if (value == null) { @@ -71,21 +71,21 @@ public void AddTrigger(string key, string value) public void AddTriggers(Dictionary triggers) { - if (InputGuard.MissingEntries(triggers, "addTriggers", true)) + if (InputGuard.HasMissingEntries(triggers, "addTriggers", true)) return; _inAppMessages.Call("addTriggers", triggers.ToMap()); } public void RemoveTrigger(string key) { - if (InputGuard.Missing(key, "removeTrigger: key")) + if (InputGuard.IsMissing(key, "removeTrigger: key")) return; _inAppMessages.Call("removeTrigger", key); } public void RemoveTriggers(params string[] keys) { - if (InputGuard.MissingAny(keys, "removeTriggers: key")) + if (InputGuard.IsMissingAny(keys, "removeTriggers: key")) return; _inAppMessages.Call("removeTriggers", keys.ToArrayList()); } diff --git a/com.onesignal.unity.android/Runtime/AndroidUserManager.cs b/com.onesignal.unity.android/Runtime/AndroidUserManager.cs index 8e8e3d47d..318bf7e75 100644 --- a/com.onesignal.unity.android/Runtime/AndroidUserManager.cs +++ b/com.onesignal.unity.android/Runtime/AndroidUserManager.cs @@ -94,7 +94,7 @@ public Dictionary GetTags() public void AddTag(string key, string value) { - if (InputGuard.Missing(key, "addTag: key")) + if (InputGuard.IsMissing(key, "addTag: key")) return; if (value == null) { @@ -106,21 +106,21 @@ public void AddTag(string key, string value) public void AddTags(Dictionary tags) { - if (InputGuard.MissingEntries(tags, "addTags", true)) + if (InputGuard.HasMissingEntries(tags, "addTags", true)) return; _user.Call("addTags", tags.ToMap()); } public void RemoveTag(string key) { - if (InputGuard.Missing(key, "removeTag: key")) + if (InputGuard.IsMissing(key, "removeTag: key")) return; _user.Call("removeTag", key); } public void RemoveTags(params string[] keys) { - if (InputGuard.MissingAny(keys, "removeTags: key")) + if (InputGuard.IsMissingAny(keys, "removeTags: key")) return; _user.Call("removeTags", keys.ToArrayList()); } @@ -128,8 +128,8 @@ public void RemoveTags(params string[] keys) public void AddAlias(string label, string id) { if ( - InputGuard.Missing(label, "addAlias: label") - || InputGuard.Missing(id, "addAlias: id") + InputGuard.IsMissing(label, "addAlias: label") + || InputGuard.IsMissing(id, "addAlias: id") ) return; _user.Call("addAlias", label, id); @@ -137,56 +137,56 @@ public void AddAlias(string label, string id) public void AddAliases(Dictionary aliases) { - if (InputGuard.MissingEntries(aliases, "addAliases", false)) + if (InputGuard.HasMissingEntries(aliases, "addAliases", false)) return; _user.Call("addAliases", aliases.ToMap()); } public void RemoveAlias(string label) { - if (InputGuard.Missing(label, "removeAlias: label")) + if (InputGuard.IsMissing(label, "removeAlias: label")) return; _user.Call("removeAlias", label); } public void RemoveAliases(params string[] labels) { - if (InputGuard.MissingAny(labels, "removeAliases: label")) + if (InputGuard.IsMissingAny(labels, "removeAliases: label")) return; _user.Call("removeAliases", labels.ToArrayList()); } public void AddEmail(string email) { - if (InputGuard.Missing(email, "addEmail: email")) + if (InputGuard.IsMissing(email, "addEmail: email")) return; _user.Call("addEmail", email); } public void RemoveEmail(string email) { - if (InputGuard.Missing(email, "removeEmail: email")) + if (InputGuard.IsMissing(email, "removeEmail: email")) return; _user.Call("removeEmail", email); } public void AddSms(string sms) { - if (InputGuard.Missing(sms, "addSms: sms")) + if (InputGuard.IsMissing(sms, "addSms: sms")) return; _user.Call("addSms", sms); } public void RemoveSms(string sms) { - if (InputGuard.Missing(sms, "removeSms: sms")) + if (InputGuard.IsMissing(sms, "removeSms: sms")) return; _user.Call("removeSms", sms); } public void TrackEvent(string name, Dictionary properties = null) { - if (InputGuard.Missing(name, "trackEvent: name")) + if (InputGuard.IsMissing(name, "trackEvent: name")) return; _user.Call("trackEvent", name, properties?.ToMap()); } diff --git a/com.onesignal.unity.core/Runtime/InputGuard.cs b/com.onesignal.unity.core/Runtime/InputGuard.cs index 383825784..cb3bd11be 100644 --- a/com.onesignal.unity.core/Runtime/InputGuard.cs +++ b/com.onesignal.unity.core/Runtime/InputGuard.cs @@ -5,7 +5,7 @@ namespace OneSignalSDK { internal static class InputGuard { - public static bool Missing(string value, string api) + public static bool IsMissing(string value, string api) { if (!string.IsNullOrEmpty(value)) return false; @@ -13,29 +13,29 @@ public static bool Missing(string value, string api) return true; } - public static bool MissingAny(string[] values, string api) + public static bool IsMissingAny(string[] values, string api) { if (values == null) - return Missing(null, api); + return IsMissing(null, api); foreach (var value in values) { - if (Missing(value, api)) + if (IsMissing(value, api)) return true; } return false; } - public static bool MissingEntries( + public static bool HasMissingEntries( IDictionary values, string api, bool allowEmptyValue ) { if (values == null) - return Missing(null, api); + return IsMissing(null, api); foreach (var pair in values) { - if (Missing(pair.Key, api + ": key")) + if (IsMissing(pair.Key, api + ": key")) return true; if (allowEmptyValue) { @@ -44,7 +44,7 @@ bool allowEmptyValue Debug.LogError("OneSignal: " + api + ": value is required"); return true; } - if (Missing(pair.Value, api + ": value")) + if (IsMissing(pair.Value, api + ": value")) return true; } return false; diff --git a/com.onesignal.unity.core/Runtime/OneSignal.cs b/com.onesignal.unity.core/Runtime/OneSignal.cs index 6bb2176fc..fd8fe583a 100755 --- a/com.onesignal.unity.core/Runtime/OneSignal.cs +++ b/com.onesignal.unity.core/Runtime/OneSignal.cs @@ -145,7 +145,7 @@ public static bool ConsentRequired /// Your application id from the OneSignal dashboard public static void Initialize(string appId) { - if (InputGuard.Missing(appId, "initialize: appId")) + if (InputGuard.IsMissing(appId, "initialize: appId")) return; OneSignal.Default.Initialize(appId); } @@ -174,7 +174,7 @@ public static void Initialize(string appId) /// public static void Login(string externalId, string jwtBearerToken = null) { - if (InputGuard.Missing(externalId, "login: externalId")) + if (InputGuard.IsMissing(externalId, "login: externalId")) return; OneSignal.Default.Login(externalId, jwtBearerToken); } diff --git a/com.onesignal.unity.ios/Runtime/iOSInAppMessagesManager.cs b/com.onesignal.unity.ios/Runtime/iOSInAppMessagesManager.cs index 9bef50cff..413561aae 100644 --- a/com.onesignal.unity.ios/Runtime/iOSInAppMessagesManager.cs +++ b/com.onesignal.unity.ios/Runtime/iOSInAppMessagesManager.cs @@ -108,7 +108,7 @@ public bool Paused public void AddTrigger(string key, string value) { - if (InputGuard.Missing(key, "addTrigger: key")) + if (InputGuard.IsMissing(key, "addTrigger: key")) return; if (value == null) { @@ -120,21 +120,21 @@ public void AddTrigger(string key, string value) public void AddTriggers(Dictionary triggers) { - if (InputGuard.MissingEntries(triggers, "addTriggers", true)) + if (InputGuard.HasMissingEntries(triggers, "addTriggers", true)) return; _oneSignalInAppMessagesAddTriggers(Json.Serialize(triggers)); } public void RemoveTrigger(string key) { - if (InputGuard.Missing(key, "removeTrigger: key")) + if (InputGuard.IsMissing(key, "removeTrigger: key")) return; _oneSignalInAppMessagesRemoveTrigger(key); } public void RemoveTriggers(params string[] keys) { - if (InputGuard.MissingAny(keys, "removeTriggers: key")) + if (InputGuard.IsMissingAny(keys, "removeTriggers: key")) return; _oneSignalInAppMessagesRemoveTriggers(Json.Serialize(keys)); } diff --git a/com.onesignal.unity.ios/Runtime/iOSUserManager.cs b/com.onesignal.unity.ios/Runtime/iOSUserManager.cs index a6246e93c..fd6c3c7d0 100644 --- a/com.onesignal.unity.ios/Runtime/iOSUserManager.cs +++ b/com.onesignal.unity.ios/Runtime/iOSUserManager.cs @@ -150,7 +150,7 @@ public Dictionary GetTags() public void AddTag(string key, string value) { - if (InputGuard.Missing(key, "addTag: key")) + if (InputGuard.IsMissing(key, "addTag: key")) return; if (value == null) { @@ -162,21 +162,21 @@ public void AddTag(string key, string value) public void AddTags(Dictionary tags) { - if (InputGuard.MissingEntries(tags, "addTags", true)) + if (InputGuard.HasMissingEntries(tags, "addTags", true)) return; _oneSignalUserAddTags(Json.Serialize(tags)); } public void RemoveTag(string key) { - if (InputGuard.Missing(key, "removeTag: key")) + if (InputGuard.IsMissing(key, "removeTag: key")) return; _oneSignalUserRemoveTag(key); } public void RemoveTags(params string[] keys) { - if (InputGuard.MissingAny(keys, "removeTags: key")) + if (InputGuard.IsMissingAny(keys, "removeTags: key")) return; _oneSignalUserRemoveTags(Json.Serialize(keys)); } @@ -184,8 +184,8 @@ public void RemoveTags(params string[] keys) public void AddAlias(string label, string id) { if ( - InputGuard.Missing(label, "addAlias: label") - || InputGuard.Missing(id, "addAlias: id") + InputGuard.IsMissing(label, "addAlias: label") + || InputGuard.IsMissing(id, "addAlias: id") ) return; _oneSignalUserAddAlias(label, id); @@ -193,56 +193,56 @@ public void AddAlias(string label, string id) public void AddAliases(Dictionary aliases) { - if (InputGuard.MissingEntries(aliases, "addAliases", false)) + if (InputGuard.HasMissingEntries(aliases, "addAliases", false)) return; _oneSignalUserAddAliases(Json.Serialize(aliases)); } public void RemoveAlias(string label) { - if (InputGuard.Missing(label, "removeAlias: label")) + if (InputGuard.IsMissing(label, "removeAlias: label")) return; _oneSignalUserRemoveAlias(label); } public void RemoveAliases(params string[] labels) { - if (InputGuard.MissingAny(labels, "removeAliases: label")) + if (InputGuard.IsMissingAny(labels, "removeAliases: label")) return; _oneSignalUserRemoveAliases(Json.Serialize(labels)); } public void AddEmail(string email) { - if (InputGuard.Missing(email, "addEmail: email")) + if (InputGuard.IsMissing(email, "addEmail: email")) return; _oneSignalUserAddEmail(email); } public void RemoveEmail(string email) { - if (InputGuard.Missing(email, "removeEmail: email")) + if (InputGuard.IsMissing(email, "removeEmail: email")) return; _oneSignalUserRemoveEmail(email); } public void AddSms(string sms) { - if (InputGuard.Missing(sms, "addSms: sms")) + if (InputGuard.IsMissing(sms, "addSms: sms")) return; _oneSignalUserAddSms(sms); } public void RemoveSms(string sms) { - if (InputGuard.Missing(sms, "removeSms: sms")) + if (InputGuard.IsMissing(sms, "removeSms: sms")) return; _oneSignalUserRemoveSms(sms); } public void TrackEvent(string name, Dictionary properties = null) { - if (InputGuard.Missing(name, "trackEvent: name")) + if (InputGuard.IsMissing(name, "trackEvent: name")) return; if (properties != null) _oneSignalUserTrackEvent(name, Json.Serialize(properties)); From b2b6f8853da436b212473281de2ae9ab15a7261f Mon Sep 17 00:00:00 2001 From: Fadi George Date: Fri, 2 Oct 2026 20:54:59 -0700 Subject: [PATCH 5/6] fix: guard missing and non-finite inputs --- .../Runtime/AndroidSessionManager.cs | 23 +++++++-- .../Runtime/AndroidUserManager.cs | 2 +- .../Runtime/InputGuard.cs | 48 +++++++++++++++++++ .../Runtime/iOSLiveActivitiesManager.cs | 24 +++++++++- .../Runtime/iOSSessionManager.cs | 23 +++++++-- .../Runtime/iOSUserManager.cs | 5 +- 6 files changed, 115 insertions(+), 10 deletions(-) diff --git a/com.onesignal.unity.android/Runtime/AndroidSessionManager.cs b/com.onesignal.unity.android/Runtime/AndroidSessionManager.cs index cb729bd55..af081a2f8 100644 --- a/com.onesignal.unity.android/Runtime/AndroidSessionManager.cs +++ b/com.onesignal.unity.android/Runtime/AndroidSessionManager.cs @@ -39,11 +39,28 @@ public AndroidSessionManager(AndroidJavaClass sdkClass) _session = sdkClass.CallStatic("getSession"); } - public void AddOutcome(string name) => _session.Call("addOutcome", name); + public void AddOutcome(string name) + { + if (InputGuard.IsMissing(name, "addOutcome: name")) + return; + _session.Call("addOutcome", name); + } - public void AddUniqueOutcome(string name) => _session.Call("addUniqueOutcome", name); + public void AddUniqueOutcome(string name) + { + if (InputGuard.IsMissing(name, "addUniqueOutcome: name")) + return; + _session.Call("addUniqueOutcome", name); + } - public void AddOutcomeWithValue(string name, float value) => + public void AddOutcomeWithValue(string name, float value) + { + if ( + InputGuard.IsMissing(name, "addOutcomeWithValue: name") + || InputGuard.IsNotFinite(value, "addOutcomeWithValue: value") + ) + return; _session.Call("addOutcomeWithValue", name, value); + } } } diff --git a/com.onesignal.unity.android/Runtime/AndroidUserManager.cs b/com.onesignal.unity.android/Runtime/AndroidUserManager.cs index 318bf7e75..8c247611b 100644 --- a/com.onesignal.unity.android/Runtime/AndroidUserManager.cs +++ b/com.onesignal.unity.android/Runtime/AndroidUserManager.cs @@ -188,7 +188,7 @@ public void TrackEvent(string name, Dictionary properties = null { if (InputGuard.IsMissing(name, "trackEvent: name")) return; - _user.Call("trackEvent", name, properties?.ToMap()); + _user.Call("trackEvent", name, InputGuard.ReplaceNonFiniteNumbers(properties)?.ToMap()); } public void Initialize() diff --git a/com.onesignal.unity.core/Runtime/InputGuard.cs b/com.onesignal.unity.core/Runtime/InputGuard.cs index cb3bd11be..29fb09514 100644 --- a/com.onesignal.unity.core/Runtime/InputGuard.cs +++ b/com.onesignal.unity.core/Runtime/InputGuard.cs @@ -25,6 +25,54 @@ public static bool IsMissingAny(string[] values, string api) return false; } + public static bool IsMissing(object value, string api) + { + if (value != null) + return false; + Debug.LogError("OneSignal: " + api + " is required"); + return true; + } + + public static bool IsNotFinite(float value, string api) + { + if (!float.IsNaN(value) && !float.IsInfinity(value)) + return false; + Debug.LogError("OneSignal: " + api + " must be a finite number"); + return true; + } + + // Native JSON serializers reject NaN and Infinity (Android throws, iOS drops the payload). + public static Dictionary ReplaceNonFiniteNumbers( + IDictionary values + ) + { + if (values == null) + return null; + var result = new Dictionary(values.Count); + foreach (var pair in values) + result[pair.Key] = ReplaceNonFiniteNumber(pair.Value); + return result; + } + + private static object ReplaceNonFiniteNumber(object value) + { + switch (value) + { + case double d when double.IsNaN(d) || double.IsInfinity(d): + case float f when float.IsNaN(f) || float.IsInfinity(f): + return null; + case IDictionary dict: + return ReplaceNonFiniteNumbers(dict); + case IList list: + var items = new List(list.Count); + foreach (var item in list) + items.Add(ReplaceNonFiniteNumber(item)); + return items; + default: + return value; + } + } + public static bool HasMissingEntries( IDictionary values, string api, diff --git a/com.onesignal.unity.ios/Runtime/iOSLiveActivitiesManager.cs b/com.onesignal.unity.ios/Runtime/iOSLiveActivitiesManager.cs index 7562942f9..45bf4d632 100644 --- a/com.onesignal.unity.ios/Runtime/iOSLiveActivitiesManager.cs +++ b/com.onesignal.unity.ios/Runtime/iOSLiveActivitiesManager.cs @@ -70,6 +70,11 @@ BooleanResponseDelegate callback public async Task EnterAsync(string activityId, string token) { + if ( + InputGuard.IsMissing(activityId, "enter: activityId") + || InputGuard.IsMissing(token, "enter: token") + ) + return false; var (proxy, hashCode) = WaitingProxy._setupProxy(); _oneSignalEnterLiveActivity(activityId, token, hashCode, BooleanCallbackProxy); return await proxy; @@ -78,6 +83,8 @@ public async Task EnterAsync(string activityId, string token) [System.Obsolete("Currently unsupported, avoid using this method.")] public async Task ExitAsync(string activityId) { + if (InputGuard.IsMissing(activityId, "exit: activityId")) + return false; var (proxy, hashCode) = WaitingProxy._setupProxy(); _oneSignalExitLiveActivity(activityId, hashCode, BooleanCallbackProxy); return await proxy; @@ -85,11 +92,18 @@ public async Task ExitAsync(string activityId) public void RemovePushToStartToken(string activityType) { + if (InputGuard.IsMissing(activityType, "removePushToStartToken: activityType")) + return; _oneSignalRemovePushToStartToken(activityType); } public void SetPushToStartToken(string activityType, string token) { + if ( + InputGuard.IsMissing(activityType, "setPushToStartToken: activityType") + || InputGuard.IsMissing(token, "setPushToStartToken: token") + ) + return; _oneSignalSetPushToStartToken(activityType, token); } @@ -116,10 +130,16 @@ public void StartDefault( IDictionary content ) { + if ( + InputGuard.IsMissing(activityId, "startDefault: activityId") + || InputGuard.IsMissing(attributes, "startDefault: attributes") + || InputGuard.IsMissing(content, "startDefault: content") + ) + return; _oneSignalStartDefaultLiveActivity( activityId, - Json.Serialize(attributes), - Json.Serialize(content) + Json.Serialize(InputGuard.ReplaceNonFiniteNumbers(attributes)), + Json.Serialize(InputGuard.ReplaceNonFiniteNumbers(content)) ); } diff --git a/com.onesignal.unity.ios/Runtime/iOSSessionManager.cs b/com.onesignal.unity.ios/Runtime/iOSSessionManager.cs index e8a0d0349..be5adf310 100644 --- a/com.onesignal.unity.ios/Runtime/iOSSessionManager.cs +++ b/com.onesignal.unity.ios/Runtime/iOSSessionManager.cs @@ -42,11 +42,28 @@ internal sealed class iOSSessionManager : ISessionManager [DllImport("__Internal")] private static extern void _oneSignalSessionAddOutcomeWithValue(string name, float value); - public void AddOutcome(string name) => _oneSignalSessionAddOutcome(name); + public void AddOutcome(string name) + { + if (InputGuard.IsMissing(name, "addOutcome: name")) + return; + _oneSignalSessionAddOutcome(name); + } - public void AddUniqueOutcome(string name) => _oneSignalSessionAddUniqueOutcome(name); + public void AddUniqueOutcome(string name) + { + if (InputGuard.IsMissing(name, "addUniqueOutcome: name")) + return; + _oneSignalSessionAddUniqueOutcome(name); + } - public void AddOutcomeWithValue(string name, float value) => + public void AddOutcomeWithValue(string name, float value) + { + if ( + InputGuard.IsMissing(name, "addOutcomeWithValue: name") + || InputGuard.IsNotFinite(value, "addOutcomeWithValue: value") + ) + return; _oneSignalSessionAddOutcomeWithValue(name, value); + } } } diff --git a/com.onesignal.unity.ios/Runtime/iOSUserManager.cs b/com.onesignal.unity.ios/Runtime/iOSUserManager.cs index fd6c3c7d0..dc60cf13d 100644 --- a/com.onesignal.unity.ios/Runtime/iOSUserManager.cs +++ b/com.onesignal.unity.ios/Runtime/iOSUserManager.cs @@ -245,7 +245,10 @@ public void TrackEvent(string name, Dictionary properties = null if (InputGuard.IsMissing(name, "trackEvent: name")) return; if (properties != null) - _oneSignalUserTrackEvent(name, Json.Serialize(properties)); + _oneSignalUserTrackEvent( + name, + Json.Serialize(InputGuard.ReplaceNonFiniteNumbers(properties)) + ); else _oneSignalUserTrackEvent(name, null); } From 1c3365bfea86acd17a514a393ef038be3196ca83 Mon Sep 17 00:00:00 2001 From: Fadi George Date: Fri, 2 Oct 2026 21:31:17 -0700 Subject: [PATCH 6/6] fix(sdk): guard invalid inputs across platforms --- .../Runtime/AndroidDebugManager.cs | 4 +++ .../Runtime/AndroidInAppMessagesManager.cs | 10 +++--- .../Runtime/AndroidUserManager.cs | 15 +++----- .../Runtime/OneSignalAndroid.cs | 4 +++ .../Runtime/InputGuard.cs | 35 +++++++++++-------- com.onesignal.unity.core/Runtime/OneSignal.cs | 4 --- .../Runtime/OneSignaliOS.cs | 6 +++- .../Runtime/iOSDebugManager.cs | 4 +++ .../Runtime/iOSInAppMessagesManager.cs | 12 +++---- .../Runtime/iOSLiveActivitiesManager.cs | 4 +-- .../Runtime/iOSUserManager.cs | 15 +++----- 11 files changed, 59 insertions(+), 54 deletions(-) diff --git a/com.onesignal.unity.android/Runtime/AndroidDebugManager.cs b/com.onesignal.unity.android/Runtime/AndroidDebugManager.cs index 4ae7cb3d7..1f5f88d46 100644 --- a/com.onesignal.unity.android/Runtime/AndroidDebugManager.cs +++ b/com.onesignal.unity.android/Runtime/AndroidDebugManager.cs @@ -48,6 +48,8 @@ public LogLevel LogLevel get => _logLevel; set { + if (InputGuard.IsInvalidLogLevel(value, "setLogLevel")) + return; _logLevel = value; _debug.Call("setLogLevel", ToLogLevel(value)); } @@ -58,6 +60,8 @@ public LogLevel AlertLevel get => _alertLevel; set { + if (InputGuard.IsInvalidLogLevel(value, "setAlertLevel")) + return; _alertLevel = value; _debug.Call("setAlertLevel", ToLogLevel(value)); } diff --git a/com.onesignal.unity.android/Runtime/AndroidInAppMessagesManager.cs b/com.onesignal.unity.android/Runtime/AndroidInAppMessagesManager.cs index 33cc4f424..5de71ecb5 100644 --- a/com.onesignal.unity.android/Runtime/AndroidInAppMessagesManager.cs +++ b/com.onesignal.unity.android/Runtime/AndroidInAppMessagesManager.cs @@ -59,13 +59,11 @@ public bool Paused public void AddTrigger(string key, string value) { - if (InputGuard.IsMissing(key, "addTrigger: key")) - return; - if (value == null) - { - UnityEngine.Debug.LogError("OneSignal: addTrigger: value is required"); + if ( + InputGuard.IsMissing(key, "addTrigger: key") + || InputGuard.IsNull(value, "addTrigger: value") + ) return; - } _inAppMessages.Call("addTrigger", key, value); } diff --git a/com.onesignal.unity.android/Runtime/AndroidUserManager.cs b/com.onesignal.unity.android/Runtime/AndroidUserManager.cs index 8c247611b..869965be3 100644 --- a/com.onesignal.unity.android/Runtime/AndroidUserManager.cs +++ b/com.onesignal.unity.android/Runtime/AndroidUserManager.cs @@ -77,11 +77,8 @@ public string Language set { // Empty string is the reset to the device language. Null is not. - if (value == null) - { - Debug.LogError("OneSignal: setLanguage: language is required"); + if (InputGuard.IsNull(value, "setLanguage: language")) return; - } _user.Call("setLanguage", value); } } @@ -94,13 +91,11 @@ public Dictionary GetTags() public void AddTag(string key, string value) { - if (InputGuard.IsMissing(key, "addTag: key")) - return; - if (value == null) - { - UnityEngine.Debug.LogError("OneSignal: addTag: value is required"); + if ( + InputGuard.IsMissing(key, "addTag: key") + || InputGuard.IsNull(value, "addTag: value") + ) return; - } _user.Call("addTag", key, value); } diff --git a/com.onesignal.unity.android/Runtime/OneSignalAndroid.cs b/com.onesignal.unity.android/Runtime/OneSignalAndroid.cs index 25665873c..c8b7bc8f4 100644 --- a/com.onesignal.unity.android/Runtime/OneSignalAndroid.cs +++ b/com.onesignal.unity.android/Runtime/OneSignalAndroid.cs @@ -130,6 +130,8 @@ public override bool ConsentRequired public override void Initialize(string appId) { + if (InputGuard.IsMissing(appId, "initialize: appId")) + return; var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); var activity = unityPlayer.GetStatic("currentActivity"); @@ -199,6 +201,8 @@ private static void _enableHardwareAcceleration(AndroidJavaObject activity) public override void Login(string externalId, string jwtBearerToken = null) { + if (InputGuard.IsMissing(externalId, "login: externalId")) + return; _sdkClass.CallStatic("login", externalId, jwtBearerToken); } diff --git a/com.onesignal.unity.core/Runtime/InputGuard.cs b/com.onesignal.unity.core/Runtime/InputGuard.cs index 29fb09514..0215cf91b 100644 --- a/com.onesignal.unity.core/Runtime/InputGuard.cs +++ b/com.onesignal.unity.core/Runtime/InputGuard.cs @@ -1,5 +1,7 @@ +using System; using System.Collections.Generic; -using UnityEngine; +using OneSignalSDK.Debug.Models; +using OneSignalSDK.Debug.Utilities; namespace OneSignalSDK { @@ -9,7 +11,7 @@ public static bool IsMissing(string value, string api) { if (!string.IsNullOrEmpty(value)) return false; - Debug.LogError("OneSignal: " + api + " is required"); + SDKDebug.Error(api + " is required"); return true; } @@ -25,11 +27,11 @@ public static bool IsMissingAny(string[] values, string api) return false; } - public static bool IsMissing(object value, string api) + public static bool IsNull(object value, string api) { if (value != null) return false; - Debug.LogError("OneSignal: " + api + " is required"); + SDKDebug.Error(api + " is required"); return true; } @@ -37,7 +39,15 @@ public static bool IsNotFinite(float value, string api) { if (!float.IsNaN(value) && !float.IsInfinity(value)) return false; - Debug.LogError("OneSignal: " + api + " must be a finite number"); + SDKDebug.Error(api + " must be a finite number"); + return true; + } + + public static bool IsInvalidLogLevel(LogLevel value, string api) + { + if (Enum.IsDefined(typeof(LogLevel), value)) + return false; + SDKDebug.Error(api + " is not a valid log level"); return true; } @@ -80,19 +90,16 @@ bool allowEmptyValue ) { if (values == null) - return IsMissing(null, api); + return IsNull(values, api); foreach (var pair in values) { if (IsMissing(pair.Key, api + ": key")) return true; - if (allowEmptyValue) - { - if (pair.Value != null) - continue; - Debug.LogError("OneSignal: " + api + ": value is required"); - return true; - } - if (IsMissing(pair.Value, api + ": value")) + if ( + allowEmptyValue + ? IsNull(pair.Value, api + ": value") + : IsMissing(pair.Value, api + ": value") + ) return true; } return false; diff --git a/com.onesignal.unity.core/Runtime/OneSignal.cs b/com.onesignal.unity.core/Runtime/OneSignal.cs index fd8fe583a..a4b905fa9 100755 --- a/com.onesignal.unity.core/Runtime/OneSignal.cs +++ b/com.onesignal.unity.core/Runtime/OneSignal.cs @@ -145,8 +145,6 @@ public static bool ConsentRequired /// Your application id from the OneSignal dashboard public static void Initialize(string appId) { - if (InputGuard.IsMissing(appId, "initialize: appId")) - return; OneSignal.Default.Initialize(appId); } @@ -174,8 +172,6 @@ public static void Initialize(string appId) /// public static void Login(string externalId, string jwtBearerToken = null) { - if (InputGuard.IsMissing(externalId, "login: externalId")) - return; OneSignal.Default.Login(externalId, jwtBearerToken); } diff --git a/com.onesignal.unity.ios/Runtime/OneSignaliOS.cs b/com.onesignal.unity.ios/Runtime/OneSignaliOS.cs index 6b42dfed2..e7d6eca85 100644 --- a/com.onesignal.unity.ios/Runtime/OneSignaliOS.cs +++ b/com.onesignal.unity.ios/Runtime/OneSignaliOS.cs @@ -143,6 +143,8 @@ public override bool ConsentRequired public override void Initialize(string appId) { + if (InputGuard.IsMissing(appId, "initialize: appId")) + return; _oneSignalInitialize(appId); if (_inAppMessages == null) @@ -183,7 +185,9 @@ public override void Initialize(string appId) public override void Login(string externalId, string jwtBearerToken = null) { - if (jwtBearerToken == null) + if (InputGuard.IsMissing(externalId, "login: externalId")) + return; + if (string.IsNullOrWhiteSpace(jwtBearerToken)) { _oneSignalLogin(externalId); } diff --git a/com.onesignal.unity.ios/Runtime/iOSDebugManager.cs b/com.onesignal.unity.ios/Runtime/iOSDebugManager.cs index ac88982ed..2948ca0c9 100644 --- a/com.onesignal.unity.ios/Runtime/iOSDebugManager.cs +++ b/com.onesignal.unity.ios/Runtime/iOSDebugManager.cs @@ -48,6 +48,8 @@ public LogLevel LogLevel get => _logLevel; set { + if (InputGuard.IsInvalidLogLevel(value, "setLogLevel")) + return; _logLevel = value; _oneSignalDebugSetLogLevel((int)value); } @@ -58,6 +60,8 @@ public LogLevel AlertLevel get => _alertLevel; set { + if (InputGuard.IsInvalidLogLevel(value, "setAlertLevel")) + return; _alertLevel = value; _oneSignalDebugSetAlertLevel((int)value); } diff --git a/com.onesignal.unity.ios/Runtime/iOSInAppMessagesManager.cs b/com.onesignal.unity.ios/Runtime/iOSInAppMessagesManager.cs index 413561aae..d898c64c4 100644 --- a/com.onesignal.unity.ios/Runtime/iOSInAppMessagesManager.cs +++ b/com.onesignal.unity.ios/Runtime/iOSInAppMessagesManager.cs @@ -108,14 +108,12 @@ public bool Paused public void AddTrigger(string key, string value) { - if (InputGuard.IsMissing(key, "addTrigger: key")) + if ( + InputGuard.IsMissing(key, "addTrigger: key") + || InputGuard.IsNull(value, "addTrigger: value") + ) return; - if (value == null) - { - Debug.LogError("OneSignal: addTrigger: value is required"); - return; - } - _oneSignalInAppMessagesAddTrigger(key, value.ToString()); + _oneSignalInAppMessagesAddTrigger(key, value); } public void AddTriggers(Dictionary triggers) diff --git a/com.onesignal.unity.ios/Runtime/iOSLiveActivitiesManager.cs b/com.onesignal.unity.ios/Runtime/iOSLiveActivitiesManager.cs index 45bf4d632..5ef30f035 100644 --- a/com.onesignal.unity.ios/Runtime/iOSLiveActivitiesManager.cs +++ b/com.onesignal.unity.ios/Runtime/iOSLiveActivitiesManager.cs @@ -132,8 +132,8 @@ IDictionary content { if ( InputGuard.IsMissing(activityId, "startDefault: activityId") - || InputGuard.IsMissing(attributes, "startDefault: attributes") - || InputGuard.IsMissing(content, "startDefault: content") + || InputGuard.IsNull(attributes, "startDefault: attributes") + || InputGuard.IsNull(content, "startDefault: content") ) return; _oneSignalStartDefaultLiveActivity( diff --git a/com.onesignal.unity.ios/Runtime/iOSUserManager.cs b/com.onesignal.unity.ios/Runtime/iOSUserManager.cs index dc60cf13d..f78fd50a3 100644 --- a/com.onesignal.unity.ios/Runtime/iOSUserManager.cs +++ b/com.onesignal.unity.ios/Runtime/iOSUserManager.cs @@ -129,11 +129,8 @@ public string Language set { // Empty string is the reset to the device language. Null is not. - if (value == null) - { - Debug.LogError("OneSignal: setLanguage: language is required"); + if (InputGuard.IsNull(value, "setLanguage: language")) return; - } _oneSignalUserSetLanguage(value); } } @@ -150,13 +147,11 @@ public Dictionary GetTags() public void AddTag(string key, string value) { - if (InputGuard.IsMissing(key, "addTag: key")) - return; - if (value == null) - { - Debug.LogError("OneSignal: addTag: value is required"); + if ( + InputGuard.IsMissing(key, "addTag: key") + || InputGuard.IsNull(value, "addTag: value") + ) return; - } _oneSignalUserAddTag(key, value); }