Files
dpi/protocol/match.go

78 lines
2.4 KiB
Go

package protocol
// MatchPattern checks if the byte slice matches the magic string pattern.
//
// '?' matches any single character
// '*' matches zero or more characters
// '\' escapes special characters ('?', '*', '\')
// All other characters must match exactly
//
// Returns true if all magic bytes are matched, even if input has extra bytes.
func Match(magic string, input []byte) bool {
return match(magic, input, 0, 0)
}
// match is a recursive helper function that implements the matching logic
func match(magic string, input []byte, magicIndex, inputIndex int) bool {
// If we've reached the end of magic string, we've successfully matched all magic bytes
// It doesn't matter if there are extra bytes in the input
if magicIndex == len(magic) {
return true
}
// Handle escape character
if magic[magicIndex] == '\\' {
// Check if there's a next character in magic
if magicIndex+1 >= len(magic) {
// Backslash at end of magic string - treat as literal backslash
if inputIndex >= len(input) || input[inputIndex] != '\\' {
return false
}
return match(magic, input, magicIndex+1, inputIndex+1)
}
// Escape the next character - we need to match it literally
escapedChar := magic[magicIndex+1]
if inputIndex >= len(input) || input[inputIndex] != escapedChar {
return false
}
// Skip both the backslash and the escaped character in magic, move one in input
return match(magic, input, magicIndex+2, inputIndex+1)
}
// If we've reached the end of input but not magic string
if inputIndex == len(input) {
// If we have '*' at the current position, it can match zero characters
if magic[magicIndex] == '*' {
return match(magic, input, magicIndex+1, inputIndex)
}
return false
}
// Handle '*' character - matches zero or more characters
if magic[magicIndex] == '*' {
// Try matching zero characters
if match(magic, input, magicIndex+1, inputIndex) {
return true
}
// Try matching one or more characters
if inputIndex < len(input) && match(magic, input, magicIndex, inputIndex+1) {
return true
}
return false
}
// Handle '?' character - matches any single character
if magic[magicIndex] == '?' {
return match(magic, input, magicIndex+1, inputIndex+1)
}
// Handle exact character match
if magic[magicIndex] == input[inputIndex] {
return match(magic, input, magicIndex+1, inputIndex+1)
}
// No match found
return false
}