Adjust encoder/decoder fallbacks (#750)

* Adjust encoder/decoder fallbacks

* Dep-dup is functions

* Complexity cleanups
This commit is contained in:
Jaco Greeff
2020-11-08 11:20:22 +01:00
committed by GitHub
parent e1aa096cef
commit c67c1966d7
18 changed files with 118 additions and 78 deletions
+2 -2
View File
@@ -2,14 +2,14 @@
## 4.0.0-x
- **Breaking change** Polyfills are not provided by these libraries anymore to avoid clobbering external globals, the user should provide them if their environment is missing base functionality.
- **Breaking change** Polyfills are not injected by these libraries anymore to avoid clobbering external globals, the user should provide them if their environment is missing base functionality.
Changes:
- Remove built-in utility polyfills for `Array.fill`, `String.padStart`, `String.padEnd` as well as `Object.setPrototypeOf`. These should be provided by the actual user of the libraries if so required.
- Update `@polkadot/wasm-crypto` library (under-the-hood cleanups)
- Remove explicit crypto polyfill injection (aligning with updated `@polkadot/wasm-crypto`)
- Add `@polkadot/x-randomvalues` polyfill (for use in `@polkadot/wasm-crypto`)
- Add cross-environment `@polkadot/x-randomvalues` (for use in `@polkadot/wasm-crypto`)
## 3.7.1 Nov 1, 2020
+1 -1
View File
@@ -28,7 +28,7 @@
"@babel/runtime": "^7.12.1",
"@polkadot/networks": "^4.0.0-9",
"@polkadot/util": "^4.0.0-9",
"@polkadot/wasm-crypto": "^2.0.0-10",
"@polkadot/wasm-crypto": "^2.0.1",
"@polkadot/x-randomvalues": "^4.0.0-9",
"base-x": "^3.0.8",
"blakejs": "^1.1.0",
+6 -2
View File
@@ -3,10 +3,14 @@
import validate from './validate';
export default function isBase32 (value?: string | null): boolean {
export function testValidator (validate: (value?: string | null, ipfsCompat?: boolean) => boolean, value?: string | null, ipfsCompat?: boolean): boolean {
try {
return validate(value);
return validate(value, ipfsCompat);
} catch (error) {
return false;
}
}
export default function isBase32 (value?: string | null, ipfsCompat?: boolean): boolean {
return testValidator(validate, value, ipfsCompat);
}
+2 -5
View File
@@ -1,12 +1,9 @@
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { testValidator } from '../base32/is';
import validate from './validate';
export default function isBase58 (value?: string | null, ipfsCompat?: boolean): boolean {
try {
return validate(value, ipfsCompat);
} catch (error) {
return false;
}
return testValidator(validate, value, ipfsCompat);
}
+9 -5
View File
@@ -10,6 +10,14 @@ import isToBn from '../is/toBn';
import isHex from '../is/hex';
import hexToBn from '../hex/toBn';
function numberToBn <ExtToBn extends ToBn> (value: number | ExtToBn | BN): BN {
return BN.isBN(value)
? value
: isToBn(value)
? value.toBn()
: new BN(value);
}
/**
* @name bnToBn
* @summary Creates a BN value from a BN, BigInt, string (base 10 or hex) or number input.
@@ -35,9 +43,5 @@ export default function bnToBn <ExtToBn extends ToBn> (value?: ExtToBn | BN | Bi
return new BN(value.toString());
}
return BN.isBN(value)
? value
: isToBn(value)
? value.toBn()
: new BN(value);
return numberToBn(value);
}
+9 -5
View File
@@ -12,7 +12,13 @@ interface Options extends ToBnOptions {
bitLength?: number;
}
function setBn (valueBn: BN, byteLength: number, { isLe, isNegative }: Options): Uint8Array {
function createEmpty (byteLength: number, options: Options): Uint8Array {
return options.bitLength === -1
? new Uint8Array()
: new Uint8Array(byteLength);
}
function createValue (valueBn: BN, byteLength: number, { isLe, isNegative }: Options): Uint8Array {
const output = new Uint8Array(byteLength);
const bn = isNegative ? valueBn.toTwos(byteLength * 8) : valueBn;
@@ -51,10 +57,8 @@ function bnToU8a <ExtToBn extends ToBn> (value?: ExtToBn | BN | BigInt | number
: Math.ceil((options.bitLength || 0) / 8);
return value
? setBn(valueBn, byteLength, options)
: options.bitLength === -1
? new Uint8Array()
: new Uint8Array(byteLength);
? createValue(valueBn, byteLength, options)
: createEmpty(byteLength, options);
}
export default bnToU8a;
+3 -7
View File
@@ -35,11 +35,7 @@ export default function formatElapsed <ExtToBn extends ToBn> (now?: Date | null,
const tsNow = (now && now.getTime()) || 0;
const tsValue = getValue(value || 0);
if (tsNow && tsValue) {
const elapsed = Math.max(Math.abs(tsNow - tsValue), 0) / 1000;
return formatValue(elapsed);
}
return '0.0s';
return (tsNow && tsValue)
? formatValue(Math.max(Math.abs(tsNow - tsValue), 0) / 1000)
: '0.0s';
}
+9 -9
View File
@@ -22,14 +22,16 @@ const logTo = {
warn: 'warn'
};
function formatObject (value: Record<string, unknown>): Record<string, unknown> {
const result: Record<string, unknown> = {};
function formatOther (value: unknown): unknown {
if (value && isObject(value) && value.constructor === Object) {
return Object.keys(value).reduce((result: Record<string, unknown>, key): Record<string, unknown> => {
result[key] = format(value[key]);
return Object.keys(value).reduce((result, key): Record<string, unknown> => {
result[key] = format(value[key]);
return result;
}, {});
}
return result;
}, result);
return value;
}
export function format (value: unknown): unknown {
@@ -39,11 +41,9 @@ export function format (value: unknown): unknown {
return value.toString();
} else if (isU8a(value) || isBuffer(value)) {
return u8aToHex(u8aToU8a(value));
} else if (value && isObject(value) && value.constructor === Object) {
return formatObject(value);
}
return value;
return formatOther(value);
}
function apply (log: LogType, type: string, values: Logger$Data): void {
+14 -6
View File
@@ -8,6 +8,18 @@ import bufferToU8a from '../buffer/toU8a';
import hexToU8a from '../hex/toU8a';
import stringToU8a from '../string/toU8a';
function convertArray (value: number[] | Uint8Array): Uint8Array {
return Array.isArray(value)
? Uint8Array.from(value)
: value;
}
function convertString (value: string): Uint8Array {
return isHex(value)
? hexToU8a(value)
: stringToU8a(value);
}
/**
* @name u8aToU8a
* @summary Creates a Uint8Array value from a Uint8Array, Buffer, string or hex input.
@@ -29,12 +41,8 @@ export default function u8aToU8a (value?: number[] | Buffer | Uint8Array | strin
} else if (isBuffer(value)) {
return bufferToU8a(value);
} else if (isString(value)) {
return isHex(value)
? hexToU8a(value)
: stringToU8a(value);
return convertString(value);
}
return Array.isArray(value)
? Uint8Array.from(value)
: value;
return convertArray(value);
}
@@ -0,0 +1,20 @@
// Copyright 2017-2020 @polkadot/x-randomvalues authors & contributors
// SPDX-License-Identifier: Apache-2.0
import fallback from './fallback';
describe('fallback (insecure)', (): void => {
it('subsequent results does not match', (): void => {
expect(
fallback(new Uint8Array(32)).toString()
).not.toEqual(
fallback(new Uint8Array(32)).toString()
);
});
it('generates with the supplied length', (): void => {
expect(
fallback(new Uint8Array(128))
).toHaveLength(128);
});
});
+2 -2
View File
@@ -16,11 +16,11 @@ export default function insecureRandomValues <T extends Uint8Array> (arr: T): T
let r = 0;
for (let i = 0; i < arr.length; i++) {
if ((i & 0x03) === 0) {
if ((i & 0b11) === 0) {
r = Math.random() * 0x100000000;
}
arr[i] = (r >>> ((i & 0x03) << 3)) & 0xff;
arr[i] = (r >>> ((i & 0b11) << 3)) & 0xff;
}
return arr;
@@ -16,9 +16,6 @@ interface RNExt {
}
function getRandomValuesNative <T extends Uint8Array> (arr: T): T {
// We may want to use a base64 decoder here, but we certainly have an issue where we
// want/need this part as lean as possible. Since Buffer is already needed elsewhere
// (an generally prevalent in JS), we rather use it as-is.
return Buffer
.from((NativeModules as RNExt).RNGetRandomValues.getRandomBase64(arr.length), 'base64')
.reduce((arr, byte, index): T => {
+1 -1
View File
@@ -4,5 +4,5 @@
import Fallback from './fallback';
export default typeof TextDecoder === 'undefined'
? Fallback
? Fallback as unknown as typeof TextDecoder
: TextDecoder;
+1
View File
@@ -1,6 +1,7 @@
// Copyright 2017-2020 @polkadot/x-textencoder authors & contributors
// SPDX-License-Identifier: Apache-2.0
// This is very limited, only handling Ascii values
export default class TextDecoder {
// eslint-disable-next-line @typescript-eslint/no-unused-vars,no-useless-constructor
constructor (_: 'utf-8') {
+3 -11
View File
@@ -1,16 +1,8 @@
// Copyright 2017-2020 @polkadot/x-textencoder authors & contributors
// SPDX-License-Identifier: Apache-2.0
import Fallback from './fallback';
export default typeof TextEncoder === 'undefined'
? class {
encode (value: string): Uint8Array {
const u8a = new Uint8Array(value.length);
for (let i = 0; i < value.length; i++) {
u8a[i] = value.charCodeAt(i);
}
return u8a;
}
}
? Fallback as unknown as typeof TextEncoder
: TextEncoder;
+15
View File
@@ -0,0 +1,15 @@
// Copyright 2017-2020 @polkadot/x-textencoder authors & contributors
// SPDX-License-Identifier: Apache-2.0
// This is very limited, only handling Ascii values
export default class TextEncoder {
encode (value: string): Uint8Array {
const u8a = new Uint8Array(value.length);
for (let i = 0; i < value.length; i++) {
u8a[i] = value.charCodeAt(i);
}
return u8a;
}
}
+16 -14
View File
@@ -3,19 +3,21 @@
import { TextEncoder as NodeTextEncoder } from 'util';
class NodeFallback {
#encoder: NodeTextEncoder;
constructor () {
this.#encoder = new NodeTextEncoder();
}
// For a Jest 26.0.1 environment, Buffer !== Uint8Array
encode (value: string): Uint8Array {
const encoded = this.#encoder.encode(value);
return Uint8Array.from(encoded);
}
}
export default typeof TextEncoder === 'undefined'
? class {
#encoder: NodeTextEncoder;
constructor () {
this.#encoder = new NodeTextEncoder();
}
// For a Jest 26.0.1 environment, Buffer !== Uint8Array
encode (value: string): Uint8Array {
const encoded = this.#encoder.encode(value);
return Uint8Array.from(encoded);
}
} as unknown as typeof TextEncoder
? NodeFallback as unknown as typeof TextEncoder
: TextEncoder;
+5 -5
View File
@@ -1861,7 +1861,7 @@ __metadata:
"@babel/runtime": ^7.12.1
"@polkadot/networks": ^4.0.0-9
"@polkadot/util": ^4.0.0-9
"@polkadot/wasm-crypto": ^2.0.0-10
"@polkadot/wasm-crypto": ^2.0.1
"@polkadot/x-randomvalues": ^4.0.0-9
"@types/bn.js": ^4.11.6
"@types/create-hash": ^1.2.2
@@ -1896,13 +1896,13 @@ __metadata:
languageName: unknown
linkType: soft
"@polkadot/wasm-crypto@npm:^2.0.0-10":
version: 2.0.0-10
resolution: "@polkadot/wasm-crypto@npm:2.0.0-10"
"@polkadot/wasm-crypto@npm:^2.0.1":
version: 2.0.1
resolution: "@polkadot/wasm-crypto@npm:2.0.1"
peerDependencies:
"@polkadot/util": "*"
"@polkadot/x-randomvalues": "*"
checksum: 1217c72172b3781608280bd6c001b199ada00cec14326b27d081e1904967fc0246f512d1cd74bd15797c87f39d2efec2d639d89c608c0bcf140ec05ff8fe7564
checksum: eb5ff8e6614c98dcac94967e40d4e96bdd48521f26ab1f6419dbf14a9d76080880ab069ea2a1a55b1bd86b5c9f1480810bfb2ae36f3d54312a1631c0fefb04e3
languageName: node
linkType: hard