Skip to content

Commit 5016d79

Browse files
authored
FIX: Avoid potential for NullReferenceException in FireStateChangeNotifications (ISXB-724). (#1927)
* FIX: Avoid potential for NullReferenceException in FireStateChangeNotifications (ISXB-724). * Fix changelog since issue isn't public (and add a minor string fix while I'm here). * Formatting fix. * Hopefully appease integration tests. * Improve wording of changelog.
1 parent a7f5b71 commit 5016d79

File tree

4 files changed

+33
-6
lines changed

4 files changed

+33
-6
lines changed

Packages/com.unity.inputsystem/CHANGELOG.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,12 @@ Due to package verification, the latest version below is the unpublished version
99
however, it has to be formatted properly to pass verification tests.
1010

1111
## [Unreleased] - yyyy-mm-dd
12-
- Fixed Composite binding isn't triggered after ResetDevice() called during Action handler [ISXB-746](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-746)
13-
- Fixed resource designation for "d_InputControl" icon to address CI failure
14-
- Fixed Composite binding isn't triggered after disabling action while there are in progress [ISXB-505](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-505)
12+
13+
### Fixed
14+
- Avoid potential crashes from `NullReferenceException` in `FireStateChangeNotifications`.
15+
- Fixed an issue where a composite binding would not be consecutively triggered after ResetDevice() has been called from the associated action handler [ISXB-746](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-746).
16+
- Fixed resource designation for "d_InputControl" icon to address CI failure.
17+
- Fixed an issue where a composite binding would not be consecutively triggered after disabling actions while there are action modifiers in progress [ISXB-505](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-505).
1518

1619
## [1.8.2] - 2024-04-29
1720

Packages/com.unity.inputsystem/InputSystem/Devices/Gamepad.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public struct GamepadState : IInputStateTypeInfo
8686
internal const string ButtonSouthShortDisplayName = "Cross";
8787
internal const string ButtonNorthShortDisplayName = "Triangle";
8888
internal const string ButtonWestShortDisplayName = "Square";
89-
internal const string ButtonEastShortDisplayName = "East";
89+
internal const string ButtonEastShortDisplayName = "Circle";
9090
#elif UNITY_SWITCH
9191
internal const string ButtonSouthShortDisplayName = "B";
9292
internal const string ButtonNorthShortDisplayName = "X";

Packages/com.unity.inputsystem/InputSystem/InputManagerStateMonitors.cs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,14 +349,28 @@ private unsafe bool ProcessStateChangeMonitors(int deviceIndex, void* newStateFr
349349

350350
internal unsafe void FireStateChangeNotifications(int deviceIndex, double internalTime, InputEvent* eventPtr)
351351
{
352-
Debug.Assert(m_StateChangeMonitors != null);
353-
Debug.Assert(m_StateChangeMonitors.Length > deviceIndex);
352+
if (m_StateChangeMonitors == null)
353+
{
354+
Debug.Assert(false, "m_StateChangeMonitors is null - has AddStateChangeMonitor been called?");
355+
return;
356+
}
357+
if (m_StateChangeMonitors.Length <= deviceIndex)
358+
{
359+
Debug.Assert(false, $"deviceIndex {deviceIndex} passed to FireStateChangeNotifications is out of bounds (current length {m_StateChangeMonitors.Length}).");
360+
return;
361+
}
354362

355363
// NOTE: This method must be safe for mutating the state change monitor arrays from *within*
356364
// NotifyControlStateChanged()! This includes all monitors for the device being wiped
357365
// completely or arbitrary additions and removals having occurred.
358366

359367
ref var signals = ref m_StateChangeMonitors[deviceIndex].signalled;
368+
if (signals.AnyBitIsSet() && m_StateChangeMonitors[deviceIndex].listeners == null)
369+
{
370+
Debug.Assert(false, $"A state change for device {deviceIndex} has been set, but list of listeners is null.");
371+
return;
372+
}
373+
360374
ref var listeners = ref m_StateChangeMonitors[deviceIndex].listeners;
361375
var time = internalTime - InputRuntime.s_CurrentTimeOffsetToRealtimeSinceStartup;
362376

Packages/com.unity.inputsystem/InputSystem/Utilities/DynamicBitfield.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,16 @@ public void ClearBit(int bitIndex)
5151
array[bitIndex / 64] &= ~(1UL << (bitIndex % 64));
5252
}
5353

54+
public bool AnyBitIsSet()
55+
{
56+
for (var i = 0; i < array.length; ++i)
57+
{
58+
if (array[i] != 0)
59+
return true;
60+
}
61+
return false;
62+
}
63+
5464
private static int BitCountToULongCount(int bitCount)
5565
{
5666
return (bitCount + 63) / 64;

0 commit comments

Comments
 (0)