Skip to content

Commit

Permalink
Clamp limit values to be unsigned integers.
Browse files Browse the repository at this point in the history
This solves large page numbers potentially turning into scientific
notation when being formatted into queries. It also further safeguards
against SQL manipulation.

Refs #GH-1263
  • Loading branch information
markstory committed May 3, 2013
1 parent bd3be28 commit 2096d3f
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 25 deletions.
7 changes: 3 additions & 4 deletions lib/Cake/Controller/Component/PaginatorComponent.php
Expand Up @@ -212,6 +212,9 @@ public function paginate($object = null, $scope = array(), $whitelist = array())
$pageCount = intval(ceil($count / $limit));
$requestedPage = $page;
$page = max(min($page, $pageCount), 1);
if ($requestedPage > $page) {
throw new NotFoundException();
}

$paging = array(
'page' => $page,
Expand All @@ -234,10 +237,6 @@ public function paginate($object = null, $scope = array(), $whitelist = array())
array($object->alias => $paging)
);

if ($requestedPage > $page) {
throw new NotFoundException();
}

if (
!in_array('Paginator', $this->Controller->helpers) &&
!array_key_exists('Paginator', $this->Controller->helpers)
Expand Down
9 changes: 3 additions & 6 deletions lib/Cake/Model/Datasource/DboSource.php
Expand Up @@ -2672,16 +2672,13 @@ protected function _quoteMatchedField($match) {
*/
public function limit($limit, $offset = null) {
if ($limit) {
$rt = '';
if (!strpos(strtolower($limit), 'limit')) {
$rt = ' LIMIT';
}
$rt = ' LIMIT';

if ($offset) {
$rt .= ' ' . $offset . ',';
$rt .= sprintf(' %u,', $offset);
}

$rt .= ' ' . $limit;
$rt .= sprintf(' %u', $limit);
return $rt;
}
return null;
Expand Down
21 changes: 6 additions & 15 deletions lib/Cake/Test/Case/Controller/Component/PaginatorComponentTest.php
Expand Up @@ -896,44 +896,35 @@ public function testOutOfRangePageNumberGetsClamped() {
* @expectedException NotFoundException
* @return void
*/
public function testOutOfVeryBigRangePageNumberGetsClamped() {
public function testOutOfVeryBigPageNumberGetsClamped() {
$Controller = new PaginatorTestController($this->request);
$Controller->uses = array('PaginatorControllerPost');
$Controller->params['named'] = array(
'page' => 3000000000000000000000000,
'page' => '3000000000000000000000000',
);
$Controller->constructClasses();
$Controller->PaginatorControllerPost->recursive = 0;
$Controller->Paginator->paginate('PaginatorControllerPost');
}
}

/**
* testOutOfRangePageNumberAndPageCountZero
*
* @expectedException NotFoundException
* @return void
*/
public function testOutOfRangePageNumberAndPageCountZero() {
$Controller = new PaginatorTestController($this->request);
$Controller->uses = array('PaginatorControllerPost');
$Controller->params['named'] = array(
'page' => 3000,
'page' => '3000',
);
$Controller->constructClasses();
$Controller->PaginatorControllerPost->recursive = 0;
$Controller->paginate = array(
'conditions' => array('PaginatorControllerPost.id >' => 100)
);
try {
$Controller->Paginator->paginate('PaginatorControllerPost');
} catch (NotFoundException $e) {
$this->assertEquals(
1,
$Controller->request->params['paging']['PaginatorControllerPost']['page'],
'Page number should not be 0'
);
return;
}
$this->fail();
$Controller->Paginator->paginate('PaginatorControllerPost');
}

/**
Expand Down
24 changes: 24 additions & 0 deletions lib/Cake/Test/Case/Model/Datasource/DboSourceTest.php
Expand Up @@ -1229,4 +1229,28 @@ public function testConditionKeysToStringVirtualField() {
$this->assertEquals($expected, $result[0]);
}

/**
* Test the limit function.
*
* @return void
*/
public function testLimit() {
$db = new DboTestSource;

$result = $db->limit('0');
$this->assertNull($result);

$result = $db->limit('10');
$this->assertEquals(' LIMIT 10', $result);

$result = $db->limit('FARTS', 'BOOGERS');
$this->assertEquals(' LIMIT 0, 0', $result);

$result = $db->limit(20, 10);
$this->assertEquals(' LIMIT 10, 20', $result);

$result = $db->limit(10, 300000000000000000000000000000);
$this->assertEquals(' LIMIT 0, 10', $result);
}

}

0 comments on commit 2096d3f

Please sign in to comment.