Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 34 additions & 7 deletions src/library/assistant/database/DatabaseHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ private static void inflateDB() {
System.out.println("Already loaded tables " + loadedTables);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(DatabaseHandler.class.getClass().getResourceAsStream("/resources/database/tables.xml"));
Document doc = dBuilder.parse(DatabaseHandler.class.getResourceAsStream("/resources/database/tables.xml"));
NodeList nList = doc.getElementsByTagName("table-entry");
for (int i = 0; i < nList.getLength(); i++) {
Node nNode = nList.item(i);
Expand Down Expand Up @@ -89,7 +89,7 @@ private static void createConnection() {
conn = DriverManager.getConnection(DB_URL);
}
catch (Exception e) {
JOptionPane.showMessageDialog(null, "Cant load database", "Database Error", JOptionPane.ERROR_MESSAGE);
LOGGER.log(Level.ERROR, "Cant load database", e);
System.exit(0);
}
}
Expand Down Expand Up @@ -123,21 +123,52 @@ public ResultSet execQuery(String query) {
return result;
}

public ResultSet execQuery(String query, Object... params) {
ResultSet result;
try {
PreparedStatement pstmt = conn.prepareStatement(query);
for (int i = 0; i < params.length; i++) {
pstmt.setObject(i + 1, params[i]);
}
result = pstmt.executeQuery();
}
catch (SQLException ex) {
System.out.println("Exception at execQuery:dataHandler" + ex.getLocalizedMessage());
return null;
}
return result;
}

public boolean execAction(String qu) {
try {
stmt = conn.createStatement();
stmt.execute(qu);
return true;
}
catch (SQLException ex) {
JOptionPane.showMessageDialog(null, "Error:" + ex.getMessage(), "Error Occured", JOptionPane.ERROR_MESSAGE);
LOGGER.log(Level.ERROR, "Error: " + ex.getMessage(), ex);
System.out.println("Exception at execQuery:dataHandler" + ex.getLocalizedMessage());
return false;
}
finally {
}
}

public boolean execAction(String qu, Object... params) {
try (PreparedStatement pstmt = conn.prepareStatement(qu)) {
for (int i = 0; i < params.length; i++) {
pstmt.setObject(i + 1, params[i]);
}
pstmt.execute();
return true;
}
catch (SQLException ex) {
LOGGER.log(Level.ERROR, "Error: " + ex.getMessage(), ex);
System.out.println("Exception at execQuery:dataHandler" + ex.getLocalizedMessage());
return false;
}
}

public boolean deleteBook(Book book) {
try {
String deleteStatement = "DELETE FROM BOOK WHERE ID = ?";
Expand Down Expand Up @@ -240,10 +271,6 @@ public boolean updateMember(MemberListController.Member member) {
return false;
}

public static void main(String[] args) throws Exception {
DatabaseHandler.getInstance();
}

public ObservableList<PieChart.Data> getBookGraphStatistics() {
ObservableList<PieChart.Data> data = FXCollections.observableArrayList();
try {
Expand Down
28 changes: 12 additions & 16 deletions src/library/assistant/ui/main/MainController.java
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,8 @@ private void loadMemberInfo(ActionEvent event) {
enableDisableGraph(false);

String id = memberIDInput.getText();
String qu = "SELECT * FROM MEMBER WHERE id = '" + id + "'";
ResultSet rs = databaseHandler.execQuery(qu);
String qu = "SELECT * FROM MEMBER WHERE id = ?";
ResultSet rs = databaseHandler.execQuery(qu, id);
Boolean flag = false;
try {
while (rs.next()) {
Expand Down Expand Up @@ -236,13 +236,10 @@ private void loadIssueOperation(ActionEvent event) {

JFXButton yesButton = new JFXButton("YES");
yesButton.addEventHandler(MouseEvent.MOUSE_CLICKED, (MouseEvent event1) -> {
String str = "INSERT INTO ISSUE(memberID,bookID) VALUES ("
+ "'" + memberID + "',"
+ "'" + bookID + "')";
String str2 = "UPDATE BOOK SET isAvail = false WHERE id = '" + bookID + "'";
System.out.println(str + " and " + str2);
String str = "INSERT INTO ISSUE(memberID,bookID) VALUES (?, ?)";
String str2 = "UPDATE BOOK SET isAvail = false WHERE id = ?";

if (databaseHandler.execAction(str) && databaseHandler.execAction(str2)) {
if (databaseHandler.execAction(str, memberID, bookID) && databaseHandler.execAction(str2, bookID)) {
JFXButton button = new JFXButton("Done!");
button.setOnAction((actionEvent) -> {
bookIDInput.requestFocus();
Expand Down Expand Up @@ -281,8 +278,8 @@ private void loadBookInfo2(ActionEvent event) {
+ "ON ISSUE.memberID=MEMBER.ID\n"
+ "LEFT JOIN BOOK\n"
+ "ON ISSUE.bookID=BOOK.ID\n"
+ "WHERE ISSUE.bookID='" + id + "'";
ResultSet rs = databaseHandler.execQuery(myQuery);
+ "WHERE ISSUE.bookID=?";
ResultSet rs = databaseHandler.execQuery(myQuery, id);
if (rs.next()) {
memberNameHolder.setText(rs.getString("name"));
memberContactHolder.setText(rs.getString("mobile"));
Expand Down Expand Up @@ -330,10 +327,10 @@ private void loadSubmissionOp(ActionEvent event) {
JFXButton yesButton = new JFXButton("YES, Please");
yesButton.addEventHandler(MouseEvent.MOUSE_CLICKED, (MouseEvent ev) -> {
String id = bookID.getText();
String ac1 = "DELETE FROM ISSUE WHERE BOOKID = '" + id + "'";
String ac2 = "UPDATE BOOK SET ISAVAIL = TRUE WHERE ID = '" + id + "'";
String ac1 = "DELETE FROM ISSUE WHERE BOOKID = ?";
String ac2 = "UPDATE BOOK SET ISAVAIL = TRUE WHERE ID = ?";

if (databaseHandler.execAction(ac1) && databaseHandler.execAction(ac2)) {
if (databaseHandler.execAction(ac1, id) && databaseHandler.execAction(ac2, id)) {
JFXButton btn = new JFXButton("Done!");
btn.setOnAction((actionEvent) -> {
bookID.requestFocus();
Expand Down Expand Up @@ -364,9 +361,8 @@ private void loadRenewOp(ActionEvent event) {
}
JFXButton yesButton = new JFXButton("YES, Please");
yesButton.addEventHandler(MouseEvent.MOUSE_CLICKED, (MouseEvent event1) -> {
String ac = "UPDATE ISSUE SET issueTime = CURRENT_TIMESTAMP, renew_count = renew_count+1 WHERE BOOKID = '" + bookID.getText() + "'";
System.out.println(ac);
if (databaseHandler.execAction(ac)) {
String ac = "UPDATE ISSUE SET issueTime = CURRENT_TIMESTAMP, renew_count = renew_count+1 WHERE BOOKID = ?";
if (databaseHandler.execAction(ac, bookID.getText())) {
JFXButton btn = new JFXButton("Alright!");
AlertMaker.showMaterialDialog(rootPane, rootAnchorPane, Arrays.asList(btn), "Book Has Been Renewed", null);
disableEnableControls(false);
Expand Down
52 changes: 52 additions & 0 deletions test/library/assistant/database/DatabaseHandlerExecTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package library.assistant.database;

import java.sql.ResultSet;
import org.junit.Test;
import static org.junit.Assert.*;

public class DatabaseHandlerExecTest {

@Test
public void testExecActionWithParameters() throws Exception {
DatabaseHandler handler = DatabaseHandler.getInstance();

// Ensure table exists
handler.execAction("CREATE TABLE TEST_TABLE (ID INT PRIMARY KEY, NAME VARCHAR(255))");

// Clear table
handler.execAction("DELETE FROM TEST_TABLE WHERE 1=1");

// Insert parameterized
boolean result = handler.execAction("INSERT INTO TEST_TABLE (ID, NAME) VALUES (?, ?)", 1, "TestName");
assertTrue("Insert should succeed", result);

// Select parameterized
ResultSet rs = handler.execQuery("SELECT NAME FROM TEST_TABLE WHERE ID = ?", 1);
assertNotNull("ResultSet should not be null", rs);
assertTrue("ResultSet should have result", rs.next());
assertEquals("Name should match", "TestName", rs.getString("NAME"));

// SQL Injection attempt in Delete
// First insert another row
handler.execAction("INSERT INTO TEST_TABLE (ID, NAME) VALUES (?, ?)", 2, "OtherName");

// Verify we have 2 rows
rs = handler.execQuery("SELECT COUNT(*) FROM TEST_TABLE");
rs.next();
assertEquals("Should have 2 rows", 2, rs.getInt(1));

// Attempt injection deletion
String payload = "' OR '1'='1";
// If this was raw string concatenation: DELETE FROM TEST_TABLE WHERE NAME = '' OR '1'='1'
// With parameters, it looks for NAME equal to literal "' OR '1'='1"
handler.execAction("DELETE FROM TEST_TABLE WHERE NAME = ?", payload);

// Verify we still have 2 rows (because no name matches the payload literal)
rs = handler.execQuery("SELECT COUNT(*) FROM TEST_TABLE");
rs.next();
assertEquals("Should still have 2 rows if injection failed", 2, rs.getInt(1));

// Clean up
handler.execAction("DROP TABLE TEST_TABLE");
}
}
7 changes: 7 additions & 0 deletions test/stubs/javafx/collections/FXCollections.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package javafx.collections;

public class FXCollections {
public static <E> ObservableList<E> observableArrayList() {
return new ObservableArrayList<E>();
}
}
6 changes: 6 additions & 0 deletions test/stubs/javafx/collections/ObservableArrayList.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package javafx.collections;

import java.util.ArrayList;

public class ObservableArrayList<E> extends ArrayList<E> implements ObservableList<E> {
}
6 changes: 6 additions & 0 deletions test/stubs/javafx/collections/ObservableList.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package javafx.collections;

import java.util.List;

public interface ObservableList<E> extends List<E> {
}
7 changes: 7 additions & 0 deletions test/stubs/javafx/scene/chart/PieChart.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package javafx.scene.chart;

public class PieChart {
public static class Data {
public Data(String name, double value) {}
}
}
22 changes: 22 additions & 0 deletions test/stubs/library/assistant/ui/listbook/BookListController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package library.assistant.ui.listbook;

public class BookListController {
public static class Book {
private String id;
private String title;
private String author;
private String publisher;

public Book(String id, String title, String author, String publisher) {
this.id = id;
this.title = title;
this.author = author;
this.publisher = publisher;
}

public String getId() { return id; }
public String getTitle() { return title; }
public String getAuthor() { return author; }
public String getPublisher() { return publisher; }
}
}