I wanted to test a multi-site setup by making copies of the variable-table and prefixing one for each site. This causes errors related to locking the variable-table (no prefix) when editing settings on any of the sites.

The code that causes this behavior is in includes/bootstrap.inc line 237 and 324

This has previously been discussed here: http://drupal.org/node/47135

I think hitka's proposed solution is ok, simply add the prefix before calling db_lock_table, but maybe this should be handled in database.*.inc.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

arkepp’s picture

Just a small clarification: If you keep the original table named 'variable' you do not get any error messages, but that of course means you lock and unlock the wrong table.

wulff’s picture

AFAICT this has been fixed in cvs: db_lock_table() calls db_query() which takes care of prefixing the tables before running the query.

olav’s picture

Version: 4.7.0-beta6 » 4.7.0-rc3
Component: base system » database system
Assigned: Unassigned » olav
Status: Active » Needs review

4.7rc3 still has this bug.
The fix is simple:

Replace (database.mysql.inc:356)

db_query('LOCK TABLES {%s} WRITE', $table);

with

db_query('LOCK TABLES {' . $table . '} WRITE');

--
Olav

Gerhard Killesreiter’s picture

Version: 4.7.0-rc3 » x.y.z
Priority: Normal » Critical

Olav, can you explain why

db_query('LOCK TABLES {%s} WRITE', $table);

does not work?

rkerr’s picture

Must be in how db_query stuff parses arguments.
I'll bet that anything that gets sprintf'd into the query string is not checked for {table_name} and run through the prefixing routine.

moshe weitzman’s picture

#3 looks safe to me. nohere do we use user generated input as a table name.

rkerr’s picture

FileSize
1.07 KB

Patch attached. For MySQL and MySQLi as well.

rkerr’s picture

FileSize
1.72 KB

Added db_escape_string around $table for safety, and updated PostgreSQL inc file as well.
(New patch attached).

rkerr’s picture

FileSize
1.67 KB

Another patch for all 3 database includes, without escaping.

Steven’s picture

FileSize
2.41 KB

Using db_escape_string here is useless. The characters are not inserted inside an SQL string, but inside the SQL query itself. You don't need to get out of a " to do bad things.

Using %s is bad because prefixing is done before inserting the data. If you have a table-specific prefix, it will not get applied correctly.

It's safer to restrict table vars using an explicit db_escape_table() function which only allows alphanumerics. Patch attached.

chx’s picture

Status: Needs review » Reviewed & tested by the community

The usual quality from Steven.

rkerr’s picture

Yeah that's the best way to do it. Steven's braver than I in adding core functions ;)

Steven’s picture

Status: Reviewed & tested by the community » Fixed

Committed to HEAD.

Anonymous’s picture

Status: Fixed » Closed (fixed)