Skip to content

Commit 058ce87

Browse files
committed
Move escape funcs to utils.go, export them, add references to mysql surce code
1 parent f3b82fd commit 058ce87

File tree

2 files changed

+75
-51
lines changed

2 files changed

+75
-51
lines changed

connection.go

+5-50
Original file line numberDiff line numberDiff line change
@@ -165,60 +165,15 @@ func (mc *mysqlConn) Prepare(query string) (driver.Stmt, error) {
165165
return stmt, err
166166
}
167167

168+
// https://github.com/mysql/mysql-server/blob/mysql-5.7.5/libmysql/libmysql.c#L1150-L1156
168169
func (mc *mysqlConn) escapeBytes(v []byte) string {
169-
buf := make([]byte, len(v)*2+2)
170-
buf[0] = '\''
171-
pos := 1
170+
var escape func([]byte) []byte
172171
if mc.status&statusNoBackslashEscapes == 0 {
173-
for _, c := range v {
174-
switch c {
175-
case '\x00':
176-
buf[pos] = '\\'
177-
buf[pos+1] = '0'
178-
pos += 2
179-
case '\n':
180-
buf[pos] = '\\'
181-
buf[pos+1] = 'n'
182-
pos += 2
183-
case '\r':
184-
buf[pos] = '\\'
185-
buf[pos+1] = 'r'
186-
pos += 2
187-
case '\x1a':
188-
buf[pos] = '\\'
189-
buf[pos+1] = 'Z'
190-
pos += 2
191-
case '\'':
192-
buf[pos] = '\\'
193-
buf[pos+1] = '\''
194-
pos += 2
195-
case '"':
196-
buf[pos] = '\\'
197-
buf[pos+1] = '"'
198-
pos += 2
199-
case '\\':
200-
buf[pos] = '\\'
201-
buf[pos+1] = '\\'
202-
pos += 2
203-
default:
204-
buf[pos] = c
205-
pos += 1
206-
}
207-
}
172+
escape = EscapeString
208173
} else {
209-
for _, c := range v {
210-
if c == '\'' {
211-
buf[pos] = '\''
212-
buf[pos+1] = '\''
213-
pos += 2
214-
} else {
215-
buf[pos] = c
216-
pos++
217-
}
218-
}
174+
escape = EscapeQuotes
219175
}
220-
buf[pos] = '\''
221-
return string(buf[:pos+1])
176+
return "'" + string(escape(v)) + "'"
222177
}
223178

224179
func (mc *mysqlConn) buildQuery(query string, args []driver.Value) (string, error) {

utils.go

+70-1
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ func parseDSNParams(cfg *config, params string) (err error) {
224224
}
225225
cfg.collation = collation
226226
break
227-
227+
228228
case "columnsWithAlias":
229229
var isBool bool
230230
cfg.columnsWithAlias, isBool = readBool(value)
@@ -806,3 +806,72 @@ func appendLengthEncodedInteger(b []byte, n uint64) []byte {
806806
return append(b, 0xfe, byte(n), byte(n>>8), byte(n>>16), byte(n>>24),
807807
byte(n>>32), byte(n>>40), byte(n>>48), byte(n>>56))
808808
}
809+
810+
// Escape string with backslashes (\)
811+
// This escapes the contents of a string (provided as []byte) by adding backslashes before special
812+
// characters, and turning others into specific escape sequences, such as
813+
// turning newlines into \n and null bytes into \0.
814+
// https://github.com/mysql/mysql-server/blob/mysql-5.7.5/mysys/charset.c#L823-L932
815+
func EscapeString(v []byte) []byte {
816+
buf := make([]byte, len(v)*2)
817+
pos := 0
818+
for _, c := range v {
819+
switch c {
820+
case '\x00':
821+
buf[pos] = '\\'
822+
buf[pos+1] = '0'
823+
pos += 2
824+
case '\n':
825+
buf[pos] = '\\'
826+
buf[pos+1] = 'n'
827+
pos += 2
828+
case '\r':
829+
buf[pos] = '\\'
830+
buf[pos+1] = 'r'
831+
pos += 2
832+
case '\x1a':
833+
buf[pos] = '\\'
834+
buf[pos+1] = 'Z'
835+
pos += 2
836+
case '\'':
837+
buf[pos] = '\\'
838+
buf[pos+1] = '\''
839+
pos += 2
840+
case '"':
841+
buf[pos] = '\\'
842+
buf[pos+1] = '"'
843+
pos += 2
844+
case '\\':
845+
buf[pos] = '\\'
846+
buf[pos+1] = '\\'
847+
pos += 2
848+
default:
849+
buf[pos] = c
850+
pos += 1
851+
}
852+
}
853+
854+
return buf[:pos]
855+
}
856+
857+
// Escape apostrophes by doubling them up
858+
// This escapes the contents of a string by doubling up any apostrophes that
859+
// it contains. This is used when the NO_BACKSLASH_ESCAPES SQL_MODE is in
860+
// effect on the server.
861+
// https://github.com/mysql/mysql-server/blob/mysql-5.7.5/mysys/charset.c#L963-L1038
862+
func EscapeQuotes(v []byte) []byte {
863+
buf := make([]byte, len(v)*2)
864+
pos := 0
865+
for _, c := range v {
866+
if c == '\'' {
867+
buf[pos] = '\''
868+
buf[pos+1] = '\''
869+
pos += 2
870+
} else {
871+
buf[pos] = c
872+
pos++
873+
}
874+
}
875+
876+
return buf[:pos]
877+
}

0 commit comments

Comments
 (0)