Page MenuHomePhabricator

D12263.diff
No OneTemporary

D12263.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -5235,6 +5235,7 @@
'PhabricatorHandleQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorHarbormasterApplication' => 'PhabricatorApplication',
'PhabricatorHarbormasterConfigOptions' => 'PhabricatorApplicationConfigOptions',
+ 'PhabricatorHash' => 'Phobject',
'PhabricatorHashTestCase' => 'PhabricatorTestCase',
'PhabricatorHelpApplication' => 'PhabricatorApplication',
'PhabricatorHelpController' => 'PhabricatorController',
diff --git a/src/applications/repository/management/PhabricatorRepositoryManagementUpdateWorkflow.php b/src/applications/repository/management/PhabricatorRepositoryManagementUpdateWorkflow.php
--- a/src/applications/repository/management/PhabricatorRepositoryManagementUpdateWorkflow.php
+++ b/src/applications/repository/management/PhabricatorRepositoryManagementUpdateWorkflow.php
@@ -51,10 +51,9 @@
}
$repository = head($repos);
- $callsign = $repository->getCallsign();
try {
- $lock_name = get_class($this).':'.$callsign;
+ $lock_name = 'repository.update:'.$repository->getID();
$lock = PhabricatorGlobalLock::newLock($lock_name);
$lock->lock();
@@ -135,7 +134,7 @@
$proxy = new PhutilProxyException(
pht(
'Error while pushing "%s" repository to mirrors.',
- $repository->getCallsign()),
+ $repository->getMonogram()),
$ex);
phlog($proxy);
}
diff --git a/src/infrastructure/util/PhabricatorGlobalLock.php b/src/infrastructure/util/PhabricatorGlobalLock.php
--- a/src/infrastructure/util/PhabricatorGlobalLock.php
+++ b/src/infrastructure/util/PhabricatorGlobalLock.php
@@ -39,7 +39,20 @@
public static function newLock($name) {
$namespace = PhabricatorLiskDAO::getStorageNamespace();
- $full_name = 'global:'.$namespace.':'.$name;
+ $namespace = PhabricatorHash::digestToLength($namespace, 20);
+
+ $full_name = $namespace.'-g:'.$name;
+
+ $length_limit = 64;
+ if (strlen($full_name) > $length_limit) {
+ throw new Exception(
+ pht(
+ 'Lock name "%s" is too long (full lock name is "%s"). The '.
+ 'full lock name must not be longer than %s bytes.',
+ $name,
+ $full_name,
+ new PhutilNumber($length_limit)));
+ }
$lock = self::getLock($full_name);
if (!$lock) {
diff --git a/src/infrastructure/util/PhabricatorHash.php b/src/infrastructure/util/PhabricatorHash.php
--- a/src/infrastructure/util/PhabricatorHash.php
+++ b/src/infrastructure/util/PhabricatorHash.php
@@ -1,7 +1,8 @@
<?php
-final class PhabricatorHash {
+final class PhabricatorHash extends Phobject {
+ const INDEX_DIGEST_LENGTH = 12;
/**
* Digest a string for general use, including use which relates to security.
@@ -68,11 +69,56 @@
}
$result = '';
- for ($ii = 0; $ii < 12; $ii++) {
+ for ($ii = 0; $ii < self::INDEX_DIGEST_LENGTH; $ii++) {
$result .= $map[(ord($hash[$ii]) & 0x3F)];
}
return $result;
}
+
+ /**
+ * Shorten a string to a maximum byte length in a collision-resistant way
+ * while retaining some degree of human-readability.
+ *
+ * This function converts an input string into a prefix plus a hash. For
+ * example, a very long string beginning with "crabapplepie..." might be
+ * digested to something like "crabapp-N1wM1Nz3U84k".
+ *
+ * This allows the maximum length of identifiers to be fixed while
+ * maintaining a high degree of collision resistance and a moderate degree
+ * of human readability.
+ *
+ * @param string The string to shorten.
+ * @param int Maximum length of the result.
+ * @return string String shortened in a collision-resistant way.
+ */
+ public static function digestToLength($string, $length) {
+ // We need at least two more characters than the hash length to fit in a
+ // a 1-character prefix and a separator.
+ $min_length = self::INDEX_DIGEST_LENGTH + 2;
+ if ($length < $min_length) {
+ throw new Exception(
+ pht(
+ 'Length parameter in digestToLength() must be at least %s, '.
+ 'but %s was provided.',
+ new PhutilNumber($min_length),
+ new PhutilNumber($length)));
+ }
+
+ // We could conceivably return the string unmodified if it's shorter than
+ // the specified length. Instead, always hash it. This makes the output of
+ // the method more recognizable and consistent (no surprising new behavior
+ // once you hit a string longer than `$length`) and prevents an attacker
+ // who can control the inputs from intentionally using the hashed form
+ // of a string to cause a collision.
+
+ $hash = PhabricatorHash::digestForIndex($string);
+
+ $prefix = substr($string, 0, ($length - ($min_length - 1)));
+
+ return $prefix.'-'.$hash;
+ }
+
+
}

File Metadata

Mime Type
text/plain
Expires
Wed, Nov 20, 2:41 PM (21 h, 55 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6745707
Default Alt Text
D12263.diff (4 KB)

Event Timeline