fix(account): break a-tag cycle in computeRelayListToBroadcast
An addressable event whose `a` tags reach itself — directly (self-mention) or via any cycle of other in-cache events — would recurse unbounded through `AddressHintProvider` / `EventHintProvider` branches and crash with StackOverflowError on publish (`signAndComputeBroadcast` → `computeRelayListToBroadcast`). The crash was reproducible on the device when publishing a kind-1 note that referenced an article whose own event carries a self `a` tag (e.g. YakiHonne-authored long-form posts include their own naddr in their `a` tags).
This commit is contained in:
@@ -965,7 +965,15 @@ class Account(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun computeRelayListToBroadcast(event: Event): Set<NormalizedRelayUrl> {
|
fun computeRelayListToBroadcast(event: Event): Set<NormalizedRelayUrl> = computeRelayListToBroadcast(event, mutableSetOf())
|
||||||
|
|
||||||
|
private fun computeRelayListToBroadcast(
|
||||||
|
event: Event,
|
||||||
|
visited: MutableSet<HexKey>,
|
||||||
|
): Set<NormalizedRelayUrl> {
|
||||||
|
// a-tagged events can form cycles; without this the two recursive descents stack-overflow.
|
||||||
|
if (!visited.add(event.id)) return emptySet()
|
||||||
|
|
||||||
if (event is GiftWrapEvent) {
|
if (event is GiftWrapEvent) {
|
||||||
val receiver = event.recipientPubKey()
|
val receiver = event.recipientPubKey()
|
||||||
return if (receiver != null) {
|
return if (receiver != null) {
|
||||||
@@ -1044,7 +1052,7 @@ class Account(
|
|||||||
}
|
}
|
||||||
|
|
||||||
linkedNote.event?.let { linkedEvent ->
|
linkedNote.event?.let { linkedEvent ->
|
||||||
relayList.addAll(computeRelayListToBroadcast(linkedEvent))
|
relayList.addAll(computeRelayListToBroadcast(linkedEvent, visited))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1065,7 +1073,7 @@ class Account(
|
|||||||
}
|
}
|
||||||
|
|
||||||
linkedNote.event?.let { linkedEvent ->
|
linkedNote.event?.let { linkedEvent ->
|
||||||
relayList.addAll(computeRelayListToBroadcast(linkedEvent))
|
relayList.addAll(computeRelayListToBroadcast(linkedEvent, visited))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user