@ganache/rlp
Advanced tools
Comparing version 0.5.2 to 0.5.3-alpha.0
142
lib/index.js
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.decode = exports.encodeLength = exports.encode = exports.digest = exports.encodeRange = exports.getLength = void 0; | ||
const rlp_1 = require("rlp"); | ||
Object.defineProperty(exports, "getLength", { enumerable: true, get: function () { return rlp_1.getLength; } }); | ||
exports.decode = exports.encodeLength = exports.encode = exports.digest = exports.encodeRange = void 0; | ||
const utils_1 = require("@ganache/utils"); | ||
@@ -11,3 +9,2 @@ /** | ||
* | ||
* @param input - | ||
**/ | ||
@@ -102,6 +99,141 @@ function encodeRange(items, start, length) { | ||
exports.encodeLength = encodeLength; | ||
/** | ||
* Slices a Buffer, throws if the slice goes out-of-bounds of the Buffer. | ||
* E.g. `safeSlice(hexToBytes('aa'), 1, 2)` will throw. | ||
* @param input | ||
* @param start | ||
* @param end | ||
*/ | ||
function safeSlice(input, start, end) { | ||
if (end > input.length) { | ||
throw new Error("invalid RLP (safeSlice): end slice of Buffer out-of-bounds"); | ||
} | ||
return input.slice(start, end); | ||
} | ||
/** | ||
* RLP Decoding based on https://eth.wiki/en/fundamentals/rlp | ||
* @param input Will be converted to Buffer | ||
* @returns decoded Array of Buffers containing the original message | ||
**/ | ||
function decode(input) { | ||
return (0, rlp_1.decode)(input); | ||
if (!input || input.length === 0) { | ||
return utils_1.BUFFER_EMPTY; | ||
} | ||
const decoded = _decode(input); | ||
if (decoded.remainder.length !== 0) { | ||
throw new Error("invalid RLP: remainder must be zero"); | ||
} | ||
return decoded.data; | ||
} | ||
exports.decode = decode; | ||
/** | ||
* Parse integers. Check if there is no leading zeros | ||
* @param v The value to parse | ||
*/ | ||
function decodeLength(v) { | ||
if (v[0] === 0) { | ||
throw new Error("invalid RLP: extra zeros"); | ||
} | ||
return parseHexByte(bytesToHex(v)); | ||
} | ||
/** Decode an input with RLP */ | ||
function _decode(input) { | ||
let length, llength, data, innerRemainder, d; | ||
const decoded = []; | ||
const firstByte = input[0]; | ||
if (firstByte <= 0x7f) { | ||
// a single byte whose value is in the [0x00, 0x7f] range, that byte is its own RLP encoding. | ||
return { | ||
data: input.slice(0, 1), | ||
remainder: input.slice(1) | ||
}; | ||
} | ||
else if (firstByte <= 0xb7) { | ||
// string is 0-55 bytes long. A single byte with value 0x80 plus the length of the string followed by the string | ||
// The range of the first byte is [0x80, 0xb7] | ||
length = firstByte - 0x7f; | ||
// set 0x80 null to 0 | ||
if (firstByte === 0x80) { | ||
data = Buffer.from([]); | ||
} | ||
else { | ||
data = safeSlice(input, 1, length); | ||
} | ||
if (length === 2 && data[0] < 0x80) { | ||
throw new Error("invalid RLP encoding: invalid prefix, single byte < 0x80 are not prefixed"); | ||
} | ||
return { | ||
data, | ||
remainder: input.slice(length) | ||
}; | ||
} | ||
else if (firstByte <= 0xbf) { | ||
// string is greater than 55 bytes long. A single byte with the value (0xb7 plus the length of the length), | ||
// followed by the length, followed by the string | ||
llength = firstByte - 0xb6; | ||
if (input.length - 1 < llength) { | ||
throw new Error("invalid RLP: not enough bytes for string length"); | ||
} | ||
length = decodeLength(safeSlice(input, 1, llength)); | ||
if (length <= 55) { | ||
throw new Error("invalid RLP: expected string length to be greater than 55"); | ||
} | ||
data = safeSlice(input, llength, length + llength); | ||
return { | ||
data, | ||
remainder: input.slice(length + llength) | ||
}; | ||
} | ||
else if (firstByte <= 0xf7) { | ||
// a list between 0-55 bytes long | ||
length = firstByte - 0xbf; | ||
innerRemainder = safeSlice(input, 1, length); | ||
while (innerRemainder.length) { | ||
d = _decode(innerRemainder); | ||
decoded.push(d.data); | ||
innerRemainder = d.remainder; | ||
} | ||
return { | ||
data: decoded, | ||
remainder: input.slice(length) | ||
}; | ||
} | ||
else { | ||
// a list over 55 bytes long | ||
llength = firstByte - 0xf6; | ||
length = decodeLength(safeSlice(input, 1, llength)); | ||
if (length < 56) { | ||
throw new Error("invalid RLP: encoded list too short"); | ||
} | ||
const totalLength = llength + length; | ||
if (totalLength > input.length) { | ||
throw new Error("invalid RLP: total length is larger than the data"); | ||
} | ||
innerRemainder = safeSlice(input, llength, totalLength); | ||
while (innerRemainder.length) { | ||
d = _decode(innerRemainder); | ||
decoded.push(d.data); | ||
innerRemainder = d.remainder; | ||
} | ||
return { | ||
data: decoded, | ||
remainder: input.slice(totalLength) | ||
}; | ||
} | ||
} | ||
const cachedHexes = Array.from({ length: 256 }, (_v, i) => i.toString(16).padStart(2, "0")); | ||
function bytesToHex(uint8a) { | ||
// Pre-caching chars with `cachedHexes` speeds this up 6x | ||
let hex = ""; | ||
for (let i = 0; i < uint8a.length; i++) { | ||
hex += cachedHexes[uint8a[i]]; | ||
} | ||
return hex; | ||
} | ||
function parseHexByte(hexByte) { | ||
const byte = Number.parseInt(hexByte, 16); | ||
if (Number.isNaN(byte)) | ||
throw new Error("Invalid byte sequence"); | ||
return byte; | ||
} | ||
//# sourceMappingURL=index.js.map |
@@ -6,3 +6,3 @@ { | ||
}, | ||
"version": "0.5.2", | ||
"version": "0.5.3-alpha.0", | ||
"description": "Recursive Length Prefix Encoding Module", | ||
@@ -52,3 +52,3 @@ "author": "David Murdoch", | ||
"dependencies": { | ||
"@ganache/utils": "0.5.2", | ||
"@ganache/utils": "0.5.3-alpha.0", | ||
"rlp": "2.2.7" | ||
@@ -61,6 +61,6 @@ }, | ||
"nyc": "15.1.0", | ||
"ts-node": "10.4.0", | ||
"typescript": "4.6.4" | ||
"ts-node": "10.9.1", | ||
"typescript": "4.7.4" | ||
}, | ||
"gitHead": "e4722fe1f1755d34be17eb13f998c5f874647933" | ||
"gitHead": "c62e6fdd944db54143e3e0b57fb1643148d85682" | ||
} |
/// <reference types="node" /> | ||
import { getLength } from "rlp"; | ||
import type { Decoded } from "rlp"; | ||
import type { RangeOf, Remainders } from "./types"; | ||
export { getLength, Decoded }; | ||
export declare type Input = Buffer | Buffer[] | List; | ||
@@ -16,2 +13,7 @@ export interface List extends Array<Input> { | ||
}; | ||
export declare type NestedBuffer = Array<Buffer | NestedBuffer>; | ||
export interface Decoded<T extends Buffer | NestedBuffer> { | ||
data: T; | ||
remainder: Buffer; | ||
} | ||
/** | ||
@@ -21,3 +23,2 @@ * Begin RLP encoding of `items`, from `start` until `length`. Call `RLP.digest` to | ||
* | ||
* @param input - | ||
**/ | ||
@@ -39,5 +40,8 @@ export declare function encodeRange<T extends EncodingInput | Readonly<EncodingInput>, Start extends RangeOf<T["length"]>>(items: T, start: Start, length: Exclude<Remainders<T["length"], Start>, 0>): EncodedPart; | ||
export declare function encodeLength(len: number, offset: number): Buffer; | ||
export declare function decode(input: Buffer[]): Buffer[]; | ||
export declare function decode(input: Buffer): Buffer; | ||
export declare function decode<T>(input: Buffer | Buffer[]): T; | ||
/** | ||
* RLP Decoding based on https://eth.wiki/en/fundamentals/rlp | ||
* @param input Will be converted to Buffer | ||
* @returns decoded Array of Buffers containing the original message | ||
**/ | ||
export declare function decode<T extends Buffer | NestedBuffer = Buffer | NestedBuffer>(input: Buffer): T; | ||
//# sourceMappingURL=index.d.ts.map |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
49551
337
+ Added@ganache/utils@0.5.3-alpha.0(transitive)
- Removed@ganache/utils@0.5.2(transitive)
Updated@ganache/utils@0.5.3-alpha.0