From 1715f35341139436a666093a9d7f7e30c69dfbf0 Mon Sep 17 00:00:00 2001 From: NotMyFault Date: Wed, 22 Dec 2021 13:10:04 +0100 Subject: [PATCH] refactor: Do prepared statements properly - Update TextureUtil client jar to 1.18.1 - Limit the update checker to our domain --- .../core/database/RollbackDatabase.java | 76 ++++++------------- .../core/util/TextureUtil.java | 8 +- .../core/util/UpdateNotification.java | 2 + 3 files changed, 29 insertions(+), 57 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/database/RollbackDatabase.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/database/RollbackDatabase.java index 209f93e3f..9dd001687 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/database/RollbackDatabase.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/database/RollbackDatabase.java @@ -11,7 +11,6 @@ import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.world.World; import org.apache.logging.log4j.Logger; -import org.intellij.lang.annotations.Language; import javax.annotation.Nonnull; import java.io.File; @@ -37,35 +36,8 @@ public class RollbackDatabase extends AsyncNotifyQueue { private final String prefix; private final File dbLocation; private final World world; - private Connection connection; - - @Language("SQLite") - private String createTable = "CREATE TABLE IF NOT EXISTS `{0}edits` (`player` BLOB(16) NOT NULL,`id` INT NOT NULL, `time` INT NOT NULL,`x1` INT NOT NULL,`x2` INT NOT NULL,`z1` INT NOT NULL,`z2` INT NOT NULL,`y1` INT NOT NULL, `y2` INT NOT NULL, `size` INT NOT NULL, `command` VARCHAR, PRIMARY KEY (player, id))"; - @Language("SQLite") - private String updateTable1 = "ALTER TABLE `{0}edits` ADD COLUMN `command` VARCHAR"; - @Language("SQLite") - private String updateTable2 = "alter table `{0}edits` add size int default 0 not null"; - @Language("SQLite") - private String insertEdit = "INSERT OR REPLACE INTO `{0}edits` (`player`,`id`,`time`,`x1`,`x2`,`z1`,`z2`,`y1`,`y2`,`command`,`size`) VALUES(?,?,?,?,?,?,?,?,?,?,?)"; - @Language("SQLite") - private String purge = "DELETE FROM `{0}edits` WHERE `time`? AND `x2`>=? AND `x1`<=? AND `z2`>=? AND `z1`<=? AND `y2`>=? AND `y1`<=? AND `player`=? ORDER BY `time` DESC, `id` DESC"; - @Language("SQLite") - private String getEditsUserAsc = "SELECT * FROM `{0}edits` WHERE `time`>? AND `x2`>=? AND `x1`<=? AND `z2`>=? AND `z1`<=? AND `y2`>=? AND `y1`<=? AND `player`=? ORDER BY `time` ASC, `id` ASC"; - @Language("SQLite") - private String getEdits = "SELECT * FROM `{0}edits` WHERE `time`>? AND `x2`>=? AND `x1`<=? AND `z2`>=? AND `z1`<=? AND `y2`>=? AND `y1`<=? ORDER BY `time` DESC, `id` DESC"; - @Language("SQLite") - private String getEditsAsc = "SELECT * FROM `{0}edits` WHERE `time`>? AND `x2`>=? AND `x1`<=? AND `z2`>=? AND `z1`<=? AND `y2`>=? AND `y1`<=? ORDER BY `time` , `id` "; - @Language("SQLite") - private String getEditUser = "SELECT * FROM `{0}edits` WHERE `player`=? AND `id`=?"; - - @Language("SQLite") - private String deleteEditsUser = "DELETE FROM `{0}edits` WHERE `player`=? AND `time`>? AND `x2`>=? AND `x1`<=? AND `y2`>=? AND `y1`<=? AND `z2`>=? AND `z1`<=?"; - @Language("SQLite") - private String deleteEditUser = "DELETE FROM `{0}edits` WHERE `player`=? AND `id`=?"; - private final ConcurrentLinkedQueue historyChanges = new ConcurrentLinkedQueue<>(); + private Connection connection; RollbackDatabase(World world) throws SQLException, ClassNotFoundException { super((t, e) -> e.printStackTrace()); @@ -77,20 +49,6 @@ public class RollbackDatabase extends AsyncNotifyQueue { ); connection = openConnection(); - // update vars - createTable = createTable.replace("{0}", prefix); - updateTable1 = updateTable1.replace("{0}", prefix); - updateTable2 = updateTable2.replace("{0}", prefix); - insertEdit = insertEdit.replace("{0}", prefix); - purge = purge.replace("{0}", prefix); - getEditsUser = getEditsUser.replace("{0}", prefix); - getEditsUserAsc = getEditsUserAsc.replace("{0}", prefix); - getEdits = getEdits.replace("{0}", prefix); - getEditsAsc = getEditsAsc.replace("{0}", prefix); - getEditUser = getEditUser.replace("{0}", prefix); - deleteEditsUser = deleteEditsUser.replace("{0}", prefix); - deleteEditUser = deleteEditUser.replace("{0}", prefix); - try { init().get(); purge((int) TimeUnit.DAYS.toSeconds(Settings.IMP.HISTORY.DELETE_AFTER_DAYS)); @@ -105,14 +63,17 @@ public class RollbackDatabase extends AsyncNotifyQueue { public Future init() { return call(() -> { - try (PreparedStatement stmt = connection.prepareStatement(createTable)) { + try (PreparedStatement stmt = connection.prepareStatement("CREATE TABLE IF NOT EXISTS`" + this.prefix + + "edits` (`player` BLOB(16) NOT NULL,`id` INT NOT NULL, `time` INT NOT NULL,`x1`" + + "INT NOT NULL,`x2` INT NOT NULL,`z1` INT NOT NULL,`z2` INT NOT NULL,`y1`" + + "INT NOT NULL, `y2` INT NOT NULL, `size` INT NOT NULL, `command` VARCHAR, PRIMARY KEY (player, id))")) { stmt.executeUpdate(); } - try (PreparedStatement stmt = connection.prepareStatement(updateTable1)) { + try (PreparedStatement stmt = connection.prepareStatement("ALTER TABLE`" + this.prefix + "edits` ADD COLUMN `command` VARCHAR")) { stmt.executeUpdate(); } catch (SQLException ignored) { } // Already updated - try (PreparedStatement stmt = connection.prepareStatement(updateTable2)) { + try (PreparedStatement stmt = connection.prepareStatement("ALTER TABLE`" + this.prefix + "edits` ADD SIZE INT DEFAULT 0 NOT NULL")) { stmt.executeUpdate(); } catch (SQLException ignored) { } // Already updated @@ -122,7 +83,7 @@ public class RollbackDatabase extends AsyncNotifyQueue { public Future delete(UUID uuid, int id) { return call(() -> { - try (PreparedStatement stmt = connection.prepareStatement(deleteEditUser)) { + try (PreparedStatement stmt = connection.prepareStatement("DELETE FROM`" + this.prefix + "edits` WHERE `player`=? AND `id`=?")) { stmt.setBytes(1, toBytes(uuid)); stmt.setInt(2, id); return stmt.executeUpdate(); @@ -132,7 +93,8 @@ public class RollbackDatabase extends AsyncNotifyQueue { public Future getEdit(@Nonnull UUID uuid, int id) { return call(() -> { - try (PreparedStatement stmt = connection.prepareStatement(getEditUser)) { + try (PreparedStatement stmt = connection.prepareStatement("SELECT * FROM`" + this.prefix + + "edits` WHERE `player`=? AND `id`=?")) { stmt.setBytes(1, toBytes(uuid)); stmt.setInt(2, id); ResultSet result = stmt.executeQuery(); @@ -172,7 +134,7 @@ public class RollbackDatabase extends AsyncNotifyQueue { long now = System.currentTimeMillis() / 1000; final int then = (int) (now - diff); return call(() -> { - try (PreparedStatement stmt = connection.prepareStatement(purge)) { + try (PreparedStatement stmt = connection.prepareStatement("DELETE FROM`" + this.prefix + "edits` WHERE `time` future = call(() -> { try { int count = 0; - String stmtStr = ascending ? uuid == null ? getEditsAsc : getEditsUserAsc : - uuid == null ? getEdits : getEditsUser; + String stmtStr = ascending ? uuid == null ? "SELECT * FROM`" + this.prefix + "edits` WHERE `time`>? AND `x2`>=? AND" + + " `x1`<=? AND `z2`>=? AND `z1`<=? AND `y2`>=? AND `y1`<=? ORDER BY `time` , `id`" : + "SELECT * FROM`" + this.prefix + "edits` WHERE `time`>? AND" + + " `x2`>=? AND `x1`<=? AND `z2`>=? AND `z1`<=? AND `y2`>=? AND `y1`<=? AND `player`=? ORDER BY `time` ASC, `id` ASC" : + uuid == null ? "SELECT * FROM`" + this.prefix + "edits` WHERE `time`>? AND `x2`>=? AND `x1`<=? AND `z2`>=? " + + "AND `z1`<=? AND `y2`>=? AND `y1`<=? ORDER BY `time` DESC, `id` DESC" : + "SELECT * FROM`" + this.prefix + "edits` WHERE `time`>? AND `x2`>=? AND `x1`<=? AND" + + " `z2`>=? AND `z1`<=? AND `y2`>=? AND `y1`<=? AND `player`=? ORDER BY `time` DESC, `id` DESC"; try (PreparedStatement stmt = connection.prepareStatement(stmtStr)) { stmt.setInt(1, (int) (minTime / 1000)); stmt.setInt(2, pos1.getBlockX()); @@ -221,7 +189,8 @@ public class RollbackDatabase extends AsyncNotifyQueue { } while (result.next()); } if (delete && uuid != null) { - try (PreparedStatement stmt = connection.prepareStatement(deleteEditsUser)) { + try (PreparedStatement stmt = connection.prepareStatement("DELETE FROM`" + this.prefix + + "edits` WHERE `player`=? AND `time`>? AND `x2`>=? AND `x1`<=? AND `y2`>=? AND `y1`<=? AND `z2`>=? AND `z1`<=?")) { stmt.setInt(1, (int) (minTime / 1000)); stmt.setInt(2, pos1.getBlockX()); stmt.setInt(3, pos2.getBlockX()); @@ -267,7 +236,8 @@ public class RollbackDatabase extends AsyncNotifyQueue { RollbackOptimizedHistory[] copy = IntStream.range(0, size) .mapToObj(i -> historyChanges.poll()).toArray(RollbackOptimizedHistory[]::new); - try (PreparedStatement stmt = connection.prepareStatement(insertEdit)) { + try (PreparedStatement stmt = connection.prepareStatement("INSERT OR REPLACE INTO`" + this.prefix + "edits`" + + " (`player`,`id`,`time`,`x1`,`x2`,`z1`,`z2`,`y1`,`y2`,`command`,`size`) VALUES(?,?,?,?,?,?,?,?,?,?,?)")) { // `player`,`id`,`time`,`x1`,`x2`,`z1`,`z2`,`y1`,`y2`,`command`,`size`) VALUES(?,?,?,?,?,?,?,?,?,?,?)" for (RollbackOptimizedHistory change : copy) { UUID uuid = change.getUUID(); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/TextureUtil.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/TextureUtil.java index 59078cba5..d1e9a17a9 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/TextureUtil.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/TextureUtil.java @@ -353,10 +353,10 @@ public class TextureUtil implements TextureHolder { LOGGER.info("Downloading asset jar from Mojang, please wait..."); new File(Fawe.imp().getDirectory() + "/" + Settings.IMP.PATHS.TEXTURES + "/").mkdirs(); try (BufferedInputStream in = new BufferedInputStream( - new URL("https://launcher.mojang.com/v1/objects/d49eb6caed53d23927648c97451503442f9e26fd/client.jar") + new URL("https://launcher.mojang.com/v1/objects/7e46fb47609401970e2818989fa584fd467cd036/client.jar") .openStream()); FileOutputStream fileOutputStream = new FileOutputStream( - Fawe.imp().getDirectory() + "/" + Settings.IMP.PATHS.TEXTURES + "/1.18.jar")) { + Fawe.imp().getDirectory() + "/" + Settings.IMP.PATHS.TEXTURES + "/1.18.1.jar")) { byte[] dataBuffer = new byte[1024]; int bytesRead; while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) { @@ -810,10 +810,10 @@ public class TextureUtil implements TextureHolder { new File(Fawe.imp().getDirectory() + "/" + Settings.IMP.PATHS.TEXTURES + "/") .mkdirs(); try (BufferedInputStream in = new BufferedInputStream( - new URL("https://launcher.mojang.com/v1/objects/d49eb6caed53d23927648c97451503442f9e26fd/client.jar") + new URL("https://launcher.mojang.com/v1/objects/7e46fb47609401970e2818989fa584fd467cd036/client.jar") .openStream()); FileOutputStream fileOutputStream = new FileOutputStream( - Fawe.imp().getDirectory() + "/" + Settings.IMP.PATHS.TEXTURES + "/1.18.jar")) { + Fawe.imp().getDirectory() + "/" + Settings.IMP.PATHS.TEXTURES + "/1.18.1.jar")) { byte[] dataBuffer = new byte[1024]; int bytesRead; while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/UpdateNotification.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/UpdateNotification.java index d680137e9..30c14c92f 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/UpdateNotification.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/UpdateNotification.java @@ -11,6 +11,7 @@ import com.sk89q.worldedit.util.formatting.text.event.ClickEvent; import org.apache.logging.log4j.Logger; import org.w3c.dom.Document; +import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import java.net.URL; @@ -29,6 +30,7 @@ public class UpdateNotification { if (Settings.IMP.ENABLED_COMPONENTS.UPDATE_NOTIFICATIONS) { try { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(new URL("https://ci.athion.net/job/FastAsyncWorldEdit/api/xml/").openStream()); faweVersion = doc.getElementsByTagName("lastSuccessfulBuild").item(0).getFirstChild().getTextContent();