mirror of https://github.com/nextcloud/bookmarks
Fix folder hashing: Murmur hash didn't work reliably
This commit is contained in:
parent
e806b07aaf
commit
ea2408b944
7
API.md
7
API.md
|
@ -346,12 +346,13 @@ The algorithm works as follows:
|
|||
- add to `childrenHashes`: `hashFolder(folderId, fields)`
|
||||
- if it's a bookmark
|
||||
- add to `childrenHashes`: `hashBookmark(bookmarkId, fields)`
|
||||
- Return `murmur2(to_json({title: folderTitle, children: childrenHashes}))`
|
||||
- Return `sha256(to_json({title: folderTitle, children: childrenHashes}))` with the title being unset in case of the root folder
|
||||
- `hashBookmark(id, fields)`
|
||||
- for all entries in `fields`
|
||||
- set `object[field]` to the value of the associated field of the bookmark
|
||||
- Return `murmur2(to_json(object))`
|
||||
- `murmur2`: [The murmur2 hashing algorithm](https://en.wikipedia.org/wiki/MurmurHash)
|
||||
- Return `sha256(to_json(object))`
|
||||
- `to_json`: A JSON stringification algorithm that adds no unnecessary white-space and doesn't use JSON's backslash escaping unless necessary (character set is UTF-8)
|
||||
- `sha256`: The SHA-256 hashing algorithm
|
||||
|
||||
### Delete folders
|
||||
|
||||
|
|
|
@ -333,8 +333,12 @@ class Bookmarks {
|
|||
throw new UnexpectedValueException('Expected bookmark or folder, but not '.$item['type']);
|
||||
}
|
||||
}, $children);
|
||||
$folder = ['title' => $folderRecord['title'], 'children' => $childHashes];
|
||||
return Murmur2Hash::hash(json_encode($folder));
|
||||
$folder = [];
|
||||
if (isset($folderRecord['title'])) {
|
||||
$folder['title'] = $folderRecord['title'];
|
||||
}
|
||||
$folder['children'] = $childHashes;
|
||||
return hash('sha256', json_encode($folder, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
||||
}
|
||||
|
||||
public function deleteFolder($userId, $folderId) {
|
||||
|
@ -419,7 +423,7 @@ class Bookmarks {
|
|||
$bookmark[$field] = $bookmarkRecord[$field];
|
||||
}
|
||||
}
|
||||
return Murmur2Hash::hash(json_encode($bookmark));
|
||||
return hash('sha256', json_encode($bookmark, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
<?php
|
||||
namespace OCA\Bookmarks;
|
||||
|
||||
class Murmur2Hash {
|
||||
public static function hash($str) {
|
||||
$l = strlen($str);
|
||||
$h = $l;
|
||||
$i = 0;
|
||||
|
||||
while ($l >= 4) {
|
||||
$k = ((ord(substr($str, $i)) & 0xff)) |
|
||||
((ord(substr($str, ++$i)) & 0xff) << 8) |
|
||||
((ord(substr($str, ++$i)) & 0xff) << 16) |
|
||||
((ord(substr($str, ++$i)) & 0xff) << 24);
|
||||
|
||||
$k = ((($k & 0xffff) * 0x5bd1e995) + (((self::unsignedRightShift($k, 16) * 0x5bd1e995) & 0xffff) << 16));
|
||||
$k ^= self::unsignedRightShift($k, 24);
|
||||
$k = ((($k & 0xffff) * 0x5bd1e995) + (((self::unsignedRightShift($k, 16) * 0x5bd1e995) & 0xffff) << 16));
|
||||
|
||||
$h = ((($h & 0xffff) * 0x5bd1e995) + (((self::unsignedRightShift($h, 16) * 0x5bd1e995) & 0xffff) << 16)) ^ $k;
|
||||
|
||||
$l -= 4;
|
||||
++$i;
|
||||
}
|
||||
|
||||
switch ($l) {
|
||||
case 3: $h ^= (ord(substr($str, $i + 2)) & 0xff) << 16;
|
||||
// no break
|
||||
case 2: $h ^= (ord(substr($str, $i + 1)) & 0xff) << 8;
|
||||
// no break
|
||||
case 1: $h ^= (ord(substr($str, $i)) & 0xff);
|
||||
$h = ((($h & 0xffff) * 0x5bd1e995) + (((self::unsignedRightShift($h, 16) * 0x5bd1e995) & 0xffff) << 16));
|
||||
}
|
||||
|
||||
$h ^= self::unsignedRightShift($h, 13);
|
||||
$h = ((($h & 0xffff) * 0x5bd1e995) + (((self::unsignedRightShift($h, 16) * 0x5bd1e995) & 0xffff) << 16));
|
||||
$h ^= self::unsignedRightShift($h, 15);
|
||||
|
||||
return self::unsignedRightShift($h, 0);
|
||||
}
|
||||
|
||||
private static function unsignedRightShift($a, $b) {
|
||||
if ($b >= 32 || $b < -32) {
|
||||
$m = (int)($b/32);
|
||||
$b = $b-($m*32);
|
||||
}
|
||||
|
||||
if ($b < 0) {
|
||||
$b = 32 + $b;
|
||||
}
|
||||
|
||||
if ($b == 0) {
|
||||
return (($a>>1) & 0x7fffffff) * 2 + (($a>>$b) & 1);
|
||||
}
|
||||
|
||||
if ($a < 0) {
|
||||
$a = ($a >> 1);
|
||||
$a &= 0x7fffffff;
|
||||
$a |= 0x40000000;
|
||||
$a = ($a >> ($b - 1));
|
||||
} else {
|
||||
$a = ($a >> $b);
|
||||
}
|
||||
return $a;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue