Don't use php_strtok_r in build_tablename

This is unnecessary convoluted... we just want to find the position
of the dot. Using php_strtok_r requires a copy of the string, and the
implementation also relied on the specific semantics of the scratch
space that strtok_r uses.
This commit is contained in:
Nikita Popov 2019-04-12 16:17:35 +02:00
parent 7207110362
commit 4cfa4fb55d

View file

@ -6570,38 +6570,32 @@ static int do_exec(smart_str *querystr, ExecStatusType expect, PGconn *pg_link,
static inline void build_tablename(smart_str *querystr, PGconn *pg_link, const char *table) /* {{{ */ static inline void build_tablename(smart_str *querystr, PGconn *pg_link, const char *table) /* {{{ */
{ {
char *table_copy, *escaped, *tmp; size_t table_len = strlen(table);
const char *token;
size_t len;
/* schame.table should be "schame"."table" */ /* schema.table should be "schema"."table" */
table_copy = estrdup(table); const char *dot = memchr(table, '.', table_len);
token = php_strtok_r(table_copy, ".", &tmp); size_t len = dot ? dot - table : table_len;
if (token == NULL) { if (_php_pgsql_detect_identifier_escape(table, len) == SUCCESS) {
token = table; smart_str_appendl(querystr, table, len);
}
len = strlen(token);
if (_php_pgsql_detect_identifier_escape(token, len) == SUCCESS) {
smart_str_appendl(querystr, token, len);
} else { } else {
escaped = PGSQLescapeIdentifier(pg_link, token, len); char *escaped = PGSQLescapeIdentifier(pg_link, table, len);
smart_str_appends(querystr, escaped); smart_str_appends(querystr, escaped);
PGSQLfree(escaped); PGSQLfree(escaped);
} }
if (tmp && *tmp) { if (dot) {
len = strlen(tmp); const char *after_dot = dot + 1;
len = table_len - len - 1;
/* "schema"."table" format */ /* "schema"."table" format */
if (_php_pgsql_detect_identifier_escape(tmp, len) == SUCCESS) { if (_php_pgsql_detect_identifier_escape(after_dot, len) == SUCCESS) {
smart_str_appendc(querystr, '.'); smart_str_appendc(querystr, '.');
smart_str_appendl(querystr, tmp, len); smart_str_appendl(querystr, after_dot, len);
} else { } else {
escaped = PGSQLescapeIdentifier(pg_link, tmp, len); char *escaped = PGSQLescapeIdentifier(pg_link, after_dot, len);
smart_str_appendc(querystr, '.'); smart_str_appendc(querystr, '.');
smart_str_appends(querystr, escaped); smart_str_appends(querystr, escaped);
PGSQLfree(escaped); PGSQLfree(escaped);
} }
} }
efree(table_copy);
} }
/* }}} */ /* }}} */