From 89b1215be7f9f1f9277b8608b0ea53689db0e765 Mon Sep 17 00:00:00 2001 From: sm Date: Wed, 15 Mar 2023 21:58:16 +0200 Subject: [PATCH] [bugfix] #47 Malformed UTF-8 characters, possibly incorrectly encoded --- src/Codeception/Lib/Driver/Db.php | 7 +++++++ src/Codeception/Module/Db.php | 6 +++--- tests/data/dumps/mysql.sql | 9 +++++---- tests/data/dumps/postgres.sql | 12 +++++++----- tests/data/dumps/sqlite.sql | 10 +++++----- tests/data/sqlite.db | Bin 36864 -> 36864 bytes .../Codeception/Module/Db/AbstractDbTest.php | 7 +++++++ 7 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/Codeception/Lib/Driver/Db.php b/src/Codeception/Lib/Driver/Db.php index fdcdb4e4..b5680459 100755 --- a/src/Codeception/Lib/Driver/Db.php +++ b/src/Codeception/Lib/Driver/Db.php @@ -294,6 +294,8 @@ public function executeQuery($query, array $params): PDOStatement $type = PDO::PARAM_BOOL; } elseif (is_int($param)) { $type = PDO::PARAM_INT; + } elseif ($this->isBinary($param)) { + $type = PDO::PARAM_LOB; } else { $type = PDO::PARAM_STR; } @@ -342,4 +344,9 @@ public function getOptions(): array { return $this->options; } + + protected function isBinary(string $string): bool + { + return false === mb_detect_encoding($string, null, true); + } } diff --git a/src/Codeception/Module/Db.php b/src/Codeception/Module/Db.php index 42c58bca..7fc6c863 100644 --- a/src/Codeception/Module/Db.php +++ b/src/Codeception/Module/Db.php @@ -836,7 +836,7 @@ public function seeInDatabase(string $table, array $criteria = []): void $this->assertGreaterThan( 0, $res, - 'No matching records found for criteria ' . json_encode($criteria, JSON_THROW_ON_ERROR) . ' in table ' . $table + 'No matching records found for criteria ' . json_encode($criteria, JSON_THROW_ON_ERROR | JSON_INVALID_UTF8_SUBSTITUTE) . ' in table ' . $table ); } @@ -862,7 +862,7 @@ public function seeNumRecords(int $expectedNumber, string $table, array $criteri 'The number of found rows (%d) does not match expected number %d for criteria %s in table %s', $actualNumber, $expectedNumber, - json_encode($criteria, JSON_THROW_ON_ERROR), + json_encode($criteria, JSON_THROW_ON_ERROR | JSON_INVALID_UTF8_SUBSTITUTE), $table ) ); @@ -874,7 +874,7 @@ public function dontSeeInDatabase(string $table, array $criteria = []): void $this->assertLessThan( 1, $count, - 'Unexpectedly found matching records for criteria ' . json_encode($criteria, JSON_THROW_ON_ERROR) . ' in table ' . $table + 'Unexpectedly found matching records for criteria ' . json_encode($criteria, JSON_THROW_ON_ERROR | JSON_INVALID_UTF8_SUBSTITUTE) . ' in table ' . $table ); } diff --git a/tests/data/dumps/mysql.sql b/tests/data/dumps/mysql.sql index 3f9059fc..3617afd5 100644 --- a/tests/data/dumps/mysql.sql +++ b/tests/data/dumps/mysql.sql @@ -16,6 +16,7 @@ insert into `groups`(`id`,`name`,`enabled`,`created_at`) values (2,'jazzman',0, CREATE TABLE `users` ( `id` int(11) NOT NULL AUTO_INCREMENT, + `uuid` binary(16) DEFAULT NULL, `name` varchar(30) DEFAULT NULL, `email` varchar(255) DEFAULT NULL, `is_active` bit(1) DEFAULT b'1', @@ -24,13 +25,13 @@ CREATE TABLE `users` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -insert into `users`(`id`,`name`,`email`, `is_active`,`created_at`) values (1,'davert','davert@mail.ua', b'1','2012-02-01 21:17:04'); +insert into `users`(`id`,`uuid`, `name`,`email`, `is_active`,`created_at`) values (1,0x11edc34b01d972fa9c1d0242ac120006,'davert','davert@mail.ua', b'1','2012-02-01 21:17:04'); -insert into `users`(`id`,`name`,`email`, `is_active`,`created_at`) values (2,'nick','nick@mail.ua', b'1','2012-02-01 21:17:15'); +insert into `users`(`id`,`uuid`, `name`,`email`, `is_active`,`created_at`) values (2,null,'nick','nick@mail.ua', b'1','2012-02-01 21:17:15'); -insert into `users`(`id`,`name`,`email`, `is_active`,`created_at`) values (3,'miles','miles@davis.com', b'1','2012-02-01 21:17:25'); +insert into `users`(`id`,`uuid`, `name`,`email`, `is_active`,`created_at`) values (3,null,'miles','miles@davis.com', b'1','2012-02-01 21:17:25'); -insert into `users`(`id`,`name`,`email`, `is_active`,`created_at`) values (4,'bird','charlie@parker.com', b'0','2012-02-01 21:17:39'); +insert into `users`(`id`,`uuid`, `name`,`email`, `is_active`,`created_at`) values (4,null,'bird','charlie@parker.com', b'0','2012-02-01 21:17:39'); diff --git a/tests/data/dumps/postgres.sql b/tests/data/dumps/postgres.sql index a95dfe0f..13b87d0e 100755 --- a/tests/data/dumps/postgres.sql +++ b/tests/data/dumps/postgres.sql @@ -28,6 +28,7 @@ SET default_with_oids = false; DROP TABLE IF EXISTS users CASCADE; CREATE TABLE users ( name character varying(30), + uuid bytea, email character varying(50), created_at timestamp without time zone DEFAULT now(), id integer NOT NULL @@ -181,6 +182,7 @@ ALTER SEQUENCE permissions_id_seq OWNED BY permissions.id; DROP TABLE IF EXISTS users CASCADE; CREATE TABLE users ( name character varying(30), + uuid bytea, email character varying(50), created_at timestamp without time zone DEFAULT now(), id integer NOT NULL @@ -332,11 +334,11 @@ SELECT pg_catalog.setval('permissions_id_seq', 10, true); -- Data for Name: users; Type: TABLE DATA; Schema: public; Owner: - -- -COPY users (name, email, created_at, id) FROM stdin; -davert davert@mail.ua \N 1 -nick nick@mail.ua 2012-02-02 22:30:31.748 2 -miles miles@davis.com 2012-02-02 22:30:52.166 3 -bird charlie@parker.com 2012-02-02 22:32:13.107 4 +COPY users (name, uuid, email, created_at, id) FROM stdin; +davert \\x11edc34b01d972fa9c1d0242ac120006 davert@mail.ua \N 1 +nick NULL nick@mail.ua 2012-02-02 22:30:31.748 2 +miles NULL miles@davis.com 2012-02-02 22:30:52.166 3 +bird NULL charlie@parker.com 2012-02-02 22:32:13.107 4 \. diff --git a/tests/data/dumps/sqlite.sql b/tests/data/dumps/sqlite.sql index 4fbfeb95..87d65cd9 100755 --- a/tests/data/dumps/sqlite.sql +++ b/tests/data/dumps/sqlite.sql @@ -11,11 +11,11 @@ INSERT INTO "permissions" VALUES(5,3,2,'member'); INSERT INTO "permissions" VALUES(7,4,2,'admin'); DROP TABLE IF EXISTS "users"; -CREATE TABLE "users" ("name" VARCHAR, "email" VARCHAR, "created_at" DATETIME DEFAULT CURRENT_TIMESTAMP); -INSERT INTO "users" VALUES('davert','davert@mail.ua','2012-02-01 21:17:04'); -INSERT INTO "users" VALUES('nick','nick@mail.ua','2012-02-01 21:17:15'); -INSERT INTO "users" VALUES('miles','miles@davis.com','2012-02-01 21:17:25'); -INSERT INTO "users" VALUES('bird','charlie@parker.com','2012-02-01 21:17:39'); +CREATE TABLE "users" ("name" VARCHAR, "uuid" BLOB DEFAULT NULL, "email" VARCHAR, "created_at" DATETIME DEFAULT CURRENT_TIMESTAMP); +INSERT INTO "users" VALUES('davert',X'11edc34b01d972fa9c1d0242ac120006','davert@mail.ua','2012-02-01 21:17:04'); +INSERT INTO "users" VALUES('nick',null,'nick@mail.ua','2012-02-01 21:17:15'); +INSERT INTO "users" VALUES('miles',null,'miles@davis.com','2012-02-01 21:17:25'); +INSERT INTO "users" VALUES('bird',null,'charlie@parker.com','2012-02-01 21:17:39'); DROP TABLE IF EXISTS "empty_table"; CREATE TABLE "empty_table" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL , "field" VARCHAR); diff --git a/tests/data/sqlite.db b/tests/data/sqlite.db index 6c7c70e451b5db94d66ed1dcfe7bf6074fa51875..b8b0d252a70ff2ed7592f9d4ccb45196f21b2df9 100644 GIT binary patch delta 169 zcmZozz|^pSX+n~e_e5R>1_lo95(a)ZzAt{YDygGsoRV0UT2vzV_OLhO V&7xm(WSN}S2r;m2zVEN-001BpE8qYC delta 125 zcmZozz|^pSX+n~e%m!Wt1_lo9eg=LwzAtb|~o!5Lb2j4$KEg@PgbXizLC)@jLvuHE3h)>S<*JM#= c0*cJ_SLM-WWRcV~PDw0FEh^c3-(S%I0Hc&2O8@`> diff --git a/tests/unit/Codeception/Module/Db/AbstractDbTest.php b/tests/unit/Codeception/Module/Db/AbstractDbTest.php index 325482c8..f880866b 100644 --- a/tests/unit/Codeception/Module/Db/AbstractDbTest.php +++ b/tests/unit/Codeception/Module/Db/AbstractDbTest.php @@ -64,6 +64,11 @@ public function testConnectionIsKeptForTheWholeSuite() $this->module->_afterSuite(); } + public function testSeeInDatabaseWithBinary() + { + $this->module->seeInDatabase('users', ['uuid' => hex2bin('11edc34b01d972fa9c1d0242ac120006')]); + } + public function testSeeInDatabase() { $this->module->seeInDatabase('users', ['name' => 'davert']); @@ -71,6 +76,7 @@ public function testSeeInDatabase() public function testCountInDatabase() { + $this->module->seeNumRecords(1, 'users', ['uuid' => hex2bin('11edc34b01d972fa9c1d0242ac120006')]); $this->module->seeNumRecords(1, 'users', ['name' => 'davert']); $this->module->seeNumRecords(0, 'users', ['name' => 'davert', 'email' => 'xxx@yyy.zz']); $this->module->seeNumRecords(0, 'users', ['name' => 'user1']); @@ -78,6 +84,7 @@ public function testCountInDatabase() public function testDontSeeInDatabase() { + $this->module->dontSeeInDatabase('users', ['uuid' => hex2bin('ffffffffffffffffffffffffffffffff')]); $this->module->dontSeeInDatabase('users', ['name' => 'user1']); }