Skip to content

Commit 16ebe84

Browse files
committed
Maven publish & securities
- Escaped Table name (SQL Injection Security)
1 parent 9f37740 commit 16ebe84

11 files changed

Lines changed: 31 additions & 25 deletions

File tree

src/main/java/niwer/queryon/DataBase.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ public Table getTable(Class<? extends Table> tableClass) {
135135
*/
136136
public boolean tabExists(Table table) {
137137
this.reconnect(); // Ensure the connection is active before executing the query
138-
try (final var STATEMENT = this.sqlConnection.prepareStatement("SELECT name FROM sqlite_master WHERE type='table' AND name='" + table.name() + "';")) {
138+
try (final var STATEMENT = this.sqlConnection.prepareStatement("SELECT name FROM sqlite_master WHERE type='table' AND name=" + table.escapedName() + ";")) {
139139
return STATEMENT.executeQuery().next(); // If the query returns a result, the table exists
140140
} catch (SQLException e) {
141141
Console.log("Failed to check if table exists: " + e.getMessage()).type(QueryonLogTypes.SQL).error().container(QueryonEngine.LOGGER).send();
@@ -165,7 +165,7 @@ public boolean tabExists(Class<? extends Table> tableClass) {
165165
protected Table dropTable(Class<? extends Table> tableClass) {
166166
final Table table = this.getTable(tableClass);
167167
Console.log("Unregistering and dropping table " + table.name()).type(QueryonLogTypes.SQL).container(QueryonEngine.LOGGER).send();
168-
QueryManager.query(this, "DROP TABLE IF EXISTS " + table.name() + ";");
168+
QueryManager.query(this, "DROP TABLE IF EXISTS " + table.escapedName() + ";");
169169
REGISTERED_TABLES.remove(table);
170170
return table;
171171
}

src/main/java/niwer/queryon/queries/interaction/DeletionManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public final DeletionManager where(Expression expression) {
3232

3333
@Override
3434
protected String buildQuery() {
35-
final StringBuilder QUERY = new StringBuilder("DELETE FROM ").append(TABLE.name());
35+
final StringBuilder QUERY = new StringBuilder("DELETE FROM ").append(TABLE.escapedName());
3636

3737
/* Add WHERE condition */
3838
if (this.whereCondition != null) QUERY.append(" WHERE ").append(this.whereCondition);

src/main/java/niwer/queryon/queries/interaction/InsertionManager.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public final InsertionManager onConflictDoUpdate(UpdateManager updateManager) {
108108
protected String buildQuery() {
109109
final StringBuilder QUERY = new StringBuilder("INSERT");
110110
if (IGNORE_CONFLICTS) QUERY.append(" OR IGNORE");
111-
QUERY.append(" INTO ").append(TABLE.name()).append(" (").append(QueryonEngine.formatValues(COLUMNS)).append(") VALUES ");
111+
QUERY.append(" INTO ").append(TABLE.escapedName()).append(" (").append(QueryonEngine.formatValues(COLUMNS)).append(") VALUES ");
112112

113113
/* Add objects */
114114
final String VALUES_SQL = ROWS.stream()
@@ -121,7 +121,7 @@ protected String buildQuery() {
121121
case NONE -> { /* No conflict resolution, do nothing */ }
122122
case DO_NOTHING -> QUERY.append(" ON CONFLICT DO NOTHING");
123123
case DO_UPDATE -> {
124-
QUERY.append(" ON CONFLICT DO UPDATE SET ").append(doUpdateManager.buildQuery().replaceFirst("UPDATE " + TABLE.name() + " SET ", ""));
124+
QUERY.append(" ON CONFLICT DO UPDATE SET ").append(doUpdateManager.buildQuery().replaceFirst("UPDATE " + TABLE.escapedName() + " SET ", ""));
125125
}
126126
}
127127

src/main/java/niwer/queryon/queries/interaction/SelectionManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public final SelectionManager limit(int limit) {
9999
protected String buildQuery() {
100100
final StringBuilder QUERY = new StringBuilder("SELECT ");
101101
if (IS_DISTINCT) QUERY.append("DISTINCT ");
102-
QUERY.append(QueryonEngine.formatValues(COLUMNS)).append(" FROM ").append(TABLE.name());
102+
QUERY.append(QueryonEngine.formatValues(COLUMNS)).append(" FROM ").append(TABLE.escapedName());
103103

104104
/* Add where */
105105
if (whereCondition != null) QUERY.append(" WHERE ").append(whereCondition.toString());

src/main/java/niwer/queryon/queries/interaction/UpdateManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public final UpdateManager where(Expression expression) {
8585
@Override
8686
protected String buildQuery() {
8787
if (this.SETS.isEmpty()) throw new IllegalStateException("At least one column must be set for an update query.");
88-
final StringBuilder QUERY = new StringBuilder("UPDATE " + this.TABLE.name() + " SET " + String.join(", ", this.SETS));
88+
final StringBuilder QUERY = new StringBuilder("UPDATE " + this.TABLE.escapedName() + " SET " + String.join(", ", this.SETS));
8989

9090
/* Where condition */
9191
if (this.whereCondition != null) QUERY.append(" WHERE ").append(this.whereCondition.toString());

src/main/java/niwer/queryon/tables/Column.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ public String toString() {
222222

223223
protected final String constraintSQL() {
224224
if (foreignKeyReferenceTable == null || foreignKeyReferenceColumn == null) return null;
225-
return String.format("FOREIGN KEY (%s) REFERENCES %s(%s)%s", NAME, foreignKeyReferenceTable.name(), foreignKeyReferenceColumn, " ON DELETE " + foreignKeyDeleteAction);
225+
return String.format("FOREIGN KEY (%s) REFERENCES %s(%s)%s", NAME, foreignKeyReferenceTable.escapedName(), foreignKeyReferenceColumn, " ON DELETE " + foreignKeyDeleteAction);
226226
}
227227

228228
@Override public int hashCode() { return NAME.hashCode(); }

src/main/java/niwer/queryon/tables/Table.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,16 @@ public Table(DataBase db) {
3434
}
3535

3636
public abstract String name();
37+
38+
public final String escapedName() {
39+
return "'" + this.name() + "'";
40+
}
3741

3842
public final Set<Column> columns() { return Set.copyOf(COLUMNS); }
3943

4044
/**
4145
* Helper method to create a column definition for the table. It supports basic column types (INT, VARCHAR, BOOLEAN) and allows to set various constraints (NOT NULL, UNIQUE, AUTO_INCREMENT, PRIMARY KEY) and default values.
46+
*
4247
* @param name The name of the column
4348
* @param type The type of the column (INT, VARCHAR, BOOLEAN)
4449
* @return An SQLColumn instance that can be further configured with constraints and default values, and then added to a table definition using SQLTable.addColumn()
@@ -49,6 +54,7 @@ protected final static Column createColumn(DataBase db, String name, EnumColumnT
4954

5055
/**
5156
* Helper method to create a VARCHAR column definition for the table. It allows to specify the size of the VARCHAR column and supports the same constraints and default values as createColumn.
57+
*
5258
* @param name The name of the column
5359
* @param size The size of the VARCHAR column (maximum number of characters)
5460
* @return An SQLColumn instance that can be further configured with constraints and default values, and then added to a table definition using SQLTable.addColumn()

src/test/java/niwer/queryon/queries/interaction/DeletionManagerTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ class DeletionManagerTest {
2020

2121
final String DELETE = DeletionManager.delete(DB, TestUserTable.class)
2222
.buildQuery();
23-
assertEquals("DELETE FROM test_table", DELETE);
23+
assertEquals("DELETE FROM 'test_table'", DELETE);
2424

2525
final String DELETE_WHERE = DeletionManager.delete(DB, TestUserTable.class)
2626
.where(Expression.of("name").like("%A%"))
2727
.buildQuery();
28-
assertEquals("DELETE FROM test_table WHERE name LIKE '%A%'", DELETE_WHERE);
28+
assertEquals("DELETE FROM 'test_table' WHERE name LIKE '%A%'", DELETE_WHERE);
2929
}
3030

3131
@Test void testExecute(@TempDir File tempDir) {

src/test/java/niwer/queryon/queries/interaction/InsertionManagerTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,27 +24,27 @@ class InsertionManagerTest {
2424
.row(1, "Alice", 30)
2525
.rows(InsertionManager.of(2, "Bob", 25), InsertionManager.of(3, "Carol", 28))
2626
.buildQuery();
27-
assertEquals("INSERT INTO test_table (id, name, age) VALUES (1, 'Alice', 30), (2, 'Bob', 25), (3, 'Carol', 28)", INSERT);
27+
assertEquals("INSERT INTO 'test_table' (id, name, age) VALUES (1, 'Alice', 30), (2, 'Bob', 25), (3, 'Carol', 28)", INSERT);
2828

2929
final String INSERT_OR_IGNORE = InsertionManager.insertOrIgnore(DB, TestUserTable.class, "id", "name", "age")
3030
.row(1, "Alice", 30)
3131
.rows(InsertionManager.of(2, "Bob", 25), InsertionManager.of(3, "Carol", 28))
3232
.buildQuery();
33-
assertEquals("INSERT OR IGNORE INTO test_table (id, name, age) VALUES (1, 'Alice', 30), (2, 'Bob', 25), (3, 'Carol', 28)", INSERT_OR_IGNORE);
33+
assertEquals("INSERT OR IGNORE INTO 'test_table' (id, name, age) VALUES (1, 'Alice', 30), (2, 'Bob', 25), (3, 'Carol', 28)", INSERT_OR_IGNORE);
3434

3535
final String INSERT_DO_NOTHING = InsertionManager.insertOrIgnore(DB, TestUserTable.class, "id", "name", "age")
3636
.row(1, "Alice", 30)
3737
.onConflictDoNothing()
3838
.buildQuery();
39-
assertEquals("INSERT OR IGNORE INTO test_table (id, name, age) VALUES (1, 'Alice', 30) ON CONFLICT DO NOTHING", INSERT_DO_NOTHING);
39+
assertEquals("INSERT OR IGNORE INTO 'test_table' (id, name, age) VALUES (1, 'Alice', 30) ON CONFLICT DO NOTHING", INSERT_DO_NOTHING);
4040

4141
final String INSERT_DO_UPDATE = InsertionManager.insertOrIgnore(DB, TestUserTable.class, "id", "name", "age")
4242
.row(1, "Alice", 30)
4343
.onConflictDoUpdate(
4444
UpdateManager.update(DB, TestUserTable.class).set("name", "Alice Updated").where(Expression.of("id").isEqualTo(1))
4545
)
4646
.buildQuery();
47-
assertEquals("INSERT OR IGNORE INTO test_table (id, name, age) VALUES (1, 'Alice', 30) ON CONFLICT DO UPDATE SET name = 'Alice Updated' WHERE id = 1", INSERT_DO_UPDATE);
47+
assertEquals("INSERT OR IGNORE INTO 'test_table' (id, name, age) VALUES (1, 'Alice', 30) ON CONFLICT DO UPDATE SET name = 'Alice Updated' WHERE id = 1", INSERT_DO_UPDATE);
4848
}
4949

5050
@Test void testInsertionInvalidValues(@TempDir File tempDir) {

src/test/java/niwer/queryon/queries/interaction/SelectionManagerTest.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,36 +25,36 @@ class SelectionManagerTest {
2525

2626
final String SELECT_ALL = SelectionManager.select(DB, TestUserTable.class)
2727
.buildQuery();
28-
assertEquals("SELECT * FROM test_table", SELECT_ALL);
28+
assertEquals("SELECT * FROM 'test_table'", SELECT_ALL);
2929

3030
final String SELECT_DISTINCT = SelectionManager.selectDistinct(DB, TestUserTable.class)
3131
.buildQuery();
32-
assertEquals("SELECT DISTINCT * FROM test_table", SELECT_DISTINCT);
32+
assertEquals("SELECT DISTINCT * FROM 'test_table'", SELECT_DISTINCT);
3333

3434
final String SELECT_COLUMNS = SelectionManager.select(DB, TestUserTable.class, "id", "name")
3535
.buildQuery();
36-
assertEquals("SELECT id, name FROM test_table", SELECT_COLUMNS);
36+
assertEquals("SELECT id, name FROM 'test_table'", SELECT_COLUMNS);
3737

3838
final String SELECT_COLUMNS_WHERE = SelectionManager.select(DB, TestUserTable.class, "id", "name")
3939
.where(Expression.of("age").isGreaterThan(25))
4040
.limit(25)
4141
.buildQuery();
42-
assertEquals("SELECT id, name FROM test_table WHERE age > 25 LIMIT 25", SELECT_COLUMNS_WHERE);
42+
assertEquals("SELECT id, name FROM 'test_table' WHERE age > 25 LIMIT 25", SELECT_COLUMNS_WHERE);
4343

4444
final String SELECT_COLUMNS_ORDER_BY = SelectionManager.select(DB, TestUserTable.class, "id", "name")
4545
.orderBy("id", EnumOrder.ASC)
4646
.orderBy("email", EnumOrder.ASC)
4747
.orderBy("name", EnumOrder.DESC)
4848
.buildQuery();
49-
assertEquals("SELECT id, name FROM test_table ORDER BY id ASC, email ASC, name DESC", SELECT_COLUMNS_ORDER_BY);
49+
assertEquals("SELECT id, name FROM 'test_table' ORDER BY id ASC, email ASC, name DESC", SELECT_COLUMNS_ORDER_BY);
5050

5151
final String SELECT_COLUMNS_ORDER_BY_WHERE = SelectionManager.select(DB, TestUserTable.class, "id", "name")
5252
.where(Expression.of("age").isGreaterThan(25))
5353
.orderBy("id", EnumOrder.ASC)
5454
.orderBy("email", EnumOrder.ASC)
5555
.orderBy("name", EnumOrder.DESC)
5656
.buildQuery();
57-
assertEquals("SELECT id, name FROM test_table WHERE age > 25 ORDER BY id ASC, email ASC, name DESC", SELECT_COLUMNS_ORDER_BY_WHERE);
57+
assertEquals("SELECT id, name FROM 'test_table' WHERE age > 25 ORDER BY id ASC, email ASC, name DESC", SELECT_COLUMNS_ORDER_BY_WHERE);
5858
}
5959

6060
@Test void testSelectionInvalidValues(@TempDir File tempDir) {

0 commit comments

Comments
 (0)