Skip to content

Commit

Permalink
fix: base64 generation and unicode characters (#197)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-akait committed Nov 4, 2021
1 parent 5fb5562 commit 8c2d24e
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 11 deletions.
10 changes: 7 additions & 3 deletions lib/getHashDigest.js
Expand Up @@ -40,6 +40,7 @@ function encodeBufferToBase(buffer, base) {
}

let createMd4 = undefined;
let BatchedHash = undefined;

function getHashDigest(buffer, hashType, digestType, maxLength) {
hashType = hashType || 'md4';
Expand All @@ -53,9 +54,13 @@ function getHashDigest(buffer, hashType, digestType, maxLength) {
if (error.code === 'ERR_OSSL_EVP_UNSUPPORTED' && hashType === 'md4') {
if (createMd4 === undefined) {
createMd4 = require('./hash/md4');

if (BatchedHash === undefined) {
BatchedHash = require('./hash/BatchedHash');
}
}

hash = createMd4();
hash = new BatchedHash(createMd4());
}

if (!hash) {
Expand All @@ -72,8 +77,7 @@ function getHashDigest(buffer, hashType, digestType, maxLength) {
digestType === 'base49' ||
digestType === 'base52' ||
digestType === 'base58' ||
digestType === 'base62' ||
digestType === 'base64'
digestType === 'base62'
) {
return encodeBufferToBase(hash.digest(), digestType.substr(4)).substr(
0,
Expand Down
64 changes: 64 additions & 0 deletions lib/hash/BatchedHash.js
@@ -0,0 +1,64 @@
const MAX_SHORT_STRING = require('./wasm-hash').MAX_SHORT_STRING;

class BatchedHash {
constructor(hash) {
this.string = undefined;
this.encoding = undefined;
this.hash = hash;
}

/**
* Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
* @param {string|Buffer} data data
* @param {string=} inputEncoding data encoding
* @returns {this} updated hash
*/
update(data, inputEncoding) {
if (this.string !== undefined) {
if (
typeof data === 'string' &&
inputEncoding === this.encoding &&
this.string.length + data.length < MAX_SHORT_STRING
) {
this.string += data;

return this;
}

this.hash.update(this.string, this.encoding);
this.string = undefined;
}

if (typeof data === 'string') {
if (
data.length < MAX_SHORT_STRING &&
// base64 encoding is not valid since it may contain padding chars
(!inputEncoding || !inputEncoding.startsWith('ba'))
) {
this.string = data;
this.encoding = inputEncoding;
} else {
this.hash.update(data, inputEncoding);
}
} else {
this.hash.update(data);
}

return this;
}

/**
* Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
* @param {string=} encoding encoding of the return value
* @returns {string|Buffer} digest
*/
digest(encoding) {
if (this.string !== undefined) {
this.hash.update(this.string, this.encoding);
}

return this.hash.digest(encoding);
}
}

module.exports = BatchedHash;
2 changes: 1 addition & 1 deletion lib/hash/wasm-hash.js
Expand Up @@ -82,7 +82,7 @@ class WasmHash {
endPos += 2;
} else {
// bail-out for weird chars
endPos += mem.write(data.slice(endPos), endPos, encoding);
endPos += mem.write(data.slice(i), endPos, encoding);
break;
}
}
Expand Down
4 changes: 2 additions & 2 deletions test/getHashDigest.test.js
Expand Up @@ -12,15 +12,15 @@ describe('getHashDigest()', () => {
'6f8db599de986fab7a21625b7916589c',
],
['test string', 'md5', 'hex', 4, '6f8d'],
['test string', 'md5', 'base64', undefined, '2sm1pVmS8xuGJLCdWpJoRL'],
['test string', 'md5', 'base64', undefined, 'b421md6Yb6t6IWJbeRZYnA=='],
['test string', 'md5', 'base52', undefined, 'dJnldHSAutqUacjgfBQGLQx'],
['test string', 'md5', 'base26', 6, 'bhtsgu'],
[
'test string',
'sha512',
'base64',
undefined,
'2IS-kbfIPnVflXb9CzgoNESGCkvkb0urMmucPD9z8q6HuYz8RShY1-tzSUpm5-Ivx_u4H1MEzPgAhyhaZ7RKog',
'EObWR69EYkRC84jCwUp4f/ixfmFluD12fsBHdo2MvLcaGjIm58x4Frx5wEJ9lKnaaIxBo5kse/Xk18w+C+XbrA==',
],
[
'test string',
Expand Down
10 changes: 5 additions & 5 deletions test/interpolateName.test.js
Expand Up @@ -62,13 +62,13 @@ describe('interpolateName()', () => {
'/app/img/image.png',
'[sha512:hash:base64:7].[ext]',
'test content',
'2BKDTjl.png',
'DL9MrvO.png',
],
[
'/app/img/image.png',
'[sha512:contenthash:base64:7].[ext]',
'test content',
'2BKDTjl.png',
'DL9MrvO.png',
],
[
'/app/dir/file.png',
Expand Down Expand Up @@ -116,13 +116,13 @@ describe('interpolateName()', () => {
'/lib/components/modal/modal.css',
'[name].[md5:hash:base64:20].[ext]',
'test content',
'modal.1n8osQznuT8jOAwdzg_n.css',
'modal.lHP90NiApDwht3eNNIch.css',
],
[
'/lib/components/modal/modal.css',
'[name].[md5:contenthash:base64:20].[ext]',
'test content',
'modal.1n8osQznuT8jOAwdzg_n.css',
'modal.lHP90NiApDwht3eNNIch.css',
],
// Should not interpret without `hash` or `contenthash`
[
Expand Down Expand Up @@ -265,7 +265,7 @@ describe('interpolateName()', () => {
],
[
[{}, '[hash:base64]', { content: 'test string' }],
'2LIG3oc1uBNmwOoL7kXgoK',
'Lgbt1PFiMmjFpRcw2KCyrw==',
'should interpolate [hash] token with options',
],
[
Expand Down

0 comments on commit 8c2d24e

Please sign in to comment.