Skip to content

Instantly share code, notes, and snippets.

@adraffy
Last active March 11, 2024 10:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adraffy/ed42569b9e0657c76e8269077e17aa47 to your computer and use it in GitHub Desktop.
Save adraffy/ed42569b9e0657c76e8269077e17aa47 to your computer and use it in GitHub Desktop.
/// @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