Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Error detection] Bad behavior when using mb characters in addresses #47

Open
bhennesAdv opened this issue Feb 13, 2025 · 1 comment · May be fixed by #48
Open

[Error detection] Bad behavior when using mb characters in addresses #47

bhennesAdv opened this issue Feb 13, 2025 · 1 comment · May be fixed by #48

Comments

@bhennesAdv
Copy link

Hello,

I faced an error using your module which crashes the checkout behavior when using a multibyte char in the address field.

The error was the checkout javascript being broken with the message :

 Uncaught URIError: malformed URI sequence
    jQuery 2
    isPlaceOrderActionAllowed ..../Lyranetwork_Payzen/js/view/payment/method-renderer/payzen-oney.min.js:1
    wrapSuper ....mage/utils/wrapper.min.js:3
    initialize

The cookie value being encoded via url encode method, the cookie becomes corrupted once the payzen_oney_error is set into it.

The error (and it's resolution) is quiet easy once you found it:

// In https://github.com/lyra/plugin-magento/blob/master/Helper/Checkout.php
[...]
private function checkFieldValidity($field, $regex, $fieldName, $addressType, $mandatory = true)
    {
        // Error messages.
        $invalidMsg = 'The field %1 of your %2 is invalid.';
        $emptyMsg = 'The field %1 of your %2 is mandatory.';

        if ($mandatory && ! $field) {
            $this->setErrorMsg($emptyMsg, $fieldName, $addressType);
        }

        if ($field && ! preg_match($regex, $field)) {
            // Delete valid characters to retrieve invalid ones.
            $replaceRegex = preg_replace("/{(.*?)}/", '', $regex);
            $replaceRegex = str_replace(array('^', '$'), '', $replaceRegex);
            $invalidChars = preg_replace($replaceRegex, '', $field);

            if (empty($invalidChars)) {
                $this->setErrorMsg($invalidMsg, $fieldName, $addressType);
                return;
            }
// ======================================================= Error happens here :
// If the remaining string contains multibyte characters, this str_split will split them in 2
            $arr = str_split($invalidChars);
            $invalidChars = '';
            foreach ($arr as $char) {
                $invalidChars .= '<b>' . $char . '</b> ';
            }

            $this->setErrorMsg($invalidMsg, $fieldName, $addressType, $invalidChars);
        }
    }

For example, we had a customer having the following characters in its address (quiet common in France) :

n°123 Test Street

The degree sign is a problem because it's encoded C2 B0 in UTF8. So the str_split will split this into 2 invalid codes (C2 and B0)
To validate the behavior, you can run the following code :

$addressField = "n°123 Test Street";
$replaceRegex = preg_replace("/{(.*?)}/", '', "#^[A-Z0-9ÁÀÂÄÉÈÊËÍÌÎÏÓÒÔÖÚÙÛÜÇ/ '.,-]{1,127}$#ui");
$replaceRegex = str_replace(array('^', '$'), '', $replaceRegex);
$invalidChars = preg_replace($replaceRegex, '', $addressField);

echo $invalidChars . "\n";
var_dump(str_split($invalidChars));
var_dump(array_map(function ($char) { return bin2hex($char);}, str_split($invalidChars)));
var_dump(mb_str_split($invalidChars));
var_dump(array_map(function ($char) { return bin2hex($char);}, mb_str_split($invalidChars)));

/* Result here :
°
array(2) {
  [0]=>
  string(1) "�"
  [1]=>
  string(1) "�"
}
array(2) {
  [0]=>
  string(2) "c2"
  [1]=>
  string(2) "b0"
}
array(1) {
  [0]=>
  string(2) "°"
}
array(1) {
  [0]=>
  string(4) "c2b0"
}
*/

Correction is quiet simple as mb_str_split() exists in PHP codebase.
I'll open the PR directly.

Kind Regards,
Baptiste

@bhennesAdv
Copy link
Author

Well I just noticed when writing the PR that your module is supposed to be compatible with PHP ~7 but mb_str_split is available from PHP 7.4 only.

Choice is yours on this.

bhennesAdv added a commit to bhennesAdv/plugin-magento that referenced this issue Feb 13, 2025
…appeared in PHP-7.4, the composer PHP minimum version must be 7.4 with mbstring extension.

See the issue for the problem it resolves : lyra#47
@bhennesAdv bhennesAdv linked a pull request Feb 13, 2025 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant