From 43e39ab08b40a2fff3842e105ec7e968ea6dbf44 Mon Sep 17 00:00:00 2001 From: Saksham Gupta Date: Thu, 15 Apr 2021 15:02:10 +0530 Subject: [PATCH 1/2] Fix #16777 - Non-UTF8 Primary Key fix Signed-off-by: Saksham Gupta --- libraries/classes/Util.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/classes/Util.php b/libraries/classes/Util.php index 97accdaa59..3f6c40825e 100644 --- a/libraries/classes/Util.php +++ b/libraries/classes/Util.php @@ -957,6 +957,9 @@ class Util } $conditionValue = ''; + $isBinaryString = $meta->type === 'string' && stripos($fieldFlags, 'BINARY') !== false; + // 63 is the binary charset, see: https://dev.mysql.com/doc/internals/en/charsets.html + $isBlobAndIsBinaryCharset = $meta->type === 'blob' && $meta->charsetnr === 63; // timestamp is numeric on some MySQL 4.1 // for real we use CONCAT above and it should compare to string if ($meta->numeric @@ -964,10 +967,7 @@ class Util && ($meta->type !== 'real') ) { $conditionValue = '= ' . $row; - } elseif (($meta->type === 'blob') || ($meta->type === 'string') - && stripos($fieldFlags, 'BINARY') !== false - && ! empty($row) - ) { + } elseif ($isBlobAndIsBinaryCharset || (! empty($row) && $isBinaryString)) { // hexify only if this is a true not empty BLOB or a BINARY // do not waste memory building a too big condition From 94add64100bd923e2fc20b0a9e10fe94e98e39af Mon Sep 17 00:00:00 2001 From: William Desportes Date: Mon, 19 Apr 2021 16:46:08 +0200 Subject: [PATCH 2/2] Add tests for #16777 Signed-off-by: William Desportes --- test/classes/UtilTest.php | 60 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/test/classes/UtilTest.php b/test/classes/UtilTest.php index 949f3fa495..2e579b7017 100644 --- a/test/classes/UtilTest.php +++ b/test/classes/UtilTest.php @@ -207,6 +207,66 @@ class UtilTest extends AbstractTestCase ] ) ); + $this->assertSame( + ['= \'value\'', ''], + $this->callFunction( + null, + Util::class, + 'getConditionValue', + [ + 'value',// row + ((object) [ + 'numeric' => false, + 'type' => 'blob', + 'charsetnr' => 32,// armscii8_general_ci + ]),// field meta + '',// field flags + 0,// fields count + '',// condition key + '',// condition + ] + ) + ); + $this->assertSame( + ['= \'value\'', ''], + $this->callFunction( + null, + Util::class, + 'getConditionValue', + [ + 'value',// row + ((object) [ + 'numeric' => false, + 'type' => 'blob', + 'charsetnr' => 48,// latin1_general_ci + ]),// field meta + '',// field flags + 0,// fields count + '',// condition key + '',// condition + ] + ) + ); + $this->assertSame( + ['= CAST(0x76616c7565 AS BINARY)', ''], + $this->callFunction( + null, + Util::class, + 'getConditionValue', + [ + 'value',// row + ((object) [ + 'numeric' => false, + 'type' => 'blob', + 'charsetnr' => 63,// binary + ]),// field meta + '',// field flags + 0,// fields count + '',// condition key + '',// condition + ] + ) + ); $this->assertSame( ['= CAST(0x76616c7565 AS BINARY)', ''], $this->callFunction(