feat(sql): Add common whitespace characters, ASCII, HTML, backslashes to literal escaping
This commit is contained in:
@@ -120,14 +120,36 @@ func QuoteIdent(name string) string {
|
||||
return `"` + strings.ReplaceAll(name, `"`, `""`) + `"`
|
||||
}
|
||||
|
||||
// QuoteLiteral escapes a string literal for use in SQL queries
|
||||
// It doubles single quotes to prevent SQL injection
|
||||
func QuoteLiteral(s string) string {
|
||||
return "'" + strings.ReplaceAll(s, "'", "''") + "'"
|
||||
s = strings.ReplaceAll(s, "\x00", "")
|
||||
|
||||
var b strings.Builder
|
||||
b.Grow(len(s) + 2)
|
||||
b.WriteByte('\'')
|
||||
|
||||
for _, r := range s {
|
||||
switch r {
|
||||
case '\'':
|
||||
b.WriteString("''")
|
||||
case '\\':
|
||||
b.WriteString("\\\\")
|
||||
case '\x00':
|
||||
continue
|
||||
case '\t', '\n', '\r':
|
||||
b.WriteRune(r)
|
||||
default:
|
||||
if r < 0x20 {
|
||||
b.WriteString(fmt.Sprintf("\\%03o", r))
|
||||
} else {
|
||||
b.WriteRune(r)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
b.WriteByte('\'')
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// QuoteValue formats a value according to its type for use in SQL queries
|
||||
// It handles strings, numbers, booleans, null, and UUIDs safely
|
||||
func QuoteValue(v any) string {
|
||||
if v == nil {
|
||||
return "NULL"
|
||||
@@ -135,7 +157,6 @@ func QuoteValue(v any) string {
|
||||
|
||||
switch val := v.(type) {
|
||||
case string:
|
||||
// Check if it's a valid UUID format
|
||||
if matched, _ := regexp.MatchString(`^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$`, strings.ToLower(val)); matched {
|
||||
return QuoteLiteral(val)
|
||||
}
|
||||
@@ -150,14 +171,10 @@ func QuoteValue(v any) string {
|
||||
}
|
||||
return "FALSE"
|
||||
default:
|
||||
// For unknown types, convert to string and escape
|
||||
return QuoteLiteral(fmt.Sprintf("%v", val))
|
||||
}
|
||||
}
|
||||
|
||||
// BuildWhereClause safely builds a WHERE clause from conditions
|
||||
// conditions is a map of column names to values (uses = operator)
|
||||
// Returns empty string if no conditions provided
|
||||
func BuildWhereClause(conditions map[string]any) (string, error) {
|
||||
if len(conditions) == 0 {
|
||||
return "", nil
|
||||
|
||||
Reference in New Issue
Block a user