Add byteLengthWithFallback to ShortStrings (#4089)
Co-authored-by: Francisco <fg@frang.io>
This commit is contained in:
@ -54,7 +54,7 @@ library ShortStrings {
|
||||
* @dev Decode a `ShortString` back to a "normal" string.
|
||||
*/
|
||||
function toString(ShortString sstr) internal pure returns (string memory) {
|
||||
uint256 len = length(sstr);
|
||||
uint256 len = byteLength(sstr);
|
||||
// using `new string(len)` would work locally but is not memory safe.
|
||||
string memory str = new string(32);
|
||||
/// @solidity memory-safe-assembly
|
||||
@ -68,7 +68,7 @@ library ShortStrings {
|
||||
/**
|
||||
* @dev Return the length of a `ShortString`.
|
||||
*/
|
||||
function length(ShortString sstr) internal pure returns (uint256) {
|
||||
function byteLength(ShortString sstr) internal pure returns (uint256) {
|
||||
uint256 result = uint256(ShortString.unwrap(sstr)) & 0xFF;
|
||||
if (result > 31) {
|
||||
revert InvalidShortString();
|
||||
@ -98,4 +98,18 @@ library ShortStrings {
|
||||
return store;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Return the length of a string that was encoded to `ShortString` or written to storage using {setWithFallback}.
|
||||
*
|
||||
* WARNING: This will return the "byte length" of the string. This may not reflect the actual length in terms of
|
||||
* actual characters as the UTF-8 encoding of a single character can span over multiple bytes.
|
||||
*/
|
||||
function byteLengthWithFallback(ShortString value, string storage store) internal view returns (uint256) {
|
||||
if (ShortString.unwrap(value) != _FALLBACK_SENTINEL) {
|
||||
return byteLength(value);
|
||||
} else {
|
||||
return bytes(store).length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@ contract('ShortStrings', function () {
|
||||
const encoded = await this.mock.$toShortString(str);
|
||||
expect(decode(encoded)).to.be.equal(str);
|
||||
|
||||
const length = await this.mock.$length(encoded);
|
||||
const length = await this.mock.$byteLength(encoded);
|
||||
expect(length.toNumber()).to.be.equal(str.length);
|
||||
|
||||
const decoded = await this.mock.$toString(encoded);
|
||||
@ -44,6 +44,9 @@ contract('ShortStrings', function () {
|
||||
await expectRevertCustomError(promise, 'InvalidShortString()');
|
||||
}
|
||||
|
||||
const length = await this.mock.$byteLengthWithFallback(ret0, 0);
|
||||
expect(length.toNumber()).to.be.equal(str.length);
|
||||
|
||||
const recovered = await this.mock.$toStringWithFallback(ret0, 0);
|
||||
expect(recovered).to.be.equal(str);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user