Fix: Truncate key-length when generating identicons

Hex-digits with character count above 17 cannot be safely converted to an Integer, see [MAX_SAFE_INTEGER](https://medium.com/the-node-js-collection/javascripts-number-type-8d59199db1b6#53cd).

Therefore, when long keys (e.g. 32 characters) are passed into `generateIdenticon()`, and the modulus of 2^18 is performed, the result is 0 all the time. This means, the identicon will render as an empty svg image.

Here is a proof-of-concept (run in any modern browser):

```js
const key = '841b625dcf75413ff3ed5137a81ff1c3';
const int = parseInt(key, 16);
const hash = int % Math.pow(2, 18);
// throws, due to floating point conversion / integer overflow
console.assert(258499 === hash, "Modulus for 'hash' should be != 0");

const int2 = parseInt(key.substr(-16), 16);
const hash2 = int2 % Math.pow(2, 18);
// works as expected
console.assert(258048 === hash2, "Modulus 'hash2' should be != 0");
```

Truncating the passed in argument to a maximum of 16 characters solves the issue.

As a sidenote, the same code in Python will work correctly:

```python
key = '841b625dcf75413ff3ed5137a81ff1c3'
int = int(key, 16)
hash = int % pow(2, 18)
assert 258499 == hash
```
This commit is contained in:
Matthias Adler 2017-08-06 17:06:20 +02:00
parent c3933bd9fd
commit 43623f349b
No known key found for this signature in database
GPG Key ID: B34AD33A1E6348B1

View File

@ -47,7 +47,7 @@ define(["app/lib/promise", "app/config"], function(Q, config) {
} }
Q.when(key, function(key) { Q.when(key, function(key) {
var hash = pad((parseInt(key, 16) % Math.pow(2, 18)).toString(2), 18), var hash = pad((parseInt(key.substr(-16), 16) % Math.pow(2, 18)).toString(2), 18),
index = 0; index = 0;
svg.setAttribute("data-hash", key); svg.setAttribute("data-hash", key);