A stray open bracket with no closing bracket is not an error - the convention is to treat it as an ordinary character. Today the scanner falls back to a literal open bracket when it never finds the close.
Treat an open bracket with no closing bracket as a literal character.
Real patterns contain stray brackets - a filename like a[b is perfectly legal -
so an open [ that never finds a matching ] must not break the matcher. The
convention, shared by the shell and by git, is to treat the lone [ as a literal
character. So [abc (no closing bracket) matches the four-character name [abc,
and matches nothing shorter.
The change is a single fallback: after the scanner walks looking for the closing
], check whether it ran off the end of the pattern. If it did, no class was ever
formed, so return the [ as an ordinary literal and advance by one - letting the
main scan continue with abc as plain characters. Only when a real ] is found do
you treat the span as a class. This keeps a malformed pattern predictable instead
of throwing, which matters even more once these patterns come from a file.
// after scanning for ']': if we ran off the end, no class was closedif j >= len(pat) {return pat[p] == c, p + 1 // the '[' is a plain literal character}return matched, j + 1