Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Open sidebar
project
drupal
Commits
e9a044b3
Commit
e9a044b3
authored
Jan 29, 2014
by
catch
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue
#829464
by Berdir, Github sync, sepgil: Orderby() should escape fields and verify direction.
parent
29bf9e89
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
88 additions
and
12 deletions
+88
-12
core/lib/Drupal/Core/Database/Query/Select.php
core/lib/Drupal/Core/Database/Query/Select.php
+3
-1
core/lib/Drupal/Core/Database/Query/SelectInterface.php
core/lib/Drupal/Core/Database/Query/SelectInterface.php
+12
-2
core/lib/Drupal/Core/Database/Query/TableSortExtender.php
core/lib/Drupal/Core/Database/Query/TableSortExtender.php
+3
-4
core/lib/Drupal/Core/Entity/Query/Sql/Query.php
core/lib/Drupal/Core/Entity/Query/Sql/Query.php
+2
-2
core/lib/Drupal/Core/Entity/Query/Sql/QueryAggregate.php
core/lib/Drupal/Core/Entity/Query/Sql/QueryAggregate.php
+1
-1
core/modules/comment/comment.module
core/modules/comment/comment.module
+4
-2
core/tests/Drupal/Tests/Core/Database/OrderByTest.php
core/tests/Drupal/Tests/Core/Database/OrderByTest.php
+63
-0
No files found.
core/lib/Drupal/Core/Database/Query/Select.php
View file @
e9a044b3
...
...
@@ -541,6 +541,8 @@ public function addJoin($type, $table, $alias = NULL, $condition = NULL, $argume
}
public
function
orderBy
(
$field
,
$direction
=
'ASC'
)
{
// Only allow ASC and DESC, default to ASC.
$direction
=
strtoupper
(
$direction
)
==
'DESC'
?
'DESC'
:
'ASC'
;
$this
->
order
[
$field
]
=
$direction
;
return
$this
;
}
...
...
@@ -748,7 +750,7 @@ public function __toString() {
$query
.
=
"
\n
ORDER BY "
;
$fields
=
array
();
foreach
(
$this
->
order
as
$field
=>
$direction
)
{
$fields
[]
=
$field
.
' '
.
$direction
;
$fields
[]
=
$this
->
connection
->
escapeField
(
$field
)
.
' '
.
$direction
;
}
$query
.
=
implode
(
', '
,
$fields
);
}
...
...
core/lib/Drupal/Core/Database/Query/SelectInterface.php
View file @
e9a044b3
...
...
@@ -363,9 +363,19 @@ public function addJoin($type, $table, $alias = NULL, $condition = NULL, $argume
* called.
*
* @param $field
* The field on which to order.
* The field on which to order. The field is escaped for security so only
* valid field and alias names are possible. To order by an expression, add
* the expression with addExpression() first and then use the alias to order
* on.
*
* Example:
* <code>
* $query->addExpression('SUBSTRING(thread, 1, (LENGTH(thread) - 1))', 'order_field');
* $query->orderBy('order_field', 'ASC');
* </code>
* @param $direction
* The direction to sort. Legal values are "ASC" and "DESC".
* The direction to sort. Legal values are "ASC" and "DESC". Any other value
* will be converted to "ASC".
* @return \Drupal\Core\Database\Query\SelectInterface
* The called object.
*/
...
...
core/lib/Drupal/Core/Database/Query/TableSortExtender.php
View file @
e9a044b3
...
...
@@ -46,10 +46,9 @@ public function orderByHeader(array $header) {
// Based on code from db_escape_table(), but this can also contain a dot.
$field
=
preg_replace
(
'/[^A-Za-z0-9_.]+/'
,
''
,
$ts
[
'sql'
]);
// Sort order can only be ASC or DESC.
$sort
=
drupal_strtoupper
(
$ts
[
'sort'
]);
$sort
=
in_array
(
$sort
,
array
(
'ASC'
,
'DESC'
))
?
$sort
:
''
;
$this
->
orderBy
(
$field
,
$sort
);
// orderBy() will ensure that only ASC/DESC values are accepted, so we
// don't need to sanitize that here.
$this
->
orderBy
(
$field
,
$ts
[
'sort'
]);
}
return
$this
;
}
...
...
core/lib/Drupal/Core/Entity/Query/Sql/Query.php
View file @
e9a044b3
...
...
@@ -222,8 +222,8 @@ protected function addSort() {
// if the direction is descending.
$function
=
$direction
==
'ASC'
?
'min'
:
'max'
;
$expression
=
"
$function
(
$sql_alias
)"
;
$this
->
sqlQuery
->
addExpression
(
$expression
);
$this
->
sqlQuery
->
orderBy
(
$expression
,
$direction
);
$expression_alias
=
$this
->
sqlQuery
->
addExpression
(
$expression
);
$this
->
sqlQuery
->
orderBy
(
$expression
_alias
,
$direction
);
}
}
return
$this
;
...
...
core/lib/Drupal/Core/Entity/Query/Sql/QueryAggregate.php
View file @
e9a044b3
...
...
@@ -124,7 +124,7 @@ protected function addGroupBy() {
protected
function
addSortAggregate
()
{
if
(
!
$this
->
count
)
{
foreach
(
$this
->
sortAggregate
as
$alias
=>
$sort
)
{
$this
->
sqlQuery
->
orderBy
(
$
this
->
sqlExpressions
[
$
alias
]
,
$sort
[
'direction'
]);
$this
->
sqlQuery
->
orderBy
(
$alias
,
$sort
[
'direction'
]);
}
}
return
$this
;
...
...
core/modules/comment/comment.module
View file @
e9a044b3
...
...
@@ -370,9 +370,11 @@ function comment_new_page_count($num_comments, $new_replies, EntityInterface $en
->
range
(
0
,
$new_replies
);
// 2. Find the first thread.
$first_thread
=
db_select
(
$unread_threads_query
,
'thread'
)
$first_thread_query
=
db_select
(
$unread_threads_query
,
'thread'
);
$first_thread_query
->
addExpression
(
'SUBSTRING(thread, 1, (LENGTH(thread) - 1))'
,
'torder'
);
$first_thread
=
$first_thread_query
->
fields
(
'thread'
,
array
(
'thread'
))
->
orderBy
(
'
SUBSTRING(thread, 1, (LENGTH(thread) - 1))
'
)
->
orderBy
(
'
torder
'
)
->
range
(
0
,
1
)
->
execute
()
->
fetchField
();
...
...
core/tests/Drupal/Tests/Core/Database/OrderByTest.php
0 → 100644
View file @
e9a044b3
<?php
/**
* @file
* Contains Drupal\Tests\Core\Database\OrderByTest.
*/
namespace
Drupal\Tests\Core\Database
;
use
Drupal\Core\Database\Query\Select
;
use
Drupal\Tests\UnitTestCase
;
/**
* Tests the orderBy() method of select queries.
*/
class
OrderByTest
extends
UnitTestCase
{
/**
* The select query object to test.
*
* @var \Drupal\Core\Database\Query\Select
*/
protected
$query
;
/**
* {@inheritdoc}
*/
public
static
function
getInfo
()
{
return
array
(
'name'
=>
'Order by'
,
'description'
=>
'Tests the orderBy() method of select queries.'
,
'group'
=>
'Database'
,
);
}
/**
* {@inheritdoc}
*/
public
function
setUp
()
{
$connection
=
$this
->
getMockBuilder
(
'Drupal\Core\Database\Connection'
)
->
disableOriginalConstructor
()
->
getMockForAbstractClass
();
$this
->
query
=
new
Select
(
'test'
,
NULL
,
$connection
);
}
/**
* Checks that invalid sort directions in ORDER BY get converted to ASC.
*/
public
function
testInvalidDirection
()
{
$this
->
query
->
orderBy
(
'test'
,
'invalid direction'
);
$order_bys
=
$this
->
query
->
getOrderBy
();
$this
->
assertEquals
(
$order_bys
[
'test'
],
'ASC'
,
'Invalid order by direction is converted to ASC.'
);
}
/**
* Tests that fields passed for ordering get escaped properly.
*/
public
function
testFieldEscaping
()
{
$this
->
query
->
orderBy
(
'x; DROP table node; --'
);
$sql
=
$this
->
query
->
__toString
();
$this
->
assertStringEndsWith
(
'ORDER BY xDROPtablenode ASC'
,
$sql
,
'Order by field is escaped correctly.'
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment