Last active
March 11, 2024 10:20
-
-
Save adraffy/ed42569b9e0657c76e8269077e17aa47 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// @author raffy.eth | |
// SPDX-License-Identifier: MIT | |
pragma solidity ^0.8.23; | |
contract DNSDecoder { | |
function decode(bytes memory dns) external pure returns (string memory s) { | |
unchecked { | |
require(dns.length != 0); | |
bytes memory v = new bytes(dns.length - 1); // [5] 3abc0 => [3] abc, but "abc." so -1 | |
uint256 start; | |
assembly { start := add(dns, 32) } | |
uint256 src = start; | |
uint256 jump; | |
assembly { jump := sub(v, dns) } | |
while (true) { | |
uint256 word; | |
uint256 len; | |
assembly { word := mload(src) } | |
len = word >> 248; // read length from msb | |
if (len == 0) break; | |
require(src + len < start + v.length, "overflow"); // block malicious encodings | |
assembly { mstore(add(src, jump), shl(8, word)) } // memcpy 31 bytes | |
if (len < 32) { | |
src += len; | |
} else { | |
uint256 end = src + len; | |
src += ((len + 1) & 31); // shift so we're 32-aligned to the end | |
while (src < end) { | |
assembly { mstore(sub(add(src, jump), 1), mload(src)) } | |
src += 32; | |
} | |
src = end; | |
} | |
// add the period | |
assembly { mstore8(add(src, jump), 46) } | |
src += 1; | |
} | |
// we break the loop before adding the length of 0 (1) | |
jump = src - start; // so this is actual length | |
require(jump == v.length, "underflow"); | |
assembly { mstore(v, jump) } // truncate | |
s = string(v); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment