summaryrefslogtreecommitdiff
path: root/ext/pdo/pdo_sql_parser.re
diff options
context:
space:
mode:
Diffstat (limited to 'ext/pdo/pdo_sql_parser.re')
-rw-r--r--ext/pdo/pdo_sql_parser.re130
1 files changed, 48 insertions, 82 deletions
diff --git a/ext/pdo/pdo_sql_parser.re b/ext/pdo/pdo_sql_parser.re
index 04a4118fc4..6716401187 100644
--- a/ext/pdo/pdo_sql_parser.re
+++ b/ext/pdo/pdo_sql_parser.re
@@ -70,22 +70,18 @@ static int scan(Scanner *s)
struct placeholder {
const char *pos;
size_t len;
- size_t qlen; /* quoted length of value */
- char *quoted; /* quoted value */
- int freeq;
+ zend_string *quoted; /* quoted value */
int bindno;
struct placeholder *next;
};
static void free_param_name(zval *el) {
- efree(Z_PTR_P(el));
+ zend_string_release(Z_PTR_P(el));
}
-PDO_API int pdo_parse_params(pdo_stmt_t *stmt, const char *inquery, size_t inquery_len,
- char **outquery, size_t *outquery_len)
+PDO_API int pdo_parse_params(pdo_stmt_t *stmt, zend_string *inquery, zend_string **outquery)
{
Scanner s;
- const char *ptr;
char *newbuffer;
ptrdiff_t t;
uint32_t bindno = 0;
@@ -96,9 +92,8 @@ PDO_API int pdo_parse_params(pdo_stmt_t *stmt, const char *inquery, size_t inque
int query_type = PDO_PLACEHOLDER_NONE;
struct placeholder *placeholders = NULL, *placetail = NULL, *plc = NULL;
- ptr = *outquery;
- s.cur = inquery;
- s.end = inquery + inquery_len + 1;
+ s.cur = ZSTR_VAL(inquery);
+ s.end = s.cur + ZSTR_LEN(inquery) + 1;
/* phase 1: look for args */
while((t = scan(&s)) != PDO_PARSER_EOI) {
@@ -110,7 +105,7 @@ PDO_API int pdo_parse_params(pdo_stmt_t *stmt, const char *inquery, size_t inque
if (t == PDO_PARSER_BIND) {
ptrdiff_t len = s.cur - s.tok;
- if ((inquery < (s.cur - len)) && isalnum(*(s.cur - len - 1))) {
+ if ((ZSTR_VAL(inquery) < (s.cur - len)) && isalnum(*(s.cur - len - 1))) {
continue;
}
query_type |= PDO_PLACEHOLDER_NAMED;
@@ -126,9 +121,7 @@ PDO_API int pdo_parse_params(pdo_stmt_t *stmt, const char *inquery, size_t inque
if (t == PDO_PARSER_ESCAPED_QUESTION) {
plc->bindno = PDO_PARSER_BINDNO_ESCAPED_CHAR;
- plc->quoted = "?";
- plc->qlen = 1;
- plc->freeq = 0;
+ plc->quoted = ZSTR_CHAR('?');
escapes++;
} else {
plc->bindno = bindno++;
@@ -179,7 +172,7 @@ PDO_API int pdo_parse_params(pdo_stmt_t *stmt, const char *inquery, size_t inque
if (stmt->supports_placeholders == query_type && !stmt->named_rewrite_template) {
/* query matches native syntax */
if (escapes) {
- newbuffer_len = inquery_len;
+ newbuffer_len = ZSTR_LEN(inquery);
goto rewrite;
}
@@ -201,7 +194,7 @@ safe:
if (stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) {
/* query generation */
- newbuffer_len = inquery_len;
+ newbuffer_len = ZSTR_LEN(inquery);
/* let's quote all the values */
for (plc = placeholders; plc && params; plc = plc->next) {
@@ -243,16 +236,9 @@ safe:
if (!buf) {
buf = ZSTR_EMPTY_ALLOC();
}
- if (!stmt->dbh->methods->quoter(stmt->dbh, ZSTR_VAL(buf), ZSTR_LEN(buf), &plc->quoted, &plc->qlen,
- param->param_type)) {
- /* bork */
- ret = -1;
- strncpy(stmt->error_code, stmt->dbh->error_code, 6);
- if (buf) {
- zend_string_release_ex(buf, 0);
- }
- goto clean_up;
- }
+
+ plc->quoted = stmt->dbh->methods->quoter(stmt->dbh, buf, param->param_type);
+
if (buf) {
zend_string_release_ex(buf, 0);
}
@@ -261,7 +247,6 @@ safe:
ret = -1;
goto clean_up;
}
- plc->freeq = 1;
} else {
enum pdo_param_type param_type = param->param_type;
zend_string *buf = NULL;
@@ -273,40 +258,29 @@ safe:
switch (param_type) {
case PDO_PARAM_BOOL:
- plc->quoted = zend_is_true(parameter) ? "1" : "0";
- plc->qlen = sizeof("1")-1;
- plc->freeq = 0;
+ plc->quoted = zend_is_true(parameter) ? ZSTR_CHAR('1') : ZSTR_CHAR('0');
break;
case PDO_PARAM_INT:
- buf = zend_long_to_str(zval_get_long(parameter));
-
- plc->qlen = ZSTR_LEN(buf);
- plc->quoted = estrdup(ZSTR_VAL(buf));
- plc->freeq = 1;
+ plc->quoted = zend_long_to_str(zval_get_long(parameter));
break;
case PDO_PARAM_NULL:
- plc->quoted = "NULL";
- plc->qlen = sizeof("NULL")-1;
- plc->freeq = 0;
+ plc->quoted = ZSTR_KNOWN(ZEND_STR_NULL);
break;
- default:
- buf = zval_get_string(parameter);
- if (EG(exception) ||
- !stmt->dbh->methods->quoter(stmt->dbh, ZSTR_VAL(buf),
- ZSTR_LEN(buf), &plc->quoted, &plc->qlen,
- param_type)) {
+ default: {
+ buf = zval_try_get_string(parameter);
+ /* parameter does not have a string representation, buf == NULL */
+ if (EG(exception)) {
/* bork */
ret = -1;
strncpy(stmt->error_code, stmt->dbh->error_code, 6);
- if (buf) {
- zend_string_release_ex(buf, 0);
- }
goto clean_up;
}
- plc->freeq = 1;
+
+ plc->quoted = stmt->dbh->methods->quoter(stmt->dbh, buf, param_type);
+ }
}
if (buf) {
@@ -320,20 +294,19 @@ safe:
} else {
parameter = &param->parameter;
}
- plc->quoted = Z_STRVAL_P(parameter);
- plc->qlen = Z_STRLEN_P(parameter);
+ plc->quoted = zend_string_copy(Z_STR_P(parameter));
}
- newbuffer_len += plc->qlen;
+ newbuffer_len += ZSTR_LEN(plc->quoted);
}
rewrite:
/* allocate output buffer */
- newbuffer = emalloc(newbuffer_len + 1);
- *outquery = newbuffer;
+ *outquery = zend_string_alloc(newbuffer_len, 0);
+ newbuffer = ZSTR_VAL(*outquery);
/* and build the query */
+ const char *ptr = ZSTR_VAL(inquery);
plc = placeholders;
- ptr = inquery;
do {
t = plc->pos - ptr;
@@ -342,8 +315,8 @@ rewrite:
newbuffer += t;
}
if (plc->quoted) {
- memcpy(newbuffer, plc->quoted, plc->qlen);
- newbuffer += plc->qlen;
+ memcpy(newbuffer, ZSTR_VAL(plc->quoted), ZSTR_LEN(plc->quoted));
+ newbuffer += ZSTR_LEN(plc->quoted);
} else {
memcpy(newbuffer, plc->pos, plc->len);
newbuffer += plc->len;
@@ -353,24 +326,23 @@ rewrite:
plc = plc->next;
} while (plc);
- t = (inquery + inquery_len) - ptr;
+ t = ZSTR_VAL(inquery) + ZSTR_LEN(inquery) - ptr;
if (t) {
memcpy(newbuffer, ptr, t);
newbuffer += t;
}
*newbuffer = '\0';
- *outquery_len = newbuffer - *outquery;
+ ZSTR_LEN(*outquery) = newbuffer - ZSTR_VAL(*outquery);
ret = 1;
goto clean_up;
} else if (query_type == PDO_PLACEHOLDER_POSITIONAL) {
/* rewrite ? to :pdoX */
- char *name, *idxbuf;
const char *tmpl = stmt->named_rewrite_template ? stmt->named_rewrite_template : ":pdo%d";
int bind_no = 1;
- newbuffer_len = inquery_len;
+ newbuffer_len = ZSTR_LEN(inquery);
if (stmt->bound_param_map == NULL) {
ALLOC_HASHTABLE(stmt->bound_param_map);
@@ -379,36 +351,35 @@ rewrite:
for (plc = placeholders; plc; plc = plc->next) {
int skip_map = 0;
- char *p;
+ zend_string *p;
+ zend_string *idxbuf;
if (plc->bindno == PDO_PARSER_BINDNO_ESCAPED_CHAR) {
continue;
}
- name = estrndup(plc->pos, plc->len);
+ zend_string *name = zend_string_init(plc->pos, plc->len, 0);
/* check if bound parameter is already available */
- if (!strcmp(name, "?") || (p = zend_hash_str_find_ptr(stmt->bound_param_map, name, plc->len)) == NULL) {
- spprintf(&idxbuf, 0, tmpl, bind_no++);
+ if (zend_string_equals_literal(name, "?") || (p = zend_hash_find_ptr(stmt->bound_param_map, name)) == NULL) {
+ idxbuf = zend_strpprintf(0, tmpl, bind_no++);
} else {
- idxbuf = estrdup(p);
+ idxbuf = zend_string_copy(p);
skip_map = 1;
}
plc->quoted = idxbuf;
- plc->qlen = strlen(plc->quoted);
- plc->freeq = 1;
- newbuffer_len += plc->qlen;
+ newbuffer_len += ZSTR_LEN(plc->quoted);
if (!skip_map && stmt->named_rewrite_template) {
/* create a mapping */
- zend_hash_str_update_mem(stmt->bound_param_map, name, plc->len, idxbuf, plc->qlen + 1);
+ zend_hash_update_ptr(stmt->bound_param_map, name, zend_string_copy(plc->quoted));
}
/* map number to name */
- zend_hash_index_update_mem(stmt->bound_param_map, plc->bindno, idxbuf, plc->qlen + 1);
+ zend_hash_index_update_ptr(stmt->bound_param_map, plc->bindno, zend_string_copy(plc->quoted));
- efree(name);
+ zend_string_release(name);
}
goto rewrite;
@@ -416,7 +387,7 @@ rewrite:
} else {
/* rewrite :name to ? */
- newbuffer_len = inquery_len;
+ newbuffer_len = ZSTR_LEN(inquery);
if (stmt->bound_param_map == NULL) {
ALLOC_HASHTABLE(stmt->bound_param_map);
@@ -424,12 +395,9 @@ rewrite:
}
for (plc = placeholders; plc; plc = plc->next) {
- char *name;
- name = estrndup(plc->pos, plc->len);
- zend_hash_index_update_mem(stmt->bound_param_map, plc->bindno, name, plc->len + 1);
- efree(name);
- plc->quoted = "?";
- plc->qlen = 1;
+ zend_string *name = zend_string_init(plc->pos, plc->len, 0);
+ zend_hash_index_update_ptr(stmt->bound_param_map, plc->bindno, name);
+ plc->quoted = ZSTR_CHAR('?');
newbuffer_len -= plc->len - 1;
}
@@ -441,11 +409,9 @@ clean_up:
while (placeholders) {
plc = placeholders;
placeholders = plc->next;
-
- if (plc->freeq) {
- efree(plc->quoted);
+ if (plc->quoted) {
+ zend_string_release_ex(plc->quoted, 0);
}
-
efree(plc);
}