mirror of
https://github.com/php/php-src.git
synced 2025-08-16 14:08:47 +02:00
Refactor PDO's quoter handler to return a zend_string
Closes GH-6547
This commit is contained in:
parent
df0fa5b178
commit
63cda0fea8
10 changed files with 124 additions and 109 deletions
|
@ -47,8 +47,12 @@ PHP 8.1 INTERNALS UPGRADE NOTES
|
||||||
getColumnMeta(). The type provided here does not need to match the type
|
getColumnMeta(). The type provided here does not need to match the type
|
||||||
returned by get_col (in fact no corresponding type might exist, e.g. for
|
returned by get_col (in fact no corresponding type might exist, e.g. for
|
||||||
floats). It should be the closest logical equivalent for the column type.
|
floats). It should be the closest logical equivalent for the column type.
|
||||||
- The transaction, set_attribute, quoter, and preparer handler's return type
|
- The transaction, set_attribute, and preparer handler's return type
|
||||||
has been formalized to bool instead of int.
|
has been formalized to bool instead of int.
|
||||||
- The check_liveness handler's return type has been formalized to zend_return
|
- The check_liveness handler's return type has been formalized to zend_return
|
||||||
instead of int.
|
instead of int.
|
||||||
- The closer, and fetch_error handlers have been voidified.
|
- The closer, and fetch_error handlers have been voidified.
|
||||||
|
- The quoter handler now returns the quoted string as zend_string* instead
|
||||||
|
of returning a boolean, and the quoted string as a pair of out params.
|
||||||
|
Similarly the unquoted string is now a zend_string* instead of a pair of
|
||||||
|
char* and size_t length.
|
||||||
|
|
|
@ -1119,18 +1119,17 @@ PHP_METHOD(PDO, query)
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ quotes string for use in a query. The optional paramtype acts as a hint for drivers that have alternate quoting styles. The default value is PDO_PARAM_STR */
|
/* {{{ quotes string for use in a query.
|
||||||
|
* The optional paramtype acts as a hint for drivers that have alternate quoting styles.
|
||||||
|
* The default value is PDO_PARAM_STR */
|
||||||
PHP_METHOD(PDO, quote)
|
PHP_METHOD(PDO, quote)
|
||||||
{
|
{
|
||||||
pdo_dbh_t *dbh = Z_PDO_DBH_P(ZEND_THIS);
|
pdo_dbh_t *dbh = Z_PDO_DBH_P(ZEND_THIS);
|
||||||
char *str;
|
zend_string *str;
|
||||||
size_t str_len;
|
|
||||||
zend_long paramtype = PDO_PARAM_STR;
|
zend_long paramtype = PDO_PARAM_STR;
|
||||||
char *qstr;
|
|
||||||
size_t qlen;
|
|
||||||
|
|
||||||
ZEND_PARSE_PARAMETERS_START(1, 2)
|
ZEND_PARSE_PARAMETERS_START(1, 2)
|
||||||
Z_PARAM_STRING(str, str_len)
|
Z_PARAM_STR(str)
|
||||||
Z_PARAM_OPTIONAL
|
Z_PARAM_OPTIONAL
|
||||||
Z_PARAM_LONG(paramtype)
|
Z_PARAM_LONG(paramtype)
|
||||||
ZEND_PARSE_PARAMETERS_END();
|
ZEND_PARSE_PARAMETERS_END();
|
||||||
|
@ -1143,13 +1142,7 @@ PHP_METHOD(PDO, quote)
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dbh->methods->quoter(dbh, str, str_len, &qstr, &qlen, paramtype)) {
|
RETURN_STR(dbh->methods->quoter(dbh, str, paramtype));
|
||||||
RETVAL_STRINGL(qstr, qlen);
|
|
||||||
efree(qstr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
PDO_HANDLE_DBH_ERR();
|
|
||||||
RETURN_FALSE;
|
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
|
|
@ -235,21 +235,18 @@ safe:
|
||||||
php_stream_from_zval_no_verify(stm, parameter);
|
php_stream_from_zval_no_verify(stm, parameter);
|
||||||
if (stm) {
|
if (stm) {
|
||||||
zend_string *buf;
|
zend_string *buf;
|
||||||
|
zend_string *quoted_buf;
|
||||||
|
|
||||||
buf = php_stream_copy_to_mem(stm, PHP_STREAM_COPY_ALL, 0);
|
buf = php_stream_copy_to_mem(stm, PHP_STREAM_COPY_ALL, 0);
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
buf = ZSTR_EMPTY_ALLOC();
|
buf = ZSTR_EMPTY_ALLOC();
|
||||||
}
|
}
|
||||||
if (!stmt->dbh->methods->quoter(stmt->dbh, ZSTR_VAL(buf), ZSTR_LEN(buf), &plc->quoted, &plc->qlen,
|
|
||||||
param->param_type)) {
|
quoted_buf = stmt->dbh->methods->quoter(stmt->dbh, buf, param->param_type);
|
||||||
/* bork */
|
plc->quoted = estrndup(ZSTR_VAL(quoted_buf), ZSTR_LEN(quoted_buf));
|
||||||
ret = -1;
|
plc->qlen = ZSTR_LEN(quoted_buf);
|
||||||
strncpy(stmt->error_code, stmt->dbh->error_code, 6);
|
zend_string_release_ex(quoted_buf, 0);
|
||||||
if (buf) {
|
|
||||||
zend_string_release_ex(buf, 0);
|
|
||||||
}
|
|
||||||
goto clean_up;
|
|
||||||
}
|
|
||||||
if (buf) {
|
if (buf) {
|
||||||
zend_string_release_ex(buf, 0);
|
zend_string_release_ex(buf, 0);
|
||||||
}
|
}
|
||||||
|
@ -289,21 +286,29 @@ safe:
|
||||||
plc->freeq = 0;
|
plc->freeq = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default: {
|
||||||
|
zend_string *quoted_buf;
|
||||||
|
|
||||||
|
/* TODO Should this be zval_try_get_string_func() ? */
|
||||||
buf = zval_get_string(parameter);
|
buf = zval_get_string(parameter);
|
||||||
if (EG(exception) ||
|
/* TODO Check when this can occur? */
|
||||||
!stmt->dbh->methods->quoter(stmt->dbh, ZSTR_VAL(buf),
|
if (EG(exception)) {
|
||||||
ZSTR_LEN(buf), &plc->quoted, &plc->qlen,
|
|
||||||
param_type)) {
|
|
||||||
/* bork */
|
/* bork */
|
||||||
ret = -1;
|
ret = -1;
|
||||||
strncpy(stmt->error_code, stmt->dbh->error_code, 6);
|
strncpy(stmt->error_code, stmt->dbh->error_code, 6);
|
||||||
|
/* TODO Is this dead code now? */
|
||||||
if (buf) {
|
if (buf) {
|
||||||
zend_string_release_ex(buf, 0);
|
zend_string_release_ex(buf, 0);
|
||||||
}
|
}
|
||||||
goto clean_up;
|
goto clean_up;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
quoted_buf = stmt->dbh->methods->quoter(stmt->dbh, buf, param_type);
|
||||||
|
plc->quoted = estrndup(ZSTR_VAL(quoted_buf), ZSTR_LEN(quoted_buf));
|
||||||
|
plc->qlen = ZSTR_LEN(quoted_buf);
|
||||||
plc->freeq = 1;
|
plc->freeq = 1;
|
||||||
|
zend_string_release_ex(quoted_buf, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buf) {
|
if (buf) {
|
||||||
|
|
|
@ -236,7 +236,7 @@ typedef bool (*pdo_dbh_prepare_func)(pdo_dbh_t *dbh, zend_string *sql, pdo_stmt_
|
||||||
typedef zend_long (*pdo_dbh_do_func)(pdo_dbh_t *dbh, const char *sql, size_t sql_len);
|
typedef zend_long (*pdo_dbh_do_func)(pdo_dbh_t *dbh, const char *sql, size_t sql_len);
|
||||||
|
|
||||||
/* quote a string */
|
/* quote a string */
|
||||||
typedef bool (*pdo_dbh_quote_func)(pdo_dbh_t *dbh, const char *unquoted, size_t unquotedlen, char **quoted, size_t *quotedlen, enum pdo_param_type paramtype);
|
typedef zend_string* (*pdo_dbh_quote_func)(pdo_dbh_t *dbh, const zend_string *unquoted, enum pdo_param_type paramtype);
|
||||||
|
|
||||||
/* transaction related (beingTransaction(), commit, rollBack, inTransaction)
|
/* transaction related (beingTransaction(), commit, rollBack, inTransaction)
|
||||||
* Return true if currently inside a transaction, false otherwise. */
|
* Return true if currently inside a transaction, false otherwise. */
|
||||||
|
|
|
@ -142,14 +142,14 @@ static zend_long dblib_handle_doer(pdo_dbh_t *dbh, const char *sql, size_t sql_l
|
||||||
return DBCOUNT(H->link);
|
return DBCOUNT(H->link);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool dblib_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unquotedlen, char **quoted, size_t *quotedlen, enum pdo_param_type paramtype)
|
static zend_string* dblib_handle_quoter(pdo_dbh_t *dbh, const zend_string *unquoted, enum pdo_param_type paramtype)
|
||||||
{
|
{
|
||||||
pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data;
|
pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data;
|
||||||
zend_bool use_national_character_set = 0;
|
zend_bool use_national_character_set = 0;
|
||||||
|
|
||||||
size_t i;
|
size_t i;
|
||||||
char *q;
|
char *q;
|
||||||
*quotedlen = 0;
|
size_t quotedlen = 0;
|
||||||
|
zend_string *quoted_str;
|
||||||
|
|
||||||
if (H->assume_national_character_set_strings) {
|
if (H->assume_national_character_set_strings) {
|
||||||
use_national_character_set = 1;
|
use_national_character_set = 1;
|
||||||
|
@ -162,34 +162,34 @@ static bool dblib_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unq
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Detect quoted length, adding extra char for doubled single quotes */
|
/* Detect quoted length, adding extra char for doubled single quotes */
|
||||||
for (i = 0; i < unquotedlen; i++) {
|
for (i = 0; i < ZSTR_LEN(unquoted); i++) {
|
||||||
if (unquoted[i] == '\'') ++*quotedlen;
|
if (ZSTR_VAL(unquoted)[i] == '\'') ++quotedlen;
|
||||||
++*quotedlen;
|
++quotedlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
*quotedlen += 2; /* +2 for opening, closing quotes */
|
quotedlen += 2; /* +2 for opening, closing quotes */
|
||||||
if (use_national_character_set) {
|
if (use_national_character_set) {
|
||||||
++*quotedlen; /* N prefix */
|
++quotedlen; /* N prefix */
|
||||||
}
|
}
|
||||||
q = *quoted = emalloc(*quotedlen + 1); /* Add byte for terminal null */
|
quoted_str = zend_string_alloc(quotedlen, 0);
|
||||||
|
q = ZSTR_VAL(quoted_str);
|
||||||
if (use_national_character_set) {
|
if (use_national_character_set) {
|
||||||
*q++ = 'N';
|
*q++ = 'N';
|
||||||
}
|
}
|
||||||
*q++ = '\'';
|
*q++ = '\'';
|
||||||
|
|
||||||
for (i = 0; i < unquotedlen; i++) {
|
for (i = 0; i < ZSTR_LEN(unquoted); i++) {
|
||||||
if (unquoted[i] == '\'') {
|
if (ZSTR_VAL(unquoted)[i] == '\'') {
|
||||||
*q++ = '\'';
|
*q++ = '\'';
|
||||||
*q++ = '\'';
|
*q++ = '\'';
|
||||||
} else {
|
} else {
|
||||||
*q++ = unquoted[i];
|
*q++ = ZSTR_VAL(unquoted)[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*q++ = '\'';
|
*q++ = '\'';
|
||||||
|
*q = '\0';
|
||||||
|
|
||||||
*q = 0;
|
return quoted_str;
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool pdo_dblib_transaction_cmd(const char *cmd, pdo_dbh_t *dbh)
|
static bool pdo_dblib_transaction_cmd(const char *cmd, pdo_dbh_t *dbh)
|
||||||
|
|
|
@ -649,30 +649,29 @@ free_statement:
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* called by the PDO SQL parser to add quotes to values that are copied into SQL */
|
/* called by the PDO SQL parser to add quotes to values that are copied into SQL */
|
||||||
static bool firebird_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unquotedlen, /* {{{ */
|
static zend_string* firebird_handle_quoter(pdo_dbh_t *dbh, const zend_string *unquoted, enum pdo_param_type paramtype)
|
||||||
char **quoted, size_t *quotedlen, enum pdo_param_type paramtype)
|
|
||||||
{
|
{
|
||||||
int qcount = 0;
|
int qcount = 0;
|
||||||
char const *co, *l, *r;
|
char const *co, *l, *r;
|
||||||
char *c;
|
char *c;
|
||||||
|
size_t quotedlen;
|
||||||
|
zend_string *quoted_str;
|
||||||
|
|
||||||
if (!unquotedlen) {
|
if (ZSTR_LEN(unquoted) == 0) {
|
||||||
*quotedlen = 2;
|
return zend_string_init("''", 2, 0);
|
||||||
*quoted = emalloc(*quotedlen+1);
|
|
||||||
strcpy(*quoted, "''");
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Firebird only requires single quotes to be doubled if string lengths are used */
|
/* Firebird only requires single quotes to be doubled if string lengths are used */
|
||||||
/* count the number of ' characters */
|
/* count the number of ' characters */
|
||||||
for (co = unquoted; (co = strchr(co,'\'')); qcount++, co++);
|
for (co = ZSTR_VAL(unquoted); (co = strchr(co,'\'')); qcount++, co++);
|
||||||
|
|
||||||
*quotedlen = unquotedlen + qcount + 2;
|
quotedlen = ZSTR_LEN(unquoted) + qcount + 2;
|
||||||
*quoted = c = emalloc(*quotedlen+1);
|
quoted_str = zend_string_alloc(quotedlen, 0);
|
||||||
|
c = ZSTR_VAL(quoted_str);
|
||||||
*c++ = '\'';
|
*c++ = '\'';
|
||||||
|
|
||||||
/* foreach (chunk that ends in a quote) */
|
/* foreach (chunk that ends in a quote) */
|
||||||
for (l = unquoted; (r = strchr(l,'\'')); l = r+1) {
|
for (l = ZSTR_VAL(unquoted); (r = strchr(l,'\'')); l = r+1) {
|
||||||
strncpy(c, l, r-l+1);
|
strncpy(c, l, r-l+1);
|
||||||
c += (r-l+1);
|
c += (r-l+1);
|
||||||
/* add the second quote */
|
/* add the second quote */
|
||||||
|
@ -680,11 +679,11 @@ static bool firebird_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy the remainder */
|
/* copy the remainder */
|
||||||
strncpy(c, l, *quotedlen-(c-*quoted)-1);
|
strncpy(c, l, quotedlen-(c-ZSTR_VAL(quoted_str))-1);
|
||||||
(*quoted)[*quotedlen-1] = '\'';
|
ZSTR_VAL(quoted_str)[quotedlen-1] = '\'';
|
||||||
(*quoted)[*quotedlen] = '\0';
|
ZSTR_VAL(quoted_str)[quotedlen] = '\0';
|
||||||
|
|
||||||
return true;
|
return quoted_str;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
|
|
@ -301,10 +301,13 @@ static char *pdo_mysql_last_insert_id(pdo_dbh_t *dbh, const char *name, size_t *
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* {{{ mysql_handle_quoter */
|
/* {{{ mysql_handle_quoter */
|
||||||
static bool mysql_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unquotedlen, char **quoted, size_t *quotedlen, enum pdo_param_type paramtype )
|
static zend_string* mysql_handle_quoter(pdo_dbh_t *dbh, const zend_string *unquoted, enum pdo_param_type paramtype )
|
||||||
{
|
{
|
||||||
pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
|
pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
|
||||||
zend_bool use_national_character_set = 0;
|
zend_bool use_national_character_set = 0;
|
||||||
|
char *quoted;
|
||||||
|
size_t quotedlen;
|
||||||
|
zend_string *quoted_str;
|
||||||
|
|
||||||
if (H->assume_national_character_set_strings) {
|
if (H->assume_national_character_set_strings) {
|
||||||
use_national_character_set = 1;
|
use_national_character_set = 1;
|
||||||
|
@ -318,24 +321,27 @@ static bool mysql_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unq
|
||||||
|
|
||||||
PDO_DBG_ENTER("mysql_handle_quoter");
|
PDO_DBG_ENTER("mysql_handle_quoter");
|
||||||
PDO_DBG_INF_FMT("dbh=%p", dbh);
|
PDO_DBG_INF_FMT("dbh=%p", dbh);
|
||||||
PDO_DBG_INF_FMT("unquoted=%.*s", (int)unquotedlen, unquoted);
|
PDO_DBG_INF_FMT("unquoted=%.*s", (int)ZSTR_LEN(unquoted), ZSTR_VAL(unquoted));
|
||||||
*quoted = safe_emalloc(2, unquotedlen, 3 + (use_national_character_set ? 1 : 0));
|
quoted = safe_emalloc(2, ZSTR_LEN(unquoted), 3 + (use_national_character_set ? 1 : 0));
|
||||||
|
|
||||||
if (use_national_character_set) {
|
if (use_national_character_set) {
|
||||||
*quotedlen = mysql_real_escape_string_quote(H->server, *quoted + 2, unquoted, unquotedlen, '\'');
|
quotedlen = mysql_real_escape_string_quote(H->server, quoted + 2, ZSTR_VAL(unquoted), ZSTR_LEN(unquoted), '\'');
|
||||||
(*quoted)[0] = 'N';
|
quoted[0] = 'N';
|
||||||
(*quoted)[1] = '\'';
|
quoted[1] = '\'';
|
||||||
|
|
||||||
++*quotedlen; /* N prefix */
|
++quotedlen; /* N prefix */
|
||||||
} else {
|
} else {
|
||||||
*quotedlen = mysql_real_escape_string_quote(H->server, *quoted + 1, unquoted, unquotedlen, '\'');
|
quotedlen = mysql_real_escape_string_quote(H->server, quoted + 1, ZSTR_VAL(unquoted), ZSTR_LEN(unquoted), '\'');
|
||||||
(*quoted)[0] = '\'';
|
quoted[0] = '\'';
|
||||||
}
|
}
|
||||||
|
|
||||||
(*quoted)[++*quotedlen] = '\'';
|
quoted[++quotedlen] = '\'';
|
||||||
(*quoted)[++*quotedlen] = '\0';
|
quoted[++quotedlen] = '\0';
|
||||||
PDO_DBG_INF_FMT("quoted=%.*s", (int)*quotedlen, *quoted);
|
PDO_DBG_INF_FMT("quoted=%.*s", (int)quotedlen, quoted);
|
||||||
PDO_DBG_RETURN(true);
|
|
||||||
|
quoted_str = zend_string_init(quoted, quotedlen, 0);
|
||||||
|
efree(quoted);
|
||||||
|
PDO_DBG_RETURN(quoted_str);
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
|
|
@ -350,40 +350,40 @@ static zend_long oci_handle_doer(pdo_dbh_t *dbh, const char *sql, size_t sql_len
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
static bool oci_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unquotedlen, char **quoted, size_t *quotedlen, enum pdo_param_type paramtype ) /* {{{ */
|
static zend_string* oci_handle_quoter(pdo_dbh_t *dbh, const zend_string *unquoted, enum pdo_param_type paramtype ) /* {{{ */
|
||||||
{
|
{
|
||||||
int qcount = 0;
|
int qcount = 0;
|
||||||
char const *cu, *l, *r;
|
char const *cu, *l, *r;
|
||||||
char *c;
|
char *c, *quoted;
|
||||||
|
zend_string *quoted_str;
|
||||||
|
|
||||||
if (!unquotedlen) {
|
if (ZSTR_LEN(unquoted) == 0) {
|
||||||
*quotedlen = 2;
|
return zend_string_init("''", 2, 0);
|
||||||
*quoted = emalloc(*quotedlen+1);
|
|
||||||
strcpy(*quoted, "''");
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* count single quotes */
|
/* count single quotes */
|
||||||
for (cu = unquoted; (cu = strchr(cu,'\'')); qcount++, cu++)
|
for (cu = ZSTR_VAL(unquoted); (cu = strchr(cu,'\'')); qcount++, cu++)
|
||||||
; /* empty loop */
|
; /* empty loop */
|
||||||
|
|
||||||
*quotedlen = unquotedlen + qcount + 2;
|
quotedlen = ZSTR_LEN(unquoted) + qcount + 2;
|
||||||
*quoted = c = emalloc(*quotedlen+1);
|
quoted = c = emalloc(quotedlen+1);
|
||||||
*c++ = '\'';
|
*c++ = '\'';
|
||||||
|
|
||||||
/* foreach (chunk that ends in a quote) */
|
/* foreach (chunk that ends in a quote) */
|
||||||
for (l = unquoted; (r = strchr(l,'\'')); l = r+1) {
|
for (l = ZSTR_VAL(unquoted); (r = strchr(l,'\'')); l = r+1) {
|
||||||
strncpy(c, l, r-l+1);
|
strncpy(c, l, r-l+1);
|
||||||
c += (r-l+1);
|
c += (r-l+1);
|
||||||
*c++ = '\''; /* add second quote */
|
*c++ = '\''; /* add second quote */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy remainder and add enclosing quote */
|
/* Copy remainder and add enclosing quote */
|
||||||
strncpy(c, l, *quotedlen-(c-*quoted)-1);
|
strncpy(c, l, quotedlen-(c-quoted)-1);
|
||||||
(*quoted)[*quotedlen-1] = '\'';
|
quoted[quotedlen-1] = '\'';
|
||||||
(*quoted)[*quotedlen] = '\0';
|
quoted[quotedlen] = '\0';
|
||||||
|
|
||||||
return true;
|
quoted_str = zend_string_init(quoted, quotedlen, 0);
|
||||||
|
efree(quoted);
|
||||||
|
return quoted_str;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
|
|
@ -317,33 +317,39 @@ static zend_long pgsql_handle_doer(pdo_dbh_t *dbh, const char *sql, size_t sql_l
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool pgsql_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unquotedlen, char **quoted, size_t *quotedlen, enum pdo_param_type paramtype)
|
static zend_string* pgsql_handle_quoter(pdo_dbh_t *dbh, const zend_string *unquoted, enum pdo_param_type paramtype)
|
||||||
{
|
{
|
||||||
unsigned char *escaped;
|
unsigned char *escaped;
|
||||||
|
char *quoted;
|
||||||
|
size_t quotedlen;
|
||||||
|
zend_string *quoted_str;
|
||||||
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
|
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
|
||||||
size_t tmp_len;
|
size_t tmp_len;
|
||||||
|
|
||||||
switch (paramtype) {
|
switch (paramtype) {
|
||||||
case PDO_PARAM_LOB:
|
case PDO_PARAM_LOB:
|
||||||
/* escapedlen returned by PQescapeBytea() accounts for trailing 0 */
|
/* escapedlen returned by PQescapeBytea() accounts for trailing 0 */
|
||||||
escaped = PQescapeByteaConn(H->server, (unsigned char *)unquoted, unquotedlen, &tmp_len);
|
escaped = PQescapeByteaConn(H->server, (unsigned char *)ZSTR_VAL(unquoted), ZSTR_LEN(unquoted), &tmp_len);
|
||||||
*quotedlen = tmp_len + 1;
|
quotedlen = tmp_len + 1;
|
||||||
*quoted = emalloc(*quotedlen + 1);
|
quoted = emalloc(quotedlen + 1);
|
||||||
memcpy((*quoted)+1, escaped, *quotedlen-2);
|
memcpy(quoted+1, escaped, quotedlen-2);
|
||||||
(*quoted)[0] = '\'';
|
quoted[0] = '\'';
|
||||||
(*quoted)[*quotedlen-1] = '\'';
|
quoted[quotedlen-1] = '\'';
|
||||||
(*quoted)[*quotedlen] = '\0';
|
quoted[quotedlen] = '\0';
|
||||||
PQfreemem(escaped);
|
PQfreemem(escaped);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
*quoted = safe_emalloc(2, unquotedlen, 3);
|
quoted = safe_emalloc(2, ZSTR_LEN(unquoted), 3);
|
||||||
(*quoted)[0] = '\'';
|
quoted[0] = '\'';
|
||||||
*quotedlen = PQescapeStringConn(H->server, *quoted + 1, unquoted, unquotedlen, NULL);
|
quotedlen = PQescapeStringConn(H->server, quoted + 1, ZSTR_VAL(unquoted), ZSTR_LEN(unquoted), NULL);
|
||||||
(*quoted)[*quotedlen + 1] = '\'';
|
quoted[quotedlen + 1] = '\'';
|
||||||
(*quoted)[*quotedlen + 2] = '\0';
|
quoted[quotedlen + 2] = '\0';
|
||||||
*quotedlen += 2;
|
quotedlen += 2;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
|
quoted_str = zend_string_init(quoted, quotedlen, 0);
|
||||||
|
efree(quoted);
|
||||||
|
return quoted_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *pdo_pgsql_last_insert_id(pdo_dbh_t *dbh, const char *name, size_t *len)
|
static char *pdo_pgsql_last_insert_id(pdo_dbh_t *dbh, const char *name, size_t *len)
|
||||||
|
|
|
@ -227,12 +227,14 @@ static char *pdo_sqlite_last_insert_id(pdo_dbh_t *dbh, const char *name, size_t
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NB: doesn't handle binary strings... use prepared stmts for that */
|
/* NB: doesn't handle binary strings... use prepared stmts for that */
|
||||||
static bool sqlite_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unquotedlen, char **quoted, size_t *quotedlen, enum pdo_param_type paramtype )
|
static zend_string* sqlite_handle_quoter(pdo_dbh_t *dbh, const zend_string *unquoted, enum pdo_param_type paramtype)
|
||||||
{
|
{
|
||||||
*quoted = safe_emalloc(2, unquotedlen, 3);
|
char *quoted = safe_emalloc(2, ZSTR_LEN(unquoted), 3);
|
||||||
sqlite3_snprintf(2*unquotedlen + 3, *quoted, "'%q'", unquoted);
|
/* TODO use %Q format? */
|
||||||
*quotedlen = strlen(*quoted);
|
sqlite3_snprintf(2*ZSTR_LEN(unquoted) + 3, quoted, "'%q'", ZSTR_VAL(unquoted));
|
||||||
return true;
|
zend_string *quoted_str = zend_string_init(quoted, strlen(quoted), 0);
|
||||||
|
efree(quoted);
|
||||||
|
return quoted_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool sqlite_handle_begin(pdo_dbh_t *dbh)
|
static bool sqlite_handle_begin(pdo_dbh_t *dbh)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue