You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by sw...@apache.org on 2025/11/23 05:53:30 UTC

(logging-log4cxx) branch sql_statement_validation created (now fe56f172)

This is an automated email from the ASF dual-hosted git repository.

swebb2066 pushed a change to branch sql_statement_validation
in repository https://gitbox.apache.org/repos/asf/logging-log4cxx.git


      at fe56f172 Require the SQL used by ODBCAppender to be a single statement

This branch includes the following new commits:

     new fe56f172 Require the SQL used by ODBCAppender to be a single statement

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(logging-log4cxx) 01/01: Require the SQL used by ODBCAppender to be a single statement

Posted by sw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

swebb2066 pushed a commit to branch sql_statement_validation
in repository https://gitbox.apache.org/repos/asf/logging-log4cxx.git

commit fe56f172bd74d697951a8cbcfa7fc446a663e6ab
Author: Stephen Webb <sw...@gmail.com>
AuthorDate: Sun Nov 23 16:52:11 2025 +1100

    Require the SQL used by ODBCAppender to be a single statement
---
 src/main/cpp/odbcappender.cpp            | 20 ++++++++++++++++++++
 src/test/cpp/db/odbcappendertestcase.cpp |  9 ++++++---
 2 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/src/main/cpp/odbcappender.cpp b/src/main/cpp/odbcappender.cpp
index 20ca4d55..9eb11f0b 100644
--- a/src/main/cpp/odbcappender.cpp
+++ b/src/main/cpp/odbcappender.cpp
@@ -613,6 +613,26 @@ void ODBCAppender::flushBuffer(Pool& p)
 
 void ODBCAppender::setSql(const LogString& s)
 {
+	logchar currentQuote{ 0 };
+	const logchar doubleQuote{ 0x22 };
+	const logchar singleQuote{ 0x27 };
+	const logchar semiColan{ 0x3b };
+	int charCount{ 0 };
+	for (auto ch : s)
+	{
+		++charCount;
+		if (currentQuote == ch)
+			currentQuote = 0;
+		else if (currentQuote == 0)
+		{
+			if (doubleQuote == ch || singleQuote == ch)
+				currentQuote = ch;
+			else if (semiColan == ch && s.size() != charCount)
+				throw IllegalArgumentException(LOG4CXX_STR("SQL statement cannot contain a ';'"));
+		}
+	}
+	if (0 != currentQuote)
+		throw IllegalArgumentException(LogString(LOG4CXX_STR("Unmatched ")) + currentQuote + LOG4CXX_STR(" in SQL statement"));
     _priv->sqlStatement = s;
 }
 
diff --git a/src/test/cpp/db/odbcappendertestcase.cpp b/src/test/cpp/db/odbcappendertestcase.cpp
index 2e7dec99..42483aea 100644
--- a/src/test/cpp/db/odbcappendertestcase.cpp
+++ b/src/test/cpp/db/odbcappendertestcase.cpp
@@ -39,7 +39,10 @@ class ODBCAppenderTestCase : public AppenderSkeletonTestCase
 		//
 		LOGUNIT_TEST(testDefaultThreshold);
 		LOGUNIT_TEST(testSetOptionThreshold);
-		//LOGUNIT_TEST(testConnectUsingDSN);
+//#define DataSourceName_Log4cxxTest_Is_Valid
+#ifdef DataSourceName_Log4cxxTest_Is_Valid
+		LOGUNIT_TEST(testConnectUsingDSN);
+#endif
 		LOGUNIT_TEST_SUITE_END();
 
 
@@ -72,7 +75,7 @@ class ODBCAppenderTestCase : public AppenderSkeletonTestCase
 //
 // CREATE TABLE [dbo].[UnitTestLog](
 //	 [Item] [bigint] IDENTITY(1,1) NOT NULL, /* auto incremented */
-//	 [Thread] [nchar](20) NULL
+//	 [Thread] [nchar](20) NULL,
 //	 [LogTime] [datetime] NOT NULL,
 //	 [LogName] [nchar](50) NULL,
 //	 [LogLevel] [nchar](10) NULL,
@@ -90,7 +93,7 @@ class ODBCAppenderTestCase : public AppenderSkeletonTestCase
 			for (int i = 0; i < 100; ++i)
 			{
 				LOG4CXX_INFO(odbc, "Message '" << i << "'");
-				apr_sleep(30000);
+				apr_sleep(30000); // 30 milliseconds
 			}
 			LOG4CXX_INFO(odbc, "Last message");
 		}