From 36c3d0ab04334c02dfa6b49c3162aec45053b153 Mon Sep 17 00:00:00 2001 From: Alexandr Morohin Date: Fri, 8 May 2026 13:31:25 +0500 Subject: [PATCH] fix: if the data contains the substring "ON CLUSTER", double-check it using a regular expression --- src/Transport/Http.php | 8 +++++++- tests/ClientTest.php | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/Transport/Http.php b/src/Transport/Http.php index db00f45..5ee2c0b 100644 --- a/src/Transport/Http.php +++ b/src/Transport/Http.php @@ -682,9 +682,15 @@ private function prepareWrite($sql, array $bindings = [], array $querySettings = $query = $this->prepareQuery($sql, $bindings); - if (strpos($sql, 'ON CLUSTER') === false) { + // strpos acts as a fast filter (cheap substring check) + // preg_match is used only for strict SQL keyword validation (word-boundary safe) + if ( + strpos($sql, 'ON CLUSTER') === false + || !preg_match("/\\bON\\s+CLUSTER\\b/i", $sql) + ) { return $this->getRequestWrite($query, $querySettings); } + if ( !str_starts_with($sql, 'CREATE') && !str_starts_with($sql, 'DROP') diff --git a/tests/ClientTest.php b/tests/ClientTest.php index 58d49cc..b0a216a 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -1096,4 +1096,22 @@ public function testStreamInsertFormatJSONEachRow() $this->assertEquals(count(file($file_name)), $statement->count()); } + public function testInsertWithOnClusterInData() + { + $this->client->write('DROP TABLE IF EXISTS `test`'); + $this->client->write('CREATE TABLE `test` ( + place String + ) ENGINE = TinyLog()'); + $this->client->insert( + 'test', + [ + ['REGION CLUSTER'], + ], + ['place'] + ); + + $statement = $this->client->select('SELECT place FROM `test`'); + $this->assertCount(1, $statement->rows()); + $this->assertEquals('REGION CLUSTER', $statement->fetchOne('place')); + } }