From 07a5504f1e2bff4807fa3322739f5f583ced611a Mon Sep 17 00:00:00 2001 From: Vincent ENJALBERT Date: Wed, 13 Aug 2025 19:08:23 +0200 Subject: [PATCH] #40138 - Fix string manipulations errors with multibyte characters --- app/code/Magento/Tax/Model/Calculation/Rate.php | 6 +++--- .../Magento/Tax/Model/ResourceModel/Calculation.php | 12 ++++++------ .../Unit/Model/ResourceModel/CalculationTest.php | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/Tax/Model/Calculation/Rate.php b/app/code/Magento/Tax/Model/Calculation/Rate.php index db65d2c2c9d10..8bee16d2ceab4 100644 --- a/app/code/Magento/Tax/Model/Calculation/Rate.php +++ b/app/code/Magento/Tax/Model/Calculation/Rate.php @@ -142,7 +142,7 @@ public function beforeSave() $zipFrom = $this->getZipFrom(); $zipTo = $this->getZipTo(); - if (($zipFrom && strlen($zipFrom) > 9) || ($zipTo && strlen($zipTo) > 9)) { + if (($zipFrom && mb_strlen($zipFrom) > 9) || ($zipTo && mb_strlen($zipTo) > 9)) { throw new \Magento\Framework\Exception\LocalizedException( __( 'The ZIP Code length is invalid. ' @@ -167,8 +167,8 @@ public function beforeSave() } else { $taxPostCode = $this->getTaxPostcode(); - if ($taxPostCode !== null && strlen($taxPostCode) > 10) { - $taxPostCode = substr($taxPostCode, 0, 10); + if ($taxPostCode !== null && mb_strlen($taxPostCode) > 10) { + $taxPostCode = mb_substr($taxPostCode, 0, 10); } $this->setTaxPostcode($taxPostCode)->setZipIsRange(null)->setZipFrom(null)->setZipTo(null); diff --git a/app/code/Magento/Tax/Model/ResourceModel/Calculation.php b/app/code/Magento/Tax/Model/ResourceModel/Calculation.php index 036d8533a585e..16c121fe75521 100644 --- a/app/code/Magento/Tax/Model/ResourceModel/Calculation.php +++ b/app/code/Magento/Tax/Model/ResourceModel/Calculation.php @@ -233,21 +233,21 @@ protected function _createSearchPostCodeTemplates($postcode, $exactPostcode = nu { // as needed, reduce the postcode to the correct length $len = $this->_taxData->getPostCodeSubStringLength(); - $postcode = $postcode !== null ? substr($postcode, 0, $len) : ''; + $postcode = $postcode !== null ? mb_substr($postcode, 0, $len) : ''; // begin creating the search template array $strArr = [$postcode, $postcode . '*']; // if supplied, use the exact postcode as the basis for the search templates if ($exactPostcode) { - $postcode = substr($exactPostcode, 0, $len); + $postcode = mb_substr($exactPostcode, 0, $len); $strArr[] = $postcode; } // finish building out the search template array - $strlen = strlen($postcode); + $strlen = mb_strlen($postcode); for ($i = 1; $i < $strlen; $i++) { - $strArr[] = sprintf('%s*', substr($postcode, 0, -$i)); + $strArr[] = sprintf('%s*', mb_substr($postcode, 0, -$i)); } return $strArr; @@ -346,8 +346,8 @@ protected function _getRates($request) $zipFrom = null; $zipTo = null; if (is_string($postcode) && preg_match('/^(.+)-(.+)$/', $postcode, $matches)) { - if ((self::USA_COUNTRY_CODE === $countryId && is_numeric($matches[2]) && 4 === strlen($matches[2])) || - (self::PORTUGAL_COUNTRY_CODE === $countryId && is_numeric($matches[2]) && 3 === strlen($matches[2])) + if ((self::USA_COUNTRY_CODE === $countryId && is_numeric($matches[2]) && 4 === mb_strlen($matches[2])) || + (self::PORTUGAL_COUNTRY_CODE === $countryId && is_numeric($matches[2]) && 3 === mb_strlen($matches[2])) ) { $postcodeIsNumeric = true; $originalPostcode = $postcode; diff --git a/app/code/Magento/Tax/Test/Unit/Model/ResourceModel/CalculationTest.php b/app/code/Magento/Tax/Test/Unit/Model/ResourceModel/CalculationTest.php index b65d363f13fc3..181b20a5515ad 100644 --- a/app/code/Magento/Tax/Test/Unit/Model/ResourceModel/CalculationTest.php +++ b/app/code/Magento/Tax/Test/Unit/Model/ResourceModel/CalculationTest.php @@ -67,9 +67,9 @@ public function testCreateSearchPostCodeTemplates($postalCode, $exactPostalcode) private function verifyResults($resultsArr, $code1, $code2 = null) { // determine expected size of the results array - $expectedSize = strlen($code1) + 1; // array will also include the vanilla 'code1' value + $expectedSize = mb_strlen($code1) + 1; // array will also include the vanilla 'code1' value if ($code2) { - $expectedSize = strlen($code2) + 2; // array will include both 'code1' and 'code2' + $expectedSize = mb_strlen($code2) + 2; // array will include both 'code1' and 'code2' } $actualSize = count($resultsArr); $this->assertEquals(