Skip to content

Commit

Permalink
Issue #2823361 by stevector, David Strauss: Uncaught PHP Exception ca…
Browse files Browse the repository at this point in the history
…used by long cache IDs
  • Loading branch information
stevector authored Nov 21, 2016
1 parent 2938479 commit fcff1cc
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 3 deletions.
6 changes: 3 additions & 3 deletions circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ dependencies:
- composer global require "hirak/prestissimo:^0.3"
- composer global require drush/drush:8.*
# @todo, composer is probably a bad/slow way to install core here.
# Use something like drush's
- git clone --branch 8.1.x https://git.drupal.org/project/drupal.git $DOCROOT
# Use something like drush's
- git clone --branch 8.2.x https://git.drupal.org/project/drupal.git $DOCROOT
- cd $DOCROOT && composer install
# Add apache config.
# Modify user to make sure that there will be no permission issues.
Expand Down Expand Up @@ -66,7 +66,7 @@ test:
override:
- ./vendor/bin/phpcs --report=full --extensions=php,module,inc,theme,info --standard=vendor/drupal/coder/coder_sniffer/Drupal/ --ignore=vendor .
- cd $DOCROOT && /home/ubuntu/.phpenv/shims/php core/scripts/run-tests.sh --url $SERVER --module lcache --php /home/ubuntu/.phpenv/shims/php --verbose --color

deployment:
feature:
branch: 8.x-1.x
Expand Down
32 changes: 32 additions & 0 deletions src/Backend.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public function __construct($bin, \LCache\Integrated $integrated) {
* The Cache ID.
*/
protected function getAddress($cid) {
$cid = $this->normalizeCid($cid);
return new \LCache\Address($this->bin, $cid);
}

Expand Down Expand Up @@ -203,4 +204,35 @@ public function garbageCollection() {
public function isEmpty() {
return FALSE;
}

/**
* Normalizes a cache ID in order to comply with database limitations.
*
* @param string $cid
* The passed in cache ID.
*
* @return string
* An ASCII-encoded cache ID that is limited in length.
*/
protected function normalizeCid($cid) {
$cid_is_ascii = mb_check_encoding($cid, 'ASCII');

// 508 is the max length of the address column (512) minus
// the number of characters that will be added to the stored address value
// by Address::serialze() when the bin length is long (two digits).
$max_cid_length = 508 - strlen($this->bin);
if (strlen($cid) <= $max_cid_length && $cid_is_ascii) {
return $cid;
}

// Return a string that uses as much as possible of the original cache ID
// with the hash appended.
// Cut the hash in half to allow for more storage of the real cid's length
// to be stored.
$hash = substr(hash('sha512', $cid), 0, 64);
if (!$cid_is_ascii) {
return $hash;
}
return substr($cid, 0, $max_cid_length - strlen($hash)) . $hash;
}
}
25 changes: 25 additions & 0 deletions src/Tests/BackendUnitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -275,4 +275,29 @@ public function testInvalidate() {
$this->assertFalse($backend->invalidateMultiple(array()));
}
// @codingStandardsIgnoreEnd

/**
* Test \Drupal\lcache\Backend::normalizeCids().
*/
public function testSetGetLong() {

$backend = $this->getCacheBackend();

// Set up a cache ID that is not ASCII and longer than 255 characters so we
// can test cache ID normalization.
$cid_long = str_repeat('愛€', 1000);
$cached_value_long = $this->randomMachineName();
$backend->set($cid_long, $cached_value_long);
$this->assertIdentical($cached_value_long, $backend->get($cid_long)->data, "Backend contains the correct value for long, non-ASCII cache id.");

$cid_long = str_repeat('abcdefghijk', 100);
$cached_value_long = $this->randomMachineName();
$backend->set($cid_long, $cached_value_long);
$this->assertIdentical($cached_value_long, $backend->get($cid_long)->data, "Backend contains the correct value for long, non-ASCII cache id.");

$cid_short = '愛1€';
$cached_value_short = $this->randomMachineName();
$backend->set($cid_short, $cached_value_short);
$this->assertIdentical($cached_value_short, $backend->get($cid_short)->data, "Backend contains the correct value for short, non-ASCII cache id.");
}
}

0 comments on commit fcff1cc

Please sign in to comment.