2022-03-24 18:30:59 +01:00
|
|
|
package sanitize
|
|
|
|
|
2022-03-28 17:36:59 +02:00
|
|
|
// SqlSpecial checks if the byte must be escaped/omitted in SQL.
|
|
|
|
func SqlSpecial(b byte) (special bool, omit bool) {
|
|
|
|
if b < 32 {
|
|
|
|
return true, true
|
|
|
|
}
|
2022-03-24 18:30:59 +01:00
|
|
|
|
2022-03-28 17:36:59 +02:00
|
|
|
switch b {
|
|
|
|
case '"', '\'', '\\':
|
|
|
|
return true, false
|
|
|
|
default:
|
|
|
|
return false, false
|
|
|
|
}
|
|
|
|
}
|
2022-03-24 18:30:59 +01:00
|
|
|
|
|
|
|
// SqlString escapes a string for use in an SQL query.
|
|
|
|
func SqlString(s string) string {
|
|
|
|
var i int
|
|
|
|
for i = 0; i < len(s); i++ {
|
2022-03-28 17:36:59 +02:00
|
|
|
if found, _ := SqlSpecial(s[i]); found {
|
2022-03-24 18:30:59 +01:00
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-28 17:36:59 +02:00
|
|
|
// Return if no special characters were found.
|
2022-03-24 18:30:59 +01:00
|
|
|
if i >= len(s) {
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
|
|
|
b := make([]byte, 2*len(s)-i)
|
2022-03-28 17:36:59 +02:00
|
|
|
|
2022-03-24 18:30:59 +01:00
|
|
|
copy(b, s[:i])
|
2022-03-28 17:36:59 +02:00
|
|
|
|
2022-03-24 18:30:59 +01:00
|
|
|
j := i
|
2022-03-28 17:36:59 +02:00
|
|
|
|
2022-03-24 18:30:59 +01:00
|
|
|
for ; i < len(s); i++ {
|
2022-03-28 17:36:59 +02:00
|
|
|
if special, omit := SqlSpecial(s[i]); omit {
|
|
|
|
// Omit control characters.
|
2022-03-24 18:30:59 +01:00
|
|
|
continue
|
2022-03-28 17:36:59 +02:00
|
|
|
} else if special {
|
|
|
|
// Escape other special characters.
|
|
|
|
// see https://mariadb.com/kb/en/string-literals/
|
|
|
|
b[j] = s[i]
|
2022-03-24 18:30:59 +01:00
|
|
|
j++
|
|
|
|
}
|
2022-03-28 17:36:59 +02:00
|
|
|
|
2022-03-24 18:30:59 +01:00
|
|
|
b[j] = s[i]
|
|
|
|
j++
|
|
|
|
}
|
2022-03-28 17:36:59 +02:00
|
|
|
|
2022-03-24 18:30:59 +01:00
|
|
|
return string(b[:j])
|
|
|
|
}
|