From 04dd76188051edc9cfb212c85c2830bc4ca7aca3 Mon Sep 17 00:00:00 2001 From: CaIon Date: Fri, 6 Feb 2026 19:52:35 +0800 Subject: [PATCH] fix: update LIKE pattern sanitization for token search - Change ESCAPE character from '\' to '!' for compatibility with MySQL/PostgreSQL/SQLite - Adjust sanitization logic to escape '!' and '_' correctly, improving input validation for search queries --- model/token.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/model/token.go b/model/token.go index ab3804b20..04be1c55c 100644 --- a/model/token.go +++ b/model/token.go @@ -66,15 +66,16 @@ func GetAllUserTokens(userId int, startIdx int, num int) ([]*Token, error) { // sanitizeLikePattern 校验并清洗用户输入的 LIKE 搜索模式。 // 规则: -// 1. 转义 _ 和 \(不允许 _ 作通配符) +// 1. 转义 ! 和 _(使用 ! 作为 ESCAPE 字符,兼容 MySQL/PostgreSQL/SQLite) // 2. 连续的 % 合并为单个 % // 3. 最多允许 2 个 % // 4. 含 % 时(模糊搜索),去掉 % 后关键词长度必须 >= 2 // 5. 不含 % 时按精确匹配 func sanitizeLikePattern(input string) (string, error) { - // 1. 转义 \ 和 _ - input = strings.ReplaceAll(input, `\`, `\\`) - input = strings.ReplaceAll(input, `_`, `\_`) + // 1. 先转义 ESCAPE 字符 ! 自身,再转义 _ + // 使用 ! 而非 \ 作为 ESCAPE 字符,避免 MySQL 中反斜杠的字符串转义问题 + input = strings.ReplaceAll(input, "!", "!!") + input = strings.ReplaceAll(input, `_`, `!_`) // 2. 连续的 % 直接拒绝 if strings.Contains(input, "%%") { @@ -137,14 +138,14 @@ func SearchUserTokens(userId int, keyword string, token string, offset int, limi if err != nil { return nil, 0, err } - baseQuery = baseQuery.Where("name LIKE ? ESCAPE '\\'", keywordPattern) + baseQuery = baseQuery.Where("name LIKE ? ESCAPE '!'", keywordPattern) } if token != "" { tokenPattern, err := sanitizeLikePattern(token) if err != nil { return nil, 0, err } - baseQuery = baseQuery.Where(commonKeyCol+" LIKE ? ESCAPE '\\'", tokenPattern) + baseQuery = baseQuery.Where(commonKeyCol+" LIKE ? ESCAPE '!'", tokenPattern) } // 先查匹配总数(用于分页,受 maxTokens 上限保护,避免全表 COUNT)