Skip to content

Commit a83a39f

Browse files
FIX: Handle consecutive wildcards in StringMatches (1/x) (#2311)
1 parent 6ba64b2 commit a83a39f

3 files changed

Lines changed: 40 additions & 6 deletions

File tree

Assets/Tests/InputSystem/CoreTests_Controls.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1607,4 +1607,30 @@ static void CheckChildControls(Type type, HashSet<Type> checkedTypes)
16071607
Assert.That(setMethod.IsPublic, Is.True, inputControlMessage);
16081608
}
16091609
}
1610+
1611+
[Test]
1612+
[Category("Controls")]
1613+
public void Controls_MatchPathComponent_CollapsesConsecutiveWildcards()
1614+
{
1615+
var component = "leftTrigger";
1616+
var componentType = InputControlPath.PathComponentType.Name;
1617+
1618+
var patterns = new[]
1619+
{
1620+
"*Trigger",
1621+
"**Trigger",
1622+
"***Trigger"
1623+
};
1624+
1625+
foreach (var path in patterns)
1626+
{
1627+
var indexInPath = 0;
1628+
var result = InputControlPath.MatchPathComponent(component, path, ref indexInPath, componentType);
1629+
1630+
// All patterns should match
1631+
Assert.IsTrue(result, $"Pattern '{path}' should match '{component}'");
1632+
Assert.AreEqual(path.Length, indexInPath,
1633+
$"Index should advance past entire pattern for '{path}'");
1634+
}
1635+
}
16101636
}

Packages/com.unity.inputsystem/CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,17 @@ however, it has to be formatted properly to pass verification tests.
1010

1111
## [Unreleased] - yyyy-mm-dd
1212

13+
### Changed
14+
- Consecutive wildcard characters ('*') used in input control-paths are now collapsed into a single wildcard when multiple consecutive wildcard characters are present.
15+
16+
### Added
17+
18+
### Fixed
1319

1420

1521
## [1.18.0] - 2026-01-14
1622

1723
### Changed
18-
1924
- Updated documentation to reflect that the OnMouse MonoBehaviour events are now supported in Unity 6.4 and above.
2025
- Updated the supported devices documentation to clarify that touchscreens are supported on Linux.
2126
- Updated documentation to reflect PS5 controller support on Linux.

Packages/com.unity.inputsystem/InputSystem/Controls/InputControlPath.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -507,8 +507,8 @@ private static bool StringMatches(Substring str, InternedString matchTo)
507507
nextChar = str[++posInStr];
508508
if (nextChar == '*')
509509
{
510-
////TODO: make sure we don't end up with ** here
511-
510+
while (posInStr + 1 < strLength && str[posInStr + 1] == '*')
511+
++posInStr;
512512
if (posInStr == strLength - 1)
513513
return true; // Wildcard at end of string so rest is matched.
514514

@@ -1031,15 +1031,15 @@ private static TControl MatchChildrenRecursive<TControl>(InputControl control, s
10311031
return lastMatch;
10321032
}
10331033

1034-
private enum PathComponentType
1034+
internal enum PathComponentType
10351035
{
10361036
Name,
10371037
DisplayName,
10381038
Usage,
10391039
Layout
10401040
}
10411041

1042-
private static bool MatchPathComponent(string component, string path, ref int indexInPath, PathComponentType componentType, int startIndexInComponent = 0)
1042+
internal static bool MatchPathComponent(string component, string path, ref int indexInPath, PathComponentType componentType, int startIndexInComponent = 0)
10431043
{
10441044
Debug.Assert(component != null, "Component string is null");
10451045
Debug.Assert(path != null, "Path is null");
@@ -1072,10 +1072,13 @@ private static bool MatchPathComponent(string component, string path, ref int in
10721072
break;
10731073
}
10741074

1075-
////TODO: allow only single '*' and recognize '**'
10761075
// If we've reached a '*' in the path, skip character in name.
10771076
if (nextCharInPath == '*')
10781077
{
1078+
// Collapse consecutive '*' so matching logic here only needs to handle a single '*'.
1079+
while (indexInPath + 1 < pathLength && path[indexInPath + 1] == '*')
1080+
++indexInPath;
1081+
10791082
// But first let's see if we have something after the wildcard that matches the rest of the component.
10801083
// This could be when, for example, we hit "T" on matching "leftTrigger" against "*Trigger". We have to stop
10811084
// gobbling up characters for the wildcard when reaching "Trigger" in the component name.

0 commit comments

Comments
 (0)