Skip to content

Commit

Permalink
Changesx in response to revie
Browse files Browse the repository at this point in the history
  • Loading branch information
Arachnid committed Apr 4, 2024
1 parent 38407f0 commit 63ca27e
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 1 deletion.
26 changes: 26 additions & 0 deletions contracts/resolvers/profiles/ExtendedDNSResolver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ import "../../dnssec-oracle/BytesUtils.sol";
* - in which case they may not contain spaces - or single-quoted. Single quotes in
* a quoted value may be backslash-escaped.
*
*
* ┌────────┐
* │ ┌───┐ │
* ┌──────────────────────────────┴─┤" "│◄─┴────────────────────────────────────────┐
* │ └───┘ │
* │ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌────────────┐ ┌───┐ │
* ^─┴─►│key├─┬─►│"["├───►│arg├───►│"]"├─┬─►│"="├─┬─►│"'"├───►│quoted_value├───►│"'"├─┼─$
* └───┘ │ └───┘ └───┘ └───┘ │ └───┘ │ └───┘ └────────────┘ └───┘ │
* └──────────────────────────┘ │ ┌──────────────┐ │
* └─────────►│unquoted_value├─────────┘
* └──────────────┘
*
* Record types:
* - a[<coinType>] - Specifies how an `addr()` request should be resolved for the specified
* `coinType`. Ethereum has `coinType` 60. The value must be 0x-prefixed hexadecimal, and will
Expand Down Expand Up @@ -148,14 +160,28 @@ contract ExtendedDNSResolver is IExtendedDNSResolver, IERC165 {
uint256 constant STATE_IGNORED_QUOTED_VALUE = 7;
uint256 constant STATE_IGNORED_UNQUOTED_VALUE = 8;

/**
* @dev Implements a DFA to parse the text record, looking for an entry
* matching `key`.
* @param data The text record to parse.
* @param key The exact key to search for.
* @return value The value if found, or an empty string if `key` does not exist.
*/
function _findValue(
bytes memory data,
bytes memory key
) internal pure returns (bytes memory value) {
// Here we use a simple state machine to parse the text record. We
// process characters one at a time; each character can trigger a
// transition to a new state, or terminate the DFA and return a value.
// For states that expect to process a number of tokens, we use
// inner loops for efficiency reasons, to avoid the need to go
// through the outer loop and switch statement for every character.
uint256 state = STATE_START;
uint256 len = data.length;
for (uint256 i = 0; i < len; ) {
if (state == STATE_START) {
// Look for a matching key.
if (data.equals(i, key, 0, key.length)) {
i += key.length;
state = STATE_VALUE;
Expand Down
11 changes: 11 additions & 0 deletions test/resolvers/TestExtendedDNSResolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,5 +216,16 @@ contract('ExtendedDNSResolver', function (accounts) {
"I'm great",
)
})

it('rejects a record with an unterminated quoted string', async function () {
const name = 'test.test'
const result = await resolve(
name,
'text',
['note'],
"t[note]='I\\'m great",
)
expect(result).to.equal(null)
})
})
})
3 changes: 2 additions & 1 deletion test/utils/TestHexUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use(solidity)

const NULL_HASH =
'0x0000000000000000000000000000000000000000000000000000000000000000'
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'

describe('HexUtils', () => {
let HexUtils
Expand Down Expand Up @@ -139,7 +140,7 @@ describe('HexUtils', () => {
39,
)
expect(valid).to.equal(false)
expect(address).to.equal('0x0000000000000000000000000000000000000000')
expect(address).to.equal(ZERO_ADDRESS)
})
})

Expand Down

0 comments on commit 63ca27e

Please sign in to comment.