This is an automated email from the ASF dual-hosted git repository.
pjfanning pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/pekko-connectors.git
The following commit(s) were added to refs/heads/main by this push:
new dd540083a OrientDB: only validate className when it is used in a query
(#1874)
dd540083a is described below
commit dd540083a1cff84fd2289d032d10ad416d999f8f
Author: PJ Fanning <[email protected]>
AuthorDate: Thu Oct 1 07:38:59 2026 +0100
OrientDB: only validate className when it is used in a query (#1874)
Motivation:
OrientDbSourceStage validates className in its constructor
unconditionally, including when an explicit query is supplied. In that
case className is never used: createLogic ignores it in both query
branches, and the SELECT that interpolates it is only built when query is
empty.
Both DSLs require className as a positional argument, so a caller reading
purely by query must pass a syntactically valid dummy class name to get
past a check that guards a string their query never reaches.
Modification:
Validate only when query is empty, which is exactly when className is
interpolated into "SELECT * FROM $className".
Result:
Query-only reads no longer need a placeholder class name. The injection
guard is unchanged wherever className actually reaches SQL.
Tests:
Extended OrientDbSourceStageSpec with stage-level tests: an invalid class
name is still rejected with no query, a valid one is accepted, and a
class name that is empty, null, or malformed is accepted when a query is
given. Verified the query-mode test fails without this change. 11 tests
pass. Ran orientdb/mimaReportBinaryIssues (clean) and the module scalafmt
checks.
References:
Follow-up to #1821.
---
.../orientdb/impl/OrientDbSourceStage.scala | 5 ++-
.../orientdb/impl/OrientDbSourceStageSpec.scala | 36 ++++++++++++++++++++++
2 files changed, 40 insertions(+), 1 deletion(-)
diff --git
a/orientdb/src/main/scala/org/apache/pekko/stream/connectors/orientdb/impl/OrientDbSourceStage.scala
b/orientdb/src/main/scala/org/apache/pekko/stream/connectors/orientdb/impl/OrientDbSourceStage.scala
index c3b54ef4a..5271429ef 100644
---
a/orientdb/src/main/scala/org/apache/pekko/stream/connectors/orientdb/impl/OrientDbSourceStage.scala
+++
b/orientdb/src/main/scala/org/apache/pekko/stream/connectors/orientdb/impl/OrientDbSourceStage.scala
@@ -50,7 +50,10 @@ private[orientdb] final class
OrientDbSourceStage[T](className: String,
clazz: Option[Class[T]] = None)
extends GraphStage[SourceShape[OrientDbReadResult[T]]] {
- OrientDbSourceStage.validateClassName(className)
+ // `className` is interpolated into the SELECT below, so it has to be
validated.
+ // When an explicit `query` is given the class name is never used, and
callers
+ // are not required to supply a meaningful one.
+ if (query.isEmpty) OrientDbSourceStage.validateClassName(className)
val out: Outlet[OrientDbReadResult[T]] = Outlet("OrientDBSource.out")
override val shape = SourceShape(out)
diff --git
a/orientdb/src/test/scala/org/apache/pekko/stream/connectors/orientdb/impl/OrientDbSourceStageSpec.scala
b/orientdb/src/test/scala/org/apache/pekko/stream/connectors/orientdb/impl/OrientDbSourceStageSpec.scala
index 0ef5c4993..7095f5b02 100644
---
a/orientdb/src/test/scala/org/apache/pekko/stream/connectors/orientdb/impl/OrientDbSourceStageSpec.scala
+++
b/orientdb/src/test/scala/org/apache/pekko/stream/connectors/orientdb/impl/OrientDbSourceStageSpec.scala
@@ -17,6 +17,8 @@
package org.apache.pekko.stream.connectors.orientdb.impl
+import com.orientechnologies.orient.core.db.ODatabasePool
+import org.apache.pekko.stream.connectors.orientdb.OrientDbSourceSettings
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
@@ -74,4 +76,38 @@ class OrientDbSourceStageSpec extends AnyWordSpec with
Matchers {
}
}
}
+
+ "OrientDbSourceStage" should {
+
+ // the pool is never used: construction fails (or not) before the stage
runs
+ def settings: OrientDbSourceSettings =
+ OrientDbSourceSettings(null.asInstanceOf[ODatabasePool])
+
+ "reject an invalid class name when no query is given" in {
+ // the class name is interpolated into "SELECT * FROM $className"
+ assertThrows[IllegalArgumentException] {
+ new OrientDbSourceStage[Nothing]("User; DROP TABLE users; --", None,
settings)
+ }
+ }
+
+ "accept a valid class name when no query is given" in {
+ noException should be thrownBy {
+ new OrientDbSourceStage[Nothing]("User", None, settings)
+ }
+ }
+
+ "not validate the class name when an explicit query is given" in {
+ // the class name is unused in query mode, so callers are not required
+ // to supply a meaningful one
+ noException should be thrownBy {
+ new OrientDbSourceStage[Nothing]("", Some("SELECT * FROM User"),
settings)
+ }
+ noException should be thrownBy {
+ new OrientDbSourceStage[Nothing](null, Some("SELECT * FROM User"),
settings)
+ }
+ noException should be thrownBy {
+ new OrientDbSourceStage[Nothing]("not a valid name", Some("SELECT *
FROM User"), settings)
+ }
+ }
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]