diff --git a/njord/db/insert.db b/njord/db/insert.db index daca69ac..8b5322ae 100644 Binary files a/njord/db/insert.db and b/njord/db/insert.db differ diff --git a/njord/src/mssql/insert.rs b/njord/src/mssql/insert.rs index 58e89f56..0b232e1c 100644 --- a/njord/src/mssql/insert.rs +++ b/njord/src/mssql/insert.rs @@ -165,8 +165,12 @@ fn generate_statement(table_row: &T, first_statement: bool) -> Result< debug!("Skipping AutoIncrementPrimaryKey field in SQL statement generation."); continue; } + + // Escape single quotes in the value + let escaped_value = value.replace("'", "''"); + columns_str.push_str(&format!("{}, ", column_name)); - values_str.push_str(&format!("'{}', ", value)); // Surround values with single quotes + values_str.push_str(&format!("'{}', ", escaped_value)); // Surround values with single quotes } // Sanitize table name from unwanted quotations or backslashes diff --git a/njord/src/mysql/insert.rs b/njord/src/mysql/insert.rs index 3d08a0a5..fba655c7 100644 --- a/njord/src/mysql/insert.rs +++ b/njord/src/mysql/insert.rs @@ -167,8 +167,12 @@ fn generate_statement(table_row: &T, first_statement: bool) -> Result< debug!("Skipping AutoIncrementPrimaryKey field in SQL statement generation."); continue; } + + // Escape single quotes in the value + let escaped_value = value.replace("'", "''"); + columns_str.push_str(&format!("{}, ", column_name)); - values_str.push_str(&format!("'{}', ", value)); // Surround values with single quotes + values_str.push_str(&format!("'{}', ", escaped_value)); // Surround values with single quotes } // Sanitize table name from unwanted quotations or backslashes diff --git a/njord/src/oracle/insert.rs b/njord/src/oracle/insert.rs index 67dabe94..0ccf6be0 100644 --- a/njord/src/oracle/insert.rs +++ b/njord/src/oracle/insert.rs @@ -170,8 +170,12 @@ fn generate_statement(table_row: &T, first_statement: bool) -> Result< debug!("Skipping AutoIncrementPrimaryKey field in SQL statement generation."); continue; } + + // Escape single quotes in the value + let escaped_value = value.replace("'", "''"); + columns_str.push_str(&format!("{}, ", column_name)); - values_str.push_str(&format!("'{}', ", value)); // Surround values with single quotes + values_str.push_str(&format!("'{}', ", escaped_value)); // Surround values with single quotes } // Sanitize table name from unwanted quotations or backslashes diff --git a/njord/src/sqlite/insert.rs b/njord/src/sqlite/insert.rs index a2158a21..2b9ea898 100644 --- a/njord/src/sqlite/insert.rs +++ b/njord/src/sqlite/insert.rs @@ -161,8 +161,12 @@ fn generate_statement(table_row: &T, first_statement: bool) -> Result< debug!("Skipping AutoIncrementPrimaryKey field in SQL statement generation."); continue; } + + // Escape single quotes in the value + let escaped_value = value.replace("'", "''"); + columns_str.push_str(&format!("{}, ", column_name)); - values_str.push_str(&format!("'{}', ", value)); // Surround values with single quotes + values_str.push_str(&format!("'{}', ", escaped_value)); // Surround values with single quotes } // Sanitize table name from unwanted quotations or backslashes diff --git a/njord/tests/mssql/insert_test.rs b/njord/tests/mssql/insert_test.rs index d8909376..7e599cb1 100644 --- a/njord/tests/mssql/insert_test.rs +++ b/njord/tests/mssql/insert_test.rs @@ -26,3 +26,27 @@ async fn insert_row() { } } } + +#[tokio::test] +async fn insert_row_with_single_quotes() { + let connection_string = + "jdbc:sqlserver://localhost;encrypt=true;username=sa;password=Njord_passw0rd;databaseName=NjordDatabase;"; + let mut conn = mssql::open(connection_string).await; + + let table_row: User = User { + id: AutoIncrementPrimaryKey::default(), + username: "quote_user".to_string(), + email: "quote_user@example.com".to_string(), + address: "Some Random 'Address' 1".to_string(), + }; + + match conn { + Ok(ref mut c) => { + let result = mssql::insert(c, vec![table_row]).await; + assert!(result.is_ok()); + } + Err(e) => { + panic!("Failed to INSERT: {:?}", e); + } + } +} diff --git a/njord/tests/mysql/insert_test.rs b/njord/tests/mysql/insert_test.rs index a4a9ccc4..f6fde5de 100644 --- a/njord/tests/mysql/insert_test.rs +++ b/njord/tests/mysql/insert_test.rs @@ -25,3 +25,26 @@ fn insert_row() { } } } + +#[test] +fn insert_row_with_single_quotes() { + let url = "mysql://njord_user:njord_password@localhost:3306/njord_db"; + let mut conn = mysql::open(url); + + let table_row: User = User { + id: AutoIncrementPrimaryKey::default(), + username: "quote_user".to_string(), + email: "quote_user@example.com".to_string(), + address: "Some Random 'Address' 1".to_string(), + }; + + match conn { + Ok(ref mut c) => { + let result = mysql::insert(c, vec![table_row]); + assert!(result.is_ok()); + } + Err(e) => { + panic!("Failed to INSERT: {:?}", e); + } + } +} diff --git a/njord/tests/oracle/insert_test.rs b/njord/tests/oracle/insert_test.rs index aeeb7106..071ac6c0 100644 --- a/njord/tests/oracle/insert_test.rs +++ b/njord/tests/oracle/insert_test.rs @@ -25,3 +25,26 @@ fn insert_row() { } } } + +#[test] +fn insert_row_with_single_quotes() { + let connection_string = "//localhost:1521/FREEPDB1"; + let mut conn = oracle::open("njord_user", "njord_password", connection_string); + + let table_row: User = User { + id: AutoIncrementPrimaryKey::default(), + username: "quote_user".to_string(), + email: "quote_user@example.com".to_string(), + address: "Some Random 'Address' 1".to_string(), + }; + + match conn { + Ok(ref mut c) => { + let result = oracle::insert(c, vec![table_row]); + assert!(result.is_ok()); + } + Err(e) => { + panic!("Failed to INSERT: {:?}", e); + } + } +} diff --git a/njord/tests/sqlite/insert_test.rs b/njord/tests/sqlite/insert_test.rs index 130d5340..5abdbf3f 100644 --- a/njord/tests/sqlite/insert_test.rs +++ b/njord/tests/sqlite/insert_test.rs @@ -68,3 +68,27 @@ fn insert_with_sub_query() { } } } + +#[test] +fn insert_row_with_single_quotes() { + let db_relative_path = "./db/insert.db"; + let db_path = Path::new(&db_relative_path); + let mut conn = sqlite::open(db_path); + + let table_row: User = User { + id: AutoIncrementPrimaryKey::default(), + username: "quote_user".to_string(), + email: "quote_user@example.com".to_string(), + address: "Some Random 'Address' 1".to_string(), + }; + + match conn { + Ok(ref mut c) => { + let result = sqlite::insert(c, vec![table_row]); + assert!(result.is_ok()); + } + Err(e) => { + panic!("Failed to INSERT: {:?}", e); + } + } +}