From e327dffb15f4248b0cdad6eec099b0b57bbd8109 Mon Sep 17 00:00:00 2001 From: Stephen Paul Weber Date: Tue, 29 Oct 2024 00:07:49 -0500 Subject: [PATCH] Bytes.ofHex can fail If the input is odd number of elements or not hex alphabet --- snikket/Client.hx | 44 +++++++++++++++++++++++--------------------- snikket/Hash.hx | 8 ++++++-- 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/snikket/Client.hx b/snikket/Client.hx index 7726aeb..880c0b2 100644 --- a/snikket/Client.hx +++ b/snikket/Client.hx @@ -253,7 +253,7 @@ class Client extends EventEmitter { if (pubsubEvent != null && pubsubEvent.getFrom() != null && pubsubEvent.getNode() == "urn:xmpp:avatar:metadata" && pubsubEvent.getItems().length > 0) { final item = pubsubEvent.getItems()[0]; final avatarSha1Hex = pubsubEvent.getItems()[0].attr.get("id"); - final avatarSha1 = Bytes.ofHex(avatarSha1Hex).getData(); + final avatarSha1 = Hash.fromHex("sha-1", avatarSha1Hex)?.hash; final metadata = item.getChild("metadata", "urn:xmpp:avatar:metadata"); var mime = "image/png"; if (metadata != null) { @@ -262,26 +262,28 @@ class Client extends EventEmitter { mime = info.attr.get("type"); } } - final chat = this.getDirectChat(JID.parse(pubsubEvent.getFrom()).asBare().asString(), false); - chat.setAvatarSha1(avatarSha1); - persistence.storeChat(accountId(), chat); - persistence.hasMedia("sha-1", avatarSha1, (has) -> { - if (has) { - this.trigger("chats/update", [chat]); - } else { - final pubsubGet = new PubsubGet(pubsubEvent.getFrom(), "urn:xmpp:avatar:data", avatarSha1Hex); - pubsubGet.onFinished(() -> { - final item = pubsubGet.getResult()[0]; - if (item == null) return; - final dataNode = item.getChild("data", "urn:xmpp:avatar:data"); - if (dataNode == null) return; - persistence.storeMedia(mime, Base64.decode(StringTools.replace(dataNode.getText(), "\n", "")).getData(), () -> { - this.trigger("chats/update", [chat]); + if (avatarSha1 != null) { + final chat = this.getDirectChat(JID.parse(pubsubEvent.getFrom()).asBare().asString(), false); + chat.setAvatarSha1(avatarSha1); + persistence.storeChat(accountId(), chat); + persistence.hasMedia("sha-1", avatarSha1, (has) -> { + if (has) { + this.trigger("chats/update", [chat]); + } else { + final pubsubGet = new PubsubGet(pubsubEvent.getFrom(), "urn:xmpp:avatar:data", avatarSha1Hex); + pubsubGet.onFinished(() -> { + final item = pubsubGet.getResult()[0]; + if (item == null) return; + final dataNode = item.getChild("data", "urn:xmpp:avatar:data"); + if (dataNode == null) return; + persistence.storeMedia(mime, Base64.decode(StringTools.replace(dataNode.getText(), "\n", "")).getData(), () -> { + this.trigger("chats/update", [chat]); + }); }); - }); - sendQuery(pubsubGet); - } - }); + sendQuery(pubsubGet); + } + }); + } } if (pubsubEvent != null && pubsubEvent.getFrom() != null && JID.parse(pubsubEvent.getFrom()).asBare().asString() == accountId() && pubsubEvent.getNode() == "http://jabber.org/protocol/nick" && pubsubEvent.getItems().length > 0) { @@ -439,7 +441,7 @@ class Client extends EventEmitter { if (from.isBare()) { final avatarSha1Hex = stanza.findText("{vcard-temp:x:update}x/photo#"); if (avatarSha1Hex != null) { - final avatarSha1 = Bytes.ofHex(avatarSha1Hex).getData(); + final avatarSha1 = Hash.fromHex("sha-1", avatarSha1Hex)?.hash; chat.setAvatarSha1(avatarSha1); persistence.storeChat(accountId(), chat); persistence.hasMedia("sha-1", avatarSha1, (has) -> { diff --git a/snikket/Hash.hx b/snikket/Hash.hx index c0f15b7..71c1f1a 100644 --- a/snikket/Hash.hx +++ b/snikket/Hash.hx @@ -28,8 +28,12 @@ class Hash { this.hash = hash; } - public static function fromHex(algorithm: String, hash: String) { - return new Hash(algorithm, Bytes.ofHex(hash).getData()); + public static function fromHex(algorithm: String, hash: String): Null { + try { + return new Hash(algorithm, Bytes.ofHex(hash).getData()); + } catch (e) { + return null; + } } public static function fromUri(uri: String): Null {