Skip to content

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

Open
@bhennesAdv

Description

@bhennesAdv

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions