用户输入 %%%% , MYSQL中数据全被查询出来的Bug(GORM)

发布于:2024-12-18 ⋅ 阅读:(70) ⋅ 点赞:(0)

1.Bug 奇遇记

        在工作中遇到的一个神奇小bug. 那是一天大雪天上午 , 打开飞书 , 哦吼 , 新bug. 看到这个bug当时就感觉出来问题出在哪里了, 仔细查看后 , 坏了啊, 这一个项目基本上涉及到模糊查询的都有这个bug. 并且 , 在我之前实习的公司 , 在学校做的项目 , 全部都存在这个bug. 怎么办? 一个一个加参数校验的条件吗? 那是不可能的 , 后面和导师说明了一下情况 , 可以封装一个公共的方法 , 如果需要模糊查询 , 对这个字段做一个转义.

2. 详细解释

像如下sql语句 , 是会把全部的数据都查询出来的

select * from test_name where name like '%%%%%'

MySQL中 % 属于通配符 , 并不会被转义 , 导致查询时 , 其实和用户输入空字符串情况一样 , 查询的是全部的数据.

解决代码

// EscapeLikeToNewStr 转义 SQL LIKE 查询中的通配符,返回被 left , right 包裹的新字符串
func EscapeLikeToNewStr(left, right, word string) string {
	return escapeCommon(left, right, word, true)
}

// EscapeLike 转义 SQL LIKE 查询中的通配符,返回原有字符串
func EscapeLike(word string) string {
	return escapeCommon("", "", word, false)
}

func escapeCommon(left, right, word string, wrap bool) string {
	var n int
	for i := range word {
		if c := word[i]; c == '%' || c == '_' || c == '\\' {
			n++
		}
	}

	// 如果没有需要转义的字符,则直接返回原始字符串
	if n == 0 {
		if wrap {
			return left + word + right
		}
		return word
	}
	var b strings.Builder
	b.Grow(len(word) + n)
	for _, c := range word {
		if c == '%' || c == '_' || c == '\\' {
			b.WriteByte('\\')
		}
		b.WriteRune(c)
	}
	if wrap {
		return left + b.String() + right
	}
	return b.String()
}

对于需要参与模糊查询的数据 , 做一次转义 . 这样 , 当用户输入 %%% 后 , 查询SQL就变成了

select * from test_name where name like '%/%/%/%%'

由于数据中并不存在名称为 %%% 的数据 , 自然就查询不出来了. OK , 这样 , 那个地方需要 , 就去调用,就可以了. 


网站公告

今日签到

点亮在社区的每一天
去签到