Closed
Description
My first attempt to use Node's mysql package went like this [paraphrasing code]:
const mysql = require('mysql');
const result = mysql.query('SELECT * FROM table LIMIT 3');
console.log(result);
This worked fine. My second attempt to use Node's mysql package went somewhat downhill:
const mysql = require('mysql');
const result = mysql.query('SELECT * FROM table WHERE description LIKE "%?%" LIMIT 3', [req.query.q]);
console.log(result);
I traced the problem back to this package. It can be characterised as one of two things:
- The question mark substitution is context-unaware. It should not wrap quote marks around strings if there already are quote marks around the question mark (i.e. it is preceded by an uneven number of any quote character). Or,
- There needs to be a second API exposed via node's mysql package which lets programmers perform an unquoted escape (and yes, I've seen Why does SqlString.escapeString return values in single quotes? #19). This will allow programmers to put escaped, user-sourced values within larger strings without having to strip off the quote marks.
As an aside, I looked at the code of this package and all three points of return from escapeString() duplicitously wrap the escaped string in quote characters, à la return "'" + val + "'";
— you ought to refactor to have this happen in a single place, e.g.:
function escapeString(val) {
return "'" + escapeUnquotedString(val) + "'";
}
function escapeUnquotedString(val) {
var chunkIndex = CHARS_GLOBAL_REGEXP.lastIndex = 0;
var escapedVal = '';
var match;
while ((match = CHARS_GLOBAL_REGEXP.exec(val))) {
escapedVal += val.slice(chunkIndex, match.index) + CHARS_ESCAPE_MAP[match[0]];
chunkIndex = CHARS_GLOBAL_REGEXP.lastIndex;
}
if (chunkIndex === 0) {
// Nothing was escaped
return val;
}
if (chunkIndex < val.length) {
return escapedVal + val.slice(chunkIndex);
}
return escapedVal;
}
This removes duplication and reduces the chances of bugs being introduced (e.g. a new return point being added but forgetting to wrap in quotes).
Metadata
Metadata
Assignees
Labels
No labels