This commit is contained in:
parent
97acaa1129
commit
4e394fc680
@ -83,8 +83,8 @@ export class AbiCoder {
|
||||
|
||||
_getWordSize(): number { return 32; }
|
||||
|
||||
_getReader(data: Uint8Array): Reader {
|
||||
return new Reader(data, this._getWordSize(), this.coerceFunc);
|
||||
_getReader(data: Uint8Array, allowLoose?: boolean): Reader {
|
||||
return new Reader(data, this._getWordSize(), this.coerceFunc, allowLoose);
|
||||
}
|
||||
|
||||
_getWriter(): Writer {
|
||||
@ -107,10 +107,10 @@ export class AbiCoder {
|
||||
return writer.data;
|
||||
}
|
||||
|
||||
decode(types: Array<string | ParamType>, data: BytesLike): Result {
|
||||
decode(types: Array<string | ParamType>, data: BytesLike, loose?: boolean): Result {
|
||||
const coders: Array<Coder> = types.map((type) => this._getCoder(ParamType.from(type)));
|
||||
const coder = new TupleCoder(coders, "_");
|
||||
return coder.decode(this._getReader(arrayify(data)));
|
||||
return coder.decode(this._getReader(arrayify(data), loose));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,16 +131,18 @@ export class Writer {
|
||||
|
||||
export class Reader {
|
||||
readonly wordSize: number;
|
||||
readonly allowLoose: boolean;
|
||||
|
||||
readonly _data: Uint8Array;
|
||||
readonly _coerceFunc: CoerceFunc;
|
||||
|
||||
_offset: number;
|
||||
|
||||
constructor(data: BytesLike, wordSize?: number, coerceFunc?: CoerceFunc) {
|
||||
constructor(data: BytesLike, wordSize?: number, coerceFunc?: CoerceFunc, allowLoose?: boolean) {
|
||||
defineReadOnly(this, "_data", arrayify(data));
|
||||
defineReadOnly(this, "wordSize", wordSize || 32);
|
||||
defineReadOnly(this, "_coerceFunc", coerceFunc);
|
||||
defineReadOnly(this, "allowLoose", allowLoose);
|
||||
|
||||
this._offset = 0;
|
||||
}
|
||||
@ -160,23 +162,27 @@ export class Reader {
|
||||
return Reader.coerce(name, value);
|
||||
}
|
||||
|
||||
_peekBytes(offset: number, length: number): Uint8Array {
|
||||
_peekBytes(offset: number, length: number, loose?: boolean): Uint8Array {
|
||||
let alignedLength = Math.ceil(length / this.wordSize) * this.wordSize;
|
||||
if (this._offset + alignedLength > this._data.length) {
|
||||
if (this.allowLoose && loose && this._offset + length <= this._data.length) {
|
||||
alignedLength = length;
|
||||
} else {
|
||||
logger.throwError("data out-of-bounds", Logger.errors.BUFFER_OVERRUN, {
|
||||
length: this._data.length,
|
||||
offset: this._offset + alignedLength
|
||||
});
|
||||
}
|
||||
}
|
||||
return this._data.slice(this._offset, this._offset + alignedLength)
|
||||
}
|
||||
|
||||
subReader(offset: number): Reader {
|
||||
return new Reader(this._data.slice(this._offset + offset), this.wordSize, this._coerceFunc);
|
||||
return new Reader(this._data.slice(this._offset + offset), this.wordSize, this._coerceFunc, this.allowLoose);
|
||||
}
|
||||
|
||||
readBytes(length: number): Uint8Array {
|
||||
let bytes = this._peekBytes(0, length);
|
||||
readBytes(length: number, loose?: boolean): Uint8Array {
|
||||
let bytes = this._peekBytes(0, length, !!loose);
|
||||
this._offset += bytes.length;
|
||||
// @TODO: Make sure the length..end bytes are all 0?
|
||||
return bytes.slice(0, length);
|
||||
|
@ -86,9 +86,6 @@ export function unpack(reader: Reader, coders: Array<Coder>): Result {
|
||||
// A reader anchored to this base
|
||||
let baseReader = reader.subReader(0);
|
||||
|
||||
// The amount of dynamic data read; to consume later to synchronize
|
||||
let dynamicLength = 0;
|
||||
|
||||
coders.forEach((coder) => {
|
||||
let value: any = null;
|
||||
|
||||
@ -105,7 +102,6 @@ export function unpack(reader: Reader, coders: Array<Coder>): Result {
|
||||
value.name = coder.localName;
|
||||
value.type = coder.type;
|
||||
}
|
||||
dynamicLength += offsetReader.consumed;
|
||||
|
||||
} else {
|
||||
try {
|
||||
@ -125,10 +121,6 @@ export function unpack(reader: Reader, coders: Array<Coder>): Result {
|
||||
}
|
||||
});
|
||||
|
||||
// @TODO: get rid of this an see if it still works?
|
||||
// Consume the dynamic components in the main reader
|
||||
reader.readBytes(dynamicLength);
|
||||
|
||||
// We only output named properties for uniquely named coders
|
||||
const uniqueNames = coders.reduce((accum, coder) => {
|
||||
const name = coder.localName;
|
||||
|
@ -17,7 +17,7 @@ export class DynamicBytesCoder extends Coder {
|
||||
}
|
||||
|
||||
decode(reader: Reader): any {
|
||||
return reader.readBytes(reader.readValue().toNumber());
|
||||
return reader.readBytes(reader.readValue().toNumber(), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -475,7 +475,7 @@ export class Interface {
|
||||
});
|
||||
|
||||
let resultIndexed = (topics != null) ? this._abiCoder.decode(indexed, concat(topics)): null;
|
||||
let resultNonIndexed = this._abiCoder.decode(nonIndexed, data);
|
||||
let resultNonIndexed = this._abiCoder.decode(nonIndexed, data, true);
|
||||
|
||||
let result: (Array<any> & { [ key: string ]: any }) = [ ];
|
||||
let nonIndexedIndex = 0, indexedIndex = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user