Skip to content

Commit c251232

Browse files
🐞 Fix Base58 decodeWord (#1545)
* 🐞 Fix Base58 `decodeWord` sanitizer ordering (#1544) * Added TestCase --------- Co-authored-by: 0x1220c <cristianizzo@me.com>
1 parent ab96a83 commit c251232

2 files changed

Lines changed: 44 additions & 2 deletions

File tree

β€Žsrc/utils/Base58.solβ€Ž

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,10 +189,15 @@ library Base58 {
189189

190190
for { let j := 0 } 1 {} {
191191
let c := sub(byte(0, mload(add(s, j))), 49)
192+
// Check if the input character is valid.
193+
if iszero(and(shl(c, 1), 0x3fff7ff03ffbeff01ff)) {
194+
mstore(0x00, 0xe8fad793) // `Base58DecodingError()`.
195+
revert(0x1c, 0x04)
196+
}
192197
let p := mul(result, 58)
193198
let acc := add(byte(0, mload(c)), p)
194-
// Check if the input character is valid.
195-
if iszero(and(0x3fff7ff03ffbeff01ff, shl(c, lt(lt(acc, p), lt(result, t))))) {
199+
// Check for multiplication or addition overflow.
200+
if iszero(lt(lt(acc, p), lt(result, t))) {
196201
mstore(0x00, 0xe8fad793) // `Base58DecodingError()`.
197202
revert(0x1c, 0x04)
198203
}

β€Žtest/Base58.t.solβ€Ž

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,43 @@ contract Base58Test is SoladyTest {
259259
this.decodeWord("JEKNVnkbo3jma5nREBBJCDoXFVeKkD56V3xKrvRmWxFH@");
260260
}
261261

262+
function testDecodeWordLowCharacterReverts() public {
263+
// 0 - 48 (before '1')
264+
for (uint256 i = 0; i < 48; i++) {
265+
vm.expectRevert(Base58.Base58DecodingError.selector);
266+
this.decodeWord(LibString.toHexString(i));
267+
}
268+
// 58 - 64 (: ; < = > ? @)
269+
for (uint256 i = 58; i <= 64; ++i) {
270+
vm.expectRevert(Base58.Base58DecodingError.selector);
271+
this.decodeWord(LibString.toHexString(i));
272+
}
273+
vm.expectRevert(Base58.Base58DecodingError.selector);
274+
this.decodeWord("I");
275+
vm.expectRevert(Base58.Base58DecodingError.selector);
276+
this.decodeWord("O");
277+
// 91 - 96 ([ \ ] ^ _ `)
278+
for (uint256 i = 91; i <= 96; ++i) {
279+
vm.expectRevert(Base58.Base58DecodingError.selector);
280+
this.decodeWord(LibString.toHexString(i));
281+
}
282+
vm.expectRevert(Base58.Base58DecodingError.selector);
283+
this.decodeWord("l");
284+
285+
// 123 - 127 ({ | } ~ DEL)
286+
for (uint256 i = 123; i <= 255; ++i) {
287+
vm.expectRevert(Base58.Base58DecodingError.selector);
288+
this.decodeWord(LibString.toHexString(i));
289+
}
290+
vm.expectRevert(Base58.Base58DecodingError.selector);
291+
this.decodeWord("\x00");
292+
293+
// Also cover an underflowing byte after a valid character, where
294+
// `result` is already nonzero (loop position > 0).
295+
vm.expectRevert(Base58.Base58DecodingError.selector);
296+
this.decodeWord("z0");
297+
}
298+
262299
function decodeWord(string memory encoded) public pure returns (bytes32) {
263300
return Base58.decodeWord(encoded);
264301
}

0 commit comments

Comments
Β (0)