diff options
Diffstat (limited to 'ext/pdo/pdo_sql_parser.re')
-rw-r--r-- | ext/pdo/pdo_sql_parser.re | 130 |
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 = ¶m->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); } |