From 362335913db6cc52512b7d195338f01b1bb703e5 Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sat, 19 Mar 2022 18:55:19 +0000 Subject: [PATCH] Fixed infinite loop in name rebuilding. If an account is renamed and then at some point renamed back to one of the original names, it confused the names rebuilding code. The current solution is to track the linked names that have already been rebuilt, and then break out of the loop once a name is encountered a second time. --- .../NamesDatabaseIntegrityCheck.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/qortal/controller/repository/NamesDatabaseIntegrityCheck.java b/src/main/java/org/qortal/controller/repository/NamesDatabaseIntegrityCheck.java index 11ae2da0..77cf0281 100644 --- a/src/main/java/org/qortal/controller/repository/NamesDatabaseIntegrityCheck.java +++ b/src/main/java/org/qortal/controller/repository/NamesDatabaseIntegrityCheck.java @@ -29,6 +29,15 @@ public class NamesDatabaseIntegrityCheck { private List nameTransactions = new ArrayList<>(); public int rebuildName(String name, Repository repository) { + return this.rebuildName(name, repository, null); + } + + public int rebuildName(String name, Repository repository, List referenceNames) { + // "referenceNames" tracks the linked names that have already been rebuilt, to prevent circular dependencies + if (referenceNames == null) { + referenceNames = new ArrayList<>(); + } + int modificationCount = 0; try { List transactions = this.fetchAllTransactionsInvolvingName(name, repository); @@ -56,7 +65,14 @@ public class NamesDatabaseIntegrityCheck { if (Objects.equals(updateNameTransactionData.getNewName(), name) && !Objects.equals(updateNameTransactionData.getName(), updateNameTransactionData.getNewName())) { // This renames an existing name, so we need to process that instead - this.rebuildName(updateNameTransactionData.getName(), repository); + + if (!referenceNames.contains(name)) { + referenceNames.add(name); + this.rebuildName(updateNameTransactionData.getName(), repository, referenceNames); + } + else { + // We've already processed this name so there's nothing more to do + } } else { Name nameObj = new Name(repository, name);