Skip to content

Commit 8628b96

Browse files
committed
Use the sqlstring module for SQL escaping and formatting
1 parent 1aa486e commit 8628b96

File tree

3 files changed

+4
-214
lines changed

3 files changed

+4
-214
lines changed

Changes.md

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ you spot any mistakes.
2222
* Support Node.js 6.x
2323
* Update `bignumber.js` to 2.3.0
2424
* Update `readable-stream` to 1.1.14
25+
* Use the `sqlstring` module for SQL escaping and formatting
2526

2627
## v2.10.2 (2016-01-12)
2728

lib/protocol/SqlString.js

+1-213
Original file line numberDiff line numberDiff line change
@@ -1,213 +1 @@
1-
var SqlString = exports;
2-
var charsRegex = /[\0\b\t\n\r\x1a\"\'\\]/g; // eslint-disable-line no-control-regex
3-
var charsMap = {
4-
'\0': '\\0',
5-
'\b': '\\b',
6-
'\t': '\\t',
7-
'\n': '\\n',
8-
'\r': '\\r',
9-
'\x1a': '\\Z',
10-
'"': '\\"',
11-
'\'': '\\\'',
12-
'\\': '\\\\'
13-
};
14-
15-
SqlString.escapeId = function escapeId(val, forbidQualified) {
16-
if (Array.isArray(val)) {
17-
var sql = '';
18-
19-
for (var i = 0; i < val.length; i++) {
20-
sql += (i === 0 ? '' : ', ') + SqlString.escapeId(val[i], forbidQualified);
21-
}
22-
23-
return sql;
24-
}
25-
26-
if (forbidQualified) {
27-
return '`' + val.replace(/`/g, '``') + '`';
28-
}
29-
30-
return '`' + val.replace(/`/g, '``').replace(/\./g, '`.`') + '`';
31-
};
32-
33-
SqlString.escape = function escape(val, stringifyObjects, timeZone) {
34-
if (val === undefined || val === null) {
35-
return 'NULL';
36-
}
37-
38-
switch (typeof val) {
39-
case 'boolean': return (val) ? 'true' : 'false';
40-
case 'number': return val+'';
41-
case 'object':
42-
if (val instanceof Date) {
43-
val = SqlString.dateToString(val, timeZone || 'local');
44-
} else if (Array.isArray(val)) {
45-
return SqlString.arrayToList(val, timeZone);
46-
} else if (Buffer.isBuffer(val)) {
47-
return SqlString.bufferToString(val);
48-
} else if (stringifyObjects) {
49-
val = val.toString();
50-
} else {
51-
return SqlString.objectToValues(val, timeZone);
52-
}
53-
}
54-
55-
return escapeString(val);
56-
};
57-
58-
SqlString.arrayToList = function arrayToList(array, timeZone) {
59-
var sql = '';
60-
61-
for (var i = 0; i < array.length; i++) {
62-
var val = array[i];
63-
64-
if (Array.isArray(val)) {
65-
sql += (i === 0 ? '' : ', ') + '(' + SqlString.arrayToList(val, timeZone) + ')';
66-
} else {
67-
sql += (i === 0 ? '' : ', ') + SqlString.escape(val, true, timeZone);
68-
}
69-
}
70-
71-
return sql;
72-
};
73-
74-
SqlString.format = function format(sql, values, stringifyObjects, timeZone) {
75-
if (values == null) {
76-
return sql;
77-
}
78-
79-
if (!(values instanceof Array || Array.isArray(values))) {
80-
values = [values];
81-
}
82-
83-
var chunkIndex = 0;
84-
var placeholdersRegex = /\?\??/g;
85-
var result = '';
86-
var valuesIndex = 0;
87-
var match;
88-
89-
while (valuesIndex < values.length && (match = placeholdersRegex.exec(sql))) {
90-
var value = match[0] === '??'
91-
? SqlString.escapeId(values[valuesIndex])
92-
: SqlString.escape(values[valuesIndex], stringifyObjects, timeZone);
93-
94-
result += sql.slice(chunkIndex, match.index) + value;
95-
chunkIndex = placeholdersRegex.lastIndex;
96-
valuesIndex++;
97-
}
98-
99-
if (chunkIndex === 0) {
100-
// Nothing was replaced
101-
return sql;
102-
}
103-
104-
if (chunkIndex < sql.length) {
105-
return result + sql.slice(chunkIndex);
106-
}
107-
108-
return result;
109-
};
110-
111-
SqlString.dateToString = function dateToString(date, timeZone) {
112-
var dt = new Date(date);
113-
114-
var year;
115-
var month;
116-
var day;
117-
var hour;
118-
var minute;
119-
var second;
120-
var millisecond;
121-
122-
if (timeZone === 'local') {
123-
year = dt.getFullYear();
124-
month = dt.getMonth() + 1;
125-
day = dt.getDate();
126-
hour = dt.getHours();
127-
minute = dt.getMinutes();
128-
second = dt.getSeconds();
129-
millisecond = dt.getMilliseconds();
130-
} else {
131-
var tz = convertTimezone(timeZone);
132-
133-
if (tz !== false && tz !== 0) {
134-
dt.setTime(dt.getTime() + (tz * 60000));
135-
}
136-
137-
year = dt.getUTCFullYear();
138-
month = dt.getUTCMonth() + 1;
139-
day = dt.getUTCDate();
140-
hour = dt.getUTCHours();
141-
minute = dt.getUTCMinutes();
142-
second = dt.getUTCSeconds();
143-
millisecond = dt.getUTCMilliseconds();
144-
}
145-
146-
// YYYY-MM-DD HH:mm:ss.mmm
147-
return zeroPad(year, 4) + '-' + zeroPad(month, 2) + '-' + zeroPad(day, 2) + ' ' +
148-
zeroPad(hour, 2) + ':' + zeroPad(minute, 2) + ':' + zeroPad(second, 2) + '.' +
149-
zeroPad(millisecond, 3);
150-
};
151-
152-
SqlString.bufferToString = function bufferToString(buffer) {
153-
return "X'" + buffer.toString('hex') + "'";
154-
};
155-
156-
SqlString.objectToValues = function objectToValues(object, timeZone) {
157-
var sql = '';
158-
159-
for (var key in object) {
160-
var val = object[key];
161-
162-
if (typeof val === 'function') {
163-
continue;
164-
}
165-
166-
sql += (sql.length === 0 ? '' : ', ') + SqlString.escapeId(key) + ' = ' + SqlString.escape(val, true, timeZone);
167-
}
168-
169-
return sql;
170-
};
171-
172-
function escapeString(val) {
173-
var chunkIndex = charsRegex.lastIndex = 0;
174-
var escapedVal = '';
175-
var match;
176-
177-
while ((match = charsRegex.exec(val))) {
178-
escapedVal += val.slice(chunkIndex, match.index) + charsMap[match[0]];
179-
chunkIndex = charsRegex.lastIndex;
180-
}
181-
182-
if (chunkIndex === 0) {
183-
// Nothing was escaped
184-
return "'" + val + "'";
185-
}
186-
187-
if (chunkIndex < val.length) {
188-
return "'" + escapedVal + val.slice(chunkIndex) + "'";
189-
}
190-
191-
return "'" + escapedVal + "'";
192-
}
193-
194-
function zeroPad(number, length) {
195-
number = number.toString();
196-
while (number.length < length) {
197-
number = '0' + number;
198-
}
199-
200-
return number;
201-
}
202-
203-
function convertTimezone(tz) {
204-
if (tz === 'Z') {
205-
return 0;
206-
}
207-
208-
var m = tz.match(/([\+\-\s])(\d\d):?(\d\d)?/);
209-
if (m) {
210-
return (m[1] == '-' ? -1 : 1) * (parseInt(m[2], 10) + ((m[3] ? parseInt(m[3], 10) : 0) / 60)) * 60;
211-
}
212-
return false;
213-
}
1+
module.exports = require('sqlstring');

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
"repository": "felixge/node-mysql",
1515
"dependencies": {
1616
"bignumber.js": "2.3.0",
17-
"readable-stream": "1.1.14"
17+
"readable-stream": "1.1.14",
18+
"sqlstring": "2.0.1"
1819
},
1920
"devDependencies": {
2021
"after": "0.8.1",

0 commit comments

Comments
 (0)