589: Handle errors thrown when converting to utf-8 r=D4nte a=D4nte

`bytesToUtf8` replaced a previously used library. The previous library did not throw when failing to decode whereas `bytesToUtf8` does. Need to handle those errors.

Co-authored-by: Franck Royer <franck@status.im>
This commit is contained in:
status-bors-ng[bot] 2022-03-02 02:42:49 +00:00 committed by GitHub
commit acdd95b449
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 57 additions and 30 deletions

View File

@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
### Fixed
- Handle errors thrown by `bytesToUtf8`.
## [0.18.0] - 2022-02-24 ## [0.18.0] - 2022-02-24
### Changed ### Changed

View File

@ -19,11 +19,7 @@ export class Message {
return new Message(chatMsg, wakuMsg.timestamp); return new Message(chatMsg, wakuMsg.timestamp);
} }
} catch (e) { } catch (e) {
console.error( console.error("Failed to decode chat message", e);
"Failed to decode chat message",
wakuMsg.payloadAsUtf8,
e
);
} }
} }
return; return;

View File

@ -79,38 +79,45 @@ export class DnsNodeDiscovery {
subdomain: string, subdomain: string,
context: SearchContext context: SearchContext
): Promise<ENR | null> { ): Promise<ENR | null> {
const entry = await this._getTXTRecord(subdomain, context);
context.visits[subdomain] = true;
let next: string;
let branches: string[];
const entryType = getEntryType(entry);
try { try {
switch (entryType) { const entry = await this._getTXTRecord(subdomain, context);
case ENRTree.ROOT_PREFIX: context.visits[subdomain] = true;
next = ENRTree.parseAndVerifyRoot(entry, context.publicKey);
return await this._search(next, context); let next: string;
case ENRTree.BRANCH_PREFIX: let branches: string[];
branches = ENRTree.parseBranch(entry);
next = selectRandomPath(branches, context); const entryType = getEntryType(entry);
return await this._search(next, context); try {
case ENRTree.RECORD_PREFIX: switch (entryType) {
return ENR.decodeTxt(entry); case ENRTree.ROOT_PREFIX:
default: next = ENRTree.parseAndVerifyRoot(entry, context.publicKey);
return null; return await this._search(next, context);
case ENRTree.BRANCH_PREFIX:
branches = ENRTree.parseBranch(entry);
next = selectRandomPath(branches, context);
return await this._search(next, context);
case ENRTree.RECORD_PREFIX:
return ENR.decodeTxt(entry);
default:
return null;
}
} catch (error) {
dbg(
`Failed to search DNS tree ${entryType} at subdomain ${subdomain}: ${error}`
);
return null;
} }
} catch (error) { } catch (error) {
dbg( dbg(`Failed to retrieve TXT record at subdomain ${subdomain}: ${error}`);
`Failed to search DNS tree ${entryType} at subdomain ${subdomain}: ${error}`
);
return null; return null;
} }
} }
/** /**
* Retrieves the TXT record stored at a location from either * Retrieves the TXT record stored at a location from either
* this DNS tree cache or via DNS query * this DNS tree cache or via DNS query.
*
* @throws if the TXT Record contains non-UTF-8 values.
*/ */
private async _getTXTRecord( private async _getTXTRecord(
subdomain: string, subdomain: string,

View File

@ -31,6 +31,14 @@ export class DnsOverHttps implements DnsClient {
public endpoints: Endpoints = [cloudflare, google, opendns] public endpoints: Endpoints = [cloudflare, google, opendns]
) {} ) {}
/**
* Resolves a TXT record
*
* @param domain The domain name
*
* @throws if the result is provided in byte form which cannot be decoded
* to UTF-8
*/
async resolveTXT(domain: string): Promise<string[]> { async resolveTXT(domain: string): Promise<string[]> {
const response = await query({ const response = await query({
questions: [{ type: "TXT", name: domain }], questions: [{ type: "TXT", name: domain }],

View File

@ -1,4 +1,5 @@
import * as RLP from "@ethersproject/rlp"; import * as RLP from "@ethersproject/rlp";
import debug from "debug";
import { Multiaddr, protocols } from "multiaddr"; import { Multiaddr, protocols } from "multiaddr";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: No types available // @ts-ignore: No types available
@ -21,6 +22,8 @@ import { decodeMultiaddrs, encodeMultiaddrs } from "./multiaddrs_codec";
import { ENRKey, ENRValue, NodeId, SequenceNumber } from "./types"; import { ENRKey, ENRValue, NodeId, SequenceNumber } from "./types";
import * as v4 from "./v4"; import * as v4 from "./v4";
const dbg = debug("waku:enr");
export class ENR extends Map<ENRKey, ENRValue> { export class ENR extends Map<ENRKey, ENRValue> {
public static readonly RECORD_PREFIX = "enr:"; public static readonly RECORD_PREFIX = "enr:";
public seq: SequenceNumber; public seq: SequenceNumber;
@ -78,7 +81,11 @@ export class ENR extends Map<ENRKey, ENRValue> {
} }
const obj: Record<ENRKey, ENRValue> = {}; const obj: Record<ENRKey, ENRValue> = {};
for (let i = 0; i < kvs.length; i += 2) { for (let i = 0; i < kvs.length; i += 2) {
obj[bytesToUtf8(kvs[i])] = kvs[i + 1]; try {
obj[bytesToUtf8(kvs[i])] = kvs[i + 1];
} catch (e) {
dbg("Failed to decode ENR key to UTF-8, skipping it", kvs[i], e);
}
} }
const enr = new ENR(obj, BigInt("0x" + bytesToHex(seq)), signature); const enr = new ENR(obj, BigInt("0x" + bytesToHex(seq)), signature);

View File

@ -256,7 +256,12 @@ export class WakuMessage {
return ""; return "";
} }
return bytesToUtf8(this.proto.payload); try {
return bytesToUtf8(this.proto.payload);
} catch (e) {
dbg("Could not decode byte as UTF-8", e);
return "";
}
} }
get payload(): Uint8Array | undefined { get payload(): Uint8Array | undefined {