diff options
author | Dries Buytaert <dries@buytaert.net> | 2011-05-22 09:08:19 -0400 |
---|---|---|
committer | Dries Buytaert <dries@buytaert.net> | 2011-05-22 09:08:19 -0400 |
commit | 5dbe8aa92b9e746962b43f9a24b10d7f9616d232 (patch) | |
tree | 3a99baca5a9f27bb3914ef9ee082eb4d2d6d84fc /includes | |
parent | c88f2e0188e48f4c4adfb101d70733a0b27d4685 (diff) | |
parent | 267b9c435c5d7266f4ce674b84d95bfe1f5a0920 (diff) | |
download | brdo-5dbe8aa92b9e746962b43f9a24b10d7f9616d232.tar.gz brdo-5dbe8aa92b9e746962b43f9a24b10d7f9616d232.tar.bz2 |
Merge branch '7.x' of git.drupal.org:project/drupal into 7.x
Diffstat (limited to 'includes')
-rw-r--r-- | includes/common.inc | 13 | ||||
-rw-r--r-- | includes/database/database.inc | 57 | ||||
-rw-r--r-- | includes/database/mysql/query.inc | 8 | ||||
-rw-r--r-- | includes/database/pgsql/query.inc | 4 | ||||
-rw-r--r-- | includes/database/query.inc | 22 | ||||
-rw-r--r-- | includes/database/select.inc | 5 | ||||
-rw-r--r-- | includes/database/sqlite/query.inc | 8 | ||||
-rw-r--r-- | includes/menu.inc | 2 |
8 files changed, 91 insertions, 28 deletions
diff --git a/includes/common.inc b/includes/common.inc index 4168ec9a2..5dadb4d16 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -7496,8 +7496,15 @@ function entity_get_controller($entity_type) { * The type of entity, i.e. 'node', 'user'. * @param $entities * The entity objects which are being prepared for view, keyed by object ID. + * @param $langcode + * (optional) A language code to be used for rendering. Defaults to the global + * content language of the current request. */ -function entity_prepare_view($entity_type, $entities) { +function entity_prepare_view($entity_type, $entities, $langcode = NULL) { + if (!isset($langcode)) { + $langcode = $GLOBALS['language_content']->language; + } + // To ensure hooks are only run once per entity, check for an // entity_view_prepared flag and only process items without it. // @todo: resolve this more generally for both entity and field level hooks. @@ -7513,7 +7520,7 @@ function entity_prepare_view($entity_type, $entities) { } if (!empty($prepare)) { - module_invoke_all('entity_prepare_view', $prepare, $entity_type); + module_invoke_all('entity_prepare_view', $prepare, $entity_type, $langcode); } } @@ -7588,7 +7595,7 @@ function entity_label($entity_type, $entity) { $label = FALSE; $info = entity_get_info($entity_type); if (isset($info['label callback']) && function_exists($info['label callback'])) { - $label = $info['label callback']($entity); + $label = $info['label callback']($entity, $entity_type); } elseif (!empty($info['entity keys']['label']) && isset($entity->{$info['entity keys']['label']})) { $label = $entity->{$info['entity keys']['label']}; diff --git a/includes/database/database.inc b/includes/database/database.inc index 4539b37a7..4cc1a33d7 100644 --- a/includes/database/database.inc +++ b/includes/database/database.inc @@ -541,6 +541,63 @@ abstract class DatabaseConnection extends PDO { } /** + * Flatten an array of query comments into a single comment string. + * + * The comment string will be sanitized to avoid SQL injection attacks. + * + * @param $comments + * An array of query comment strings. + * + * @return + * A sanitized comment string. + */ + public function makeComment($comments) { + if (empty($comments)) + return ''; + + // Flatten the array of comments. + $comment = implode('; ', $comments); + + // Sanitize the comment string so as to avoid SQL injection attacks. + return '/* ' . $this->filterComment($comment) . ' */ '; + } + + /** + * Sanitize a query comment string. + * + * Ensure a query comment does not include strings such as "* /" that might + * terminate the comment early. This avoids SQL injection attacks via the + * query comment. The comment strings in this example are separated by a + * space to avoid PHP parse errors. + * + * For example, the comment: + * @code + * db_update('example') + * ->condition('id', $id) + * ->fields(array('field2' => 10)) + * ->comment('Exploit * / DROP TABLE node; --') + * ->execute() + * @endcode + * + * Would result in the following SQL statement being generated: + * @code + * "/ * Exploit * / DROP TABLE node; -- * / UPDATE example SET field2=..." + * @endcode + * + * Unless the comment is sanitised first, the SQL server would drop the + * node table and ignore the rest of the SQL statement. + * + * @param $comment + * A query comment string. + * + * @return + * A sanitized version of the query comment string. + */ + protected function filterComment($comment = '') { + return preg_replace('/(\/\*\s*)|(\s*\*\/)/', '', $comment); + } + + /** * Executes a query string against the database. * * This method provides a central handler for the actual execution of every diff --git a/includes/database/mysql/query.inc b/includes/database/mysql/query.inc index f7fb52f04..888b6a5a4 100644 --- a/includes/database/mysql/query.inc +++ b/includes/database/mysql/query.inc @@ -42,8 +42,8 @@ class InsertQuery_mysql extends InsertQuery { } public function __toString() { - // Create a comments string to prepend to the query. - $comments = (!empty($this->comments)) ? '/* ' . implode('; ', $this->comments) . ' */ ' : ''; + // Create a sanitized comment string to prepend to the query. + $comments = $this->connection->makeComment($this->comments); // Default fields are always placed first for consistency. $insert_fields = array_merge($this->defaultFields, $this->insertFields); @@ -92,8 +92,8 @@ class TruncateQuery_mysql extends TruncateQuery { // not transactional, and result in an implicit COMMIT. When we are in a // transaction, fallback to the slower, but transactional, DELETE. if ($this->connection->inTransaction()) { - // Create a comments string to prepend to the query. - $comments = (!empty($this->comments)) ? '/* ' . implode('; ', $this->comments) . ' */ ' : ''; + // Create a comment string to prepend to the query. + $comments = $this->connection->makeComment($this->comments); return $comments . 'DELETE FROM {' . $this->connection->escapeTable($this->table) . '}'; } else { diff --git a/includes/database/pgsql/query.inc b/includes/database/pgsql/query.inc index fe7909e17..f3783a9ca 100644 --- a/includes/database/pgsql/query.inc +++ b/includes/database/pgsql/query.inc @@ -103,8 +103,8 @@ class InsertQuery_pgsql extends InsertQuery { } public function __toString() { - // Create a comments string to prepend to the query. - $comments = (!empty($this->comments)) ? '/* ' . implode('; ', $this->comments) . ' */ ' : ''; + // Create a sanitized comment string to prepend to the query. + $comments = $this->connection->makeComment($this->comments); // Default fields are always placed first for consistency. $insert_fields = array_merge($this->defaultFields, $this->insertFields); diff --git a/includes/database/query.inc b/includes/database/query.inc index 7f3e9ff85..23b652f9b 100644 --- a/includes/database/query.inc +++ b/includes/database/query.inc @@ -361,6 +361,9 @@ abstract class Query implements QueryPlaceholderInterface { * for easier debugging and allows you to more easily find where a query * with a performance problem is being generated. * + * The comment string will be sanitized to remove * / and other characters + * that may terminate the string early so as to avoid SQL injection attacks. + * * @param $comment * The comment string to be inserted into the query. * @@ -623,9 +626,8 @@ class InsertQuery extends Query { * The prepared statement. */ public function __toString() { - - // Create a comments string to prepend to the query. - $comments = (!empty($this->comments)) ? '/* ' . implode('; ', $this->comments) . ' */ ' : ''; + // Create a sanitized comment string to prepend to the query. + $comments = $this->connection->makeComment($this->comments); // Default fields are always placed first for consistency. $insert_fields = array_merge($this->defaultFields, $this->insertFields); @@ -815,9 +817,8 @@ class DeleteQuery extends Query implements QueryConditionInterface { * The prepared statement. */ public function __toString() { - - // Create a comments string to prepend to the query. - $comments = (!empty($this->comments)) ? '/* ' . implode('; ', $this->comments) . ' */ ' : ''; + // Create a sanitized comment string to prepend to the query. + $comments = $this->connection->makeComment($this->comments); $query = $comments . 'DELETE FROM {' . $this->connection->escapeTable($this->table) . '} '; @@ -884,8 +885,8 @@ class TruncateQuery extends Query { * The prepared statement. */ public function __toString() { - // Create a comments string to prepend to the query. - $comments = (!empty($this->comments)) ? '/* ' . implode('; ', $this->comments) . ' */ ' : ''; + // Create a sanitized comment string to prepend to the query. + $comments = $this->connection->makeComment($this->comments); return $comments . 'TRUNCATE {' . $this->connection->escapeTable($this->table) . '} '; } @@ -1111,9 +1112,8 @@ class UpdateQuery extends Query implements QueryConditionInterface { * The prepared statement. */ public function __toString() { - - // Create a comments string to prepend to the query. - $comments = (!empty($this->comments)) ? '/* ' . implode('; ', $this->comments) . ' */ ' : ''; + // Create a sanitized comment string to prepend to the query. + $comments = $this->connection->makeComment($this->comments); // Expressions take priority over literal fields, so we process those first // and remove any literal fields that conflict. diff --git a/includes/database/select.inc b/includes/database/select.inc index 6e4b0dc48..716c2fc3d 100644 --- a/includes/database/select.inc +++ b/includes/database/select.inc @@ -1439,9 +1439,8 @@ class SelectQuery extends Query implements SelectQueryInterface { } public function __toString() { - - // Create a comments string to prepend to the query. - $comments = (!empty($this->comments)) ? '/* ' . implode('; ', $this->comments) . ' */ ' : ''; + // Create a sanitized comment string to prepend to the query. + $comments = $this->connection->makeComment($this->comments); // SELECT $query = $comments . 'SELECT '; diff --git a/includes/database/sqlite/query.inc b/includes/database/sqlite/query.inc index a176ed649..6b8a72f2a 100644 --- a/includes/database/sqlite/query.inc +++ b/includes/database/sqlite/query.inc @@ -32,8 +32,8 @@ class InsertQuery_sqlite extends InsertQuery { } public function __toString() { - // Create a comments string to prepend to the query. - $comments = (!empty($this->comments)) ? '/* ' . implode('; ', $this->comments) . ' */ ' : ''; + // Create a sanitized comment string to prepend to the query. + $comments = $this->connection->makeComment($this->comments); // Produce as many generic placeholders as necessary. $placeholders = array_fill(0, count($this->insertFields), '?'); @@ -148,8 +148,8 @@ class DeleteQuery_sqlite extends DeleteQuery { */ class TruncateQuery_sqlite extends TruncateQuery { public function __toString() { - // Create a comments string to prepend to the query. - $comments = (!empty($this->comments)) ? '/* ' . implode('; ', $this->comments) . ' */ ' : ''; + // Create a sanitized comment string to prepend to the query. + $comments = $this->connection->makeComment($this->comments); return $comments . 'DELETE FROM {' . $this->connection->escapeTable($this->table) . '} '; } diff --git a/includes/menu.inc b/includes/menu.inc index 2a8c80c41..cfd35c794 100644 --- a/includes/menu.inc +++ b/includes/menu.inc @@ -1044,7 +1044,7 @@ function menu_tree_output($tree) { } // Allow menu-specific theme overrides. - $element['#theme'] = 'menu_link__' . $data['link']['menu_name']; + $element['#theme'] = 'menu_link__' . strtr($data['link']['menu_name'], '-', '_'); $element['#attributes']['class'] = $class; $element['#title'] = $data['link']['title']; $element['#href'] = $data['link']['href']; |