1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
|
#include <dbd/common.h>
const char *strlower(char *in) {
char *s = in;
while(*s) {
*s= (*s <= 'Z' && *s >= 'A') ? (*s - 'A') + 'a' : *s;
s++;
}
return in;
}
/*
* replace '?' placeholders with {native_prefix}\d+ placeholders
* to be compatible with native API
*/
char *replace_placeholders(lua_State *L, char native_prefix, const char *sql) {
size_t len = strlen(sql);
int num_placeholders = 0;
int extra_space = 0;
int i;
char *newsql;
int newpos = 1;
int ph_num = 1;
int in_quote = 0;
char format_str[4];
format_str[0] = native_prefix;
format_str[1] = '%';
format_str[2] = 'u';
format_str[3] = '\0';
/*
* dumb count of all '?'
* this will match more placeholders than necessesary
* but it's safer to allocate more placeholders at the
* cost of a few bytes than risk a buffer overflow
*/
for (i = 1; i < len; i++) {
if (sql[i] == '?') {
num_placeholders++;
}
}
/*
* this is MAX_PLACEHOLDER_SIZE-1 because the '?' is
* replaced with '{native_prefix}'
*/
extra_space = num_placeholders * (MAX_PLACEHOLDER_SIZE-1);
/*
* allocate a new string for the converted SQL statement
*/
newsql = malloc(sizeof(char) * (len+extra_space+1));
memset(newsql, 0, sizeof(char) * (len+extra_space+1));
/*
* copy first char. In valid SQL this cannot be a placeholder
*/
newsql[0] = sql[0];
/*
* only replace '?' not in a single quoted string
*/
for (i = 1; i < len; i++) {
/*
* don't change the quote flag if the ''' is preceded
* by a '\' to account for escaping
*/
if (sql[i] == '\'' && sql[i-1] != '\\') {
in_quote = !in_quote;
}
if (sql[i] == '?' && !in_quote) {
size_t n;
if (ph_num > MAX_PLACEHOLDERS) {
luaL_error(L, "Sorry, you are using more than %d placeholders. Use %c{num} format instead", MAX_PLACEHOLDERS, native_prefix);
}
n = snprintf(&newsql[newpos], MAX_PLACEHOLDER_SIZE, format_str, ph_num++);
newpos += n;
} else {
newsql[newpos] = sql[i];
newpos++;
}
}
/*
* terminate string on the last position
*/
newsql[newpos] = '\0';
/* fprintf(stderr, "[%s]\n", newsql); */
return newsql;
}
|