Commit d3f8b78c authored by catch's avatar catch

Issue #1003788 by stefan.r, Alan D., JimmyAx, Josh Waihi, john_brown,...

Issue #1003788 by stefan.r, Alan D., JimmyAx, Josh Waihi, john_brown, bellHead, twistor, wiifm, bzrudi71, pwolanin, gngn, Gisle, robhardwick: Fixed PostgreSQL: PDOException:Invalid text representation when attempting to load an entity with a string or non-scalar ID.
parent 9d5d3b3b
......@@ -427,6 +427,12 @@ protected function doLoadMultiple(array $ids = NULL) {
protected function getFromStorage(array $ids = NULL) {
$entities = array();
if (!empty($ids)) {
// Sanitize IDs. Before feeding ID array into buildQuery, check whether
// it is empty as this would load all entities.
$ids = $this->cleanIds($ids);
}
if ($ids === NULL || $ids) {
// Build and execute the query.
$query_result = $this->buildQuery($ids)->execute();
......@@ -452,6 +458,30 @@ protected function getFromStorage(array $ids = NULL) {
return $entities;
}
/**
* Ensures integer entity IDs are valid.
*
* The identifier sanitization provided by this method has been introduced
* as Drupal used to rely on the database to facilitate this, which worked
* correctly with MySQL but led to errors with other DBMS such as PostgreSQL.
*
* @param array $ids
* The entity IDs to verify.
* @return array
* The sanitized list of entity IDs.
*/
protected function cleanIds(array $ids) {
$definitions = $this->entityManager->getBaseFieldDefinitions($this->entityTypeId);
$id_definition = $definitions[$this->entityType->getKey('id')];
if ($id_definition->getType() == 'integer') {
$ids = array_filter($ids, function ($id) {
return is_numeric($id) && $id == (int) $id;
});
$ids = array_map('intval', $ids);
}
return $ids;
}
/**
* Gets entities from the persistent cache backend.
*
......
......@@ -70,6 +70,11 @@ function testEntityViewController() {
$this->assertRaw($entity->label());
$this->assertRaw('full');
}
// As entity_test IDs must be integers, make sure requests for non-integer
// IDs return a page not found error.
$this->drupalGet('entity_test/invalid');
$this->assertResponse(404);
}
/**
......
......@@ -1180,6 +1180,75 @@ public function testLoadMultiplePersistentCacheMiss() {
$this->assertEquals($entity, $entities[$id]);
}
/**
* Tests entity ID sanitization.
*/
public function testCleanIds() {
$valid_ids = array(
-1,
0,
1,
'-1',
'0',
'1',
0123,
-0x1A,
0x1AFC,
-0b111,
0b101,
'0123',
'00123',
'000123',
'-0123',
'-00123',
'-000123',
-10.0,
-1.0,
0.0,
1.0,
10.0,
-10.00,
-1.00,
0.00,
1.00,
10.00,
);
$this->fieldDefinitions = $this->mockFieldDefinitions(array('id'));
$this->fieldDefinitions['id']->expects($this->any())
->method('getType')
->will($this->returnValue('integer'));
$this->setUpEntityStorage();
$this->entityType->expects($this->any())
->method('getKey')
->will($this->returnValueMap(array(
array('id', 'id'),
)));
$method = new \ReflectionMethod($this->entityStorage, 'cleanIds');
$method->setAccessible(TRUE);
$this->assertEquals($valid_ids, $method->invoke($this->entityStorage, $valid_ids));
$invalid_ids = array(
'--1',
'-0x1A',
'0x1AFC',
'-0b111',
'0b101',
'a',
FALSE,
TRUE,
NULL,
'32acb',
123.123,
123.678,
);
$this->assertEquals(array(), $method->invoke($this->entityStorage, $invalid_ids));
}
/**
* Sets up the module handler with no implementations.
*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment