Skip to content

Commit 17294f5

Browse files
authored
Merge pull request #85 from ensdomains/fix/insufficient-label-checks
fix: insufficient label checks for validity + compare tweaks
2 parents bf1f987 + c8f9dfb commit 17294f5

File tree

15 files changed

+3404
-41
lines changed

15 files changed

+3404
-41
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,5 @@ typings/
7373
# intellij
7474
.idea
7575

76-
/tests/.bin
76+
/tests/.bin
77+
/tests/.latest.json

src/@types/assembly/index.d.ts

Lines changed: 2752 additions & 0 deletions
Large diffs are not rendered by default.

src/@types/assembly/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"types": "index.d.ts"
3+
}
File renamed without changes.

src/@types/es5/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"types": "index.d.ts"
3+
}

src/ensRegistry.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { BigInt, crypto, ens } from "@graphprotocol/graph-ts";
33

44
import {
5+
checkValidLabel,
56
concat,
67
createEventID,
78
EMPTY_ADDRESS,
@@ -47,7 +48,7 @@ function getDomain(
4748
timestamp: BigInt = BIG_INT_ZERO
4849
): Domain | null {
4950
let domain = Domain.load(node);
50-
if (domain === null && node == ROOT_NODE) {
51+
if (domain == null && node == ROOT_NODE) {
5152
return createDomain(node, timestamp);
5253
} else {
5354
return domain;
@@ -94,25 +95,23 @@ function _handleNewOwner(event: NewOwnerEvent, isMigrated: boolean): void {
9495
let domain = getDomain(subnode, event.block.timestamp);
9596
let parent = getDomain(event.params.node.toHexString());
9697

97-
if (domain === null) {
98+
if (domain == null) {
9899
domain = new Domain(subnode);
99100
domain.createdAt = event.block.timestamp;
100101
domain.subdomainCount = 0;
101102
}
102103

103-
if (domain.parent === null && parent !== null) {
104+
if (domain.parent == null && parent != null) {
104105
parent.subdomainCount = parent.subdomainCount + 1;
105106
parent.save();
106107
}
107108

108109
if (domain.name == null) {
109110
// Get label and node names
110111
let label = ens.nameByHash(event.params.label.toHexString());
111-
if (label != null) {
112+
if (checkValidLabel(label)) {
112113
domain.labelName = label;
113-
}
114-
115-
if (label === null) {
114+
} else {
116115
label = "[" + event.params.label.toHexString().slice(2) + "]";
117116
}
118117
if (

src/ethRegistrar.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export function handleNameRegistered(event: NameRegisteredEvent): void {
5555
domain.expiryDate = event.params.expires.plus(GRACE_PERIOD_SECONDS);
5656

5757
let labelName = ens.nameByHash(label.toHexString());
58-
if (labelName != null) {
58+
if (checkValidLabel(labelName)) {
5959
domain.labelName = labelName;
6060
domain.name = labelName! + ".eth";
6161
registration.labelName = labelName;
@@ -100,7 +100,7 @@ function setNamePreimage(name: string, label: Bytes, cost: BigInt): void {
100100
}
101101

102102
let domain = Domain.load(crypto.keccak256(concat(rootNode, label)).toHex())!;
103-
if (domain.labelName !== name) {
103+
if (domain.labelName != name) {
104104
domain.labelName = name;
105105
domain.name = name + ".eth";
106106
domain.save();

src/nameWrapper.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ function decodeName(buf: Bytes): Array<string> | null {
3434
let len = buf[offset++];
3535
let hex = buf.toHexString();
3636
let firstLabel = "";
37-
if (len === 0) {
37+
if (len == 0) {
3838
return [firstLabel, "."];
3939
}
4040

@@ -68,7 +68,7 @@ export function handleNameWrapped(event: NameWrappedEvent): void {
6868
let decoded = decodeName(event.params.name);
6969
let label: string | null = null;
7070
let name: string | null = null;
71-
if (decoded !== null) {
71+
if (decoded != null) {
7272
label = decoded[0];
7373
name = decoded[1];
7474
}
@@ -120,7 +120,7 @@ export function handleNameUnwrapped(event: NameUnwrappedEvent): void {
120120

121121
let domain = createOrLoadDomain(node.toHex());
122122
domain.wrappedOwner = null;
123-
if (domain.expiryDate && domain.parent !== ETH_NODE) {
123+
if (domain.expiryDate && domain.parent != ETH_NODE) {
124124
domain.expiryDate = null;
125125
}
126126
domain.save();

src/resolver.ts

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export function handleAddrChanged(event: AddrChangedEvent): void {
5757
}
5858

5959
export function handleMulticoinAddrChanged(event: AddressChangedEvent): void {
60-
let resolver = getOrCreateResolver(event.params.node, event.address);
60+
let resolver = getOrCreateResolver(event.params.node, event.address, false);
6161

6262
let coinType = event.params.coinType;
6363
if (resolver.coinTypes == null) {
@@ -84,26 +84,32 @@ export function handleMulticoinAddrChanged(event: AddressChangedEvent): void {
8484
export function handleNameChanged(event: NameChangedEvent): void {
8585
if (event.params.name.indexOf("\u0000") != -1) return;
8686

87+
const resolver = getOrCreateResolver(event.params.node, event.address, true);
88+
8789
let resolverEvent = new NameChanged(createEventID(event));
88-
resolverEvent.resolver = createResolverID(event.params.node, event.address);
90+
resolverEvent.resolver = resolver.id;
8991
resolverEvent.blockNumber = event.block.number.toI32();
9092
resolverEvent.transactionID = event.transaction.hash;
9193
resolverEvent.name = event.params.name;
9294
resolverEvent.save();
9395
}
9496

9597
export function handleABIChanged(event: ABIChangedEvent): void {
98+
const resolver = getOrCreateResolver(event.params.node, event.address, true);
99+
96100
let resolverEvent = new AbiChanged(createEventID(event));
97-
resolverEvent.resolver = createResolverID(event.params.node, event.address);
101+
resolverEvent.resolver = resolver.id;
98102
resolverEvent.blockNumber = event.block.number.toI32();
99103
resolverEvent.transactionID = event.transaction.hash;
100104
resolverEvent.contentType = event.params.contentType;
101105
resolverEvent.save();
102106
}
103107

104108
export function handlePubkeyChanged(event: PubkeyChangedEvent): void {
109+
const resolver = getOrCreateResolver(event.params.node, event.address, true);
110+
105111
let resolverEvent = new PubkeyChanged(createEventID(event));
106-
resolverEvent.resolver = createResolverID(event.params.node, event.address);
112+
resolverEvent.resolver = resolver.id;
107113
resolverEvent.blockNumber = event.block.number.toI32();
108114
resolverEvent.transactionID = event.transaction.hash;
109115
resolverEvent.x = event.params.x;
@@ -112,7 +118,7 @@ export function handlePubkeyChanged(event: PubkeyChangedEvent): void {
112118
}
113119

114120
export function handleTextChanged(event: TextChangedEvent): void {
115-
let resolver = getOrCreateResolver(event.params.node, event.address);
121+
let resolver = getOrCreateResolver(event.params.node, event.address, false);
116122

117123
let key = event.params.key;
118124
if (resolver.texts == null) {
@@ -128,7 +134,7 @@ export function handleTextChanged(event: TextChangedEvent): void {
128134
}
129135

130136
let resolverEvent = new TextChanged(createEventID(event));
131-
resolverEvent.resolver = createResolverID(event.params.node, event.address);
137+
resolverEvent.resolver = resolver.id;
132138
resolverEvent.blockNumber = event.block.number.toI32();
133139
resolverEvent.transactionID = event.transaction.hash;
134140
resolverEvent.key = event.params.key;
@@ -138,7 +144,7 @@ export function handleTextChanged(event: TextChangedEvent): void {
138144
export function handleTextChangedWithValue(
139145
event: TextChangedWithValueEvent
140146
): void {
141-
let resolver = getOrCreateResolver(event.params.node, event.address);
147+
let resolver = getOrCreateResolver(event.params.node, event.address, false);
142148

143149
let key = event.params.key;
144150
if (resolver.texts == null) {
@@ -154,7 +160,7 @@ export function handleTextChangedWithValue(
154160
}
155161

156162
let resolverEvent = new TextChanged(createEventID(event));
157-
resolverEvent.resolver = createResolverID(event.params.node, event.address);
163+
resolverEvent.resolver = resolver.id;
158164
resolverEvent.blockNumber = event.block.number.toI32();
159165
resolverEvent.transactionID = event.transaction.hash;
160166
resolverEvent.key = event.params.key;
@@ -163,21 +169,23 @@ export function handleTextChangedWithValue(
163169
}
164170

165171
export function handleContentHashChanged(event: ContenthashChangedEvent): void {
166-
let resolver = getOrCreateResolver(event.params.node, event.address);
172+
let resolver = getOrCreateResolver(event.params.node, event.address, false);
167173
resolver.contentHash = event.params.hash;
168174
resolver.save();
169175

170176
let resolverEvent = new ContenthashChanged(createEventID(event));
171-
resolverEvent.resolver = createResolverID(event.params.node, event.address);
177+
resolverEvent.resolver = resolver.id;
172178
resolverEvent.blockNumber = event.block.number.toI32();
173179
resolverEvent.transactionID = event.transaction.hash;
174180
resolverEvent.hash = event.params.hash;
175181
resolverEvent.save();
176182
}
177183

178184
export function handleInterfaceChanged(event: InterfaceChangedEvent): void {
185+
const resolver = getOrCreateResolver(event.params.node, event.address, true);
186+
179187
let resolverEvent = new InterfaceChanged(createEventID(event));
180-
resolverEvent.resolver = createResolverID(event.params.node, event.address);
188+
resolverEvent.resolver = resolver.id;
181189
resolverEvent.blockNumber = event.block.number.toI32();
182190
resolverEvent.transactionID = event.transaction.hash;
183191
resolverEvent.interfaceID = event.params.interfaceID;
@@ -188,10 +196,12 @@ export function handleInterfaceChanged(event: InterfaceChangedEvent): void {
188196
export function handleAuthorisationChanged(
189197
event: AuthorisationChangedEvent
190198
): void {
199+
const resolver = getOrCreateResolver(event.params.node, event.address, true);
200+
191201
let resolverEvent = new AuthorisationChanged(createEventID(event));
192202
resolverEvent.blockNumber = event.block.number.toI32();
193203
resolverEvent.transactionID = event.transaction.hash;
194-
resolverEvent.resolver = createResolverID(event.params.node, event.address);
204+
resolverEvent.resolver = resolver.id;
195205
resolverEvent.owner = event.params.owner;
196206
resolverEvent.target = event.params.target;
197207
resolverEvent.isAuthorized = event.params.isAuthorised;
@@ -207,26 +217,33 @@ export function handleVersionChanged(event: VersionChangedEvent): void {
207217
resolverEvent.save();
208218

209219
let domain = Domain.load(event.params.node.toHexString());
210-
if (domain && domain.resolver === resolverEvent.resolver) {
220+
if (domain && domain.resolver == resolverEvent.resolver) {
211221
domain.resolvedAddress = null;
212222
domain.save();
213223
}
214224

215-
let resolver = getOrCreateResolver(event.params.node, event.address);
225+
let resolver = getOrCreateResolver(event.params.node, event.address, false);
216226
resolver.addr = null;
217227
resolver.contentHash = null;
218228
resolver.texts = null;
219229
resolver.coinTypes = null;
220230
resolver.save();
221231
}
222232

223-
function getOrCreateResolver(node: Bytes, address: Address): Resolver {
233+
function getOrCreateResolver(
234+
node: Bytes,
235+
address: Address,
236+
saveOnNew: boolean
237+
): Resolver {
224238
let id = createResolverID(node, address);
225239
let resolver = Resolver.load(id);
226-
if (resolver === null) {
240+
if (resolver == null) {
227241
resolver = new Resolver(id);
228242
resolver.domain = node.toHexString();
229243
resolver.address = address;
244+
if (saveOnNew) {
245+
resolver.save();
246+
}
230247
}
231248
return resolver as Resolver;
232249
}
@@ -238,7 +255,7 @@ function createEventID(event: ethereum.Event): string {
238255
.concat(event.logIndex.toString());
239256
}
240257

241-
function createResolverID(node: Bytes, resolver: Address): string {
258+
export function createResolverID(node: Bytes, resolver: Address): string {
242259
return resolver
243260
.toHexString()
244261
.concat("-")

src/utils.ts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,7 @@ export function byteArrayFromHex(s: string): ByteArray {
4141
}
4242

4343
export function uint256ToByteArray(i: BigInt): ByteArray {
44-
let hex = i
45-
.toHex()
46-
.slice(2)
47-
.padStart(64, "0");
44+
let hex = i.toHex().slice(2).padStart(64, "0");
4845
return byteArrayFromHex(hex);
4946
}
5047

@@ -68,18 +65,33 @@ export function createOrLoadDomain(node: string): Domain {
6865
return domain;
6966
}
7067

71-
export function checkValidLabel(name: string): boolean {
68+
export function checkValidLabel(name: string | null): boolean {
69+
if (name == null) {
70+
return false;
71+
}
72+
// for compiler
73+
name = name!;
7274
for (let i = 0; i < name.length; i++) {
73-
let c = name.charCodeAt(i);
74-
if (c === 0) {
75+
let charCode = name.charCodeAt(i);
76+
if (charCode === 0) {
77+
// 0 = null byte
7578
log.warning("Invalid label '{}' contained null byte. Skipping.", [name]);
7679
return false;
77-
} else if (c === 46) {
80+
} else if (charCode === 46) {
81+
// 46 = .
7882
log.warning(
7983
"Invalid label '{}' contained separator char '.'. Skipping.",
8084
[name]
8185
);
8286
return false;
87+
} else if (charCode === 91) {
88+
// 91 = [
89+
log.warning("Invalid label '{}' contained char '['. Skipping.", [name]);
90+
return false;
91+
} else if (charCode === 93) {
92+
// 93 = ]
93+
log.warning("Invalid label '{}' contained char ']'. Skipping.", [name]);
94+
return false;
8395
}
8496
}
8597

0 commit comments

Comments
 (0)