-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
fix: remove localeCompare from account order sorting #28234
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not using localCompare
maybe makes sense, but I think the implementation here has issues.
// Otherwise, sort by pubkey, stringwise. | ||
return x.pubkey.toBase58().localeCompare(y.pubkey.toBase58()); | ||
|
||
const xPubKey = x.pubkey.toBase58().toLowerCase(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why lowercase? This will change the sort order. It will also cause two pubkeys which are not identical to be interpreted as identical. Does that matter?
const xPubKey = x.pubkey.toBase58().toLowerCase(); | ||
const yPubKey = y.pubkey.toBase58().toLowerCase(); | ||
|
||
return xPubKey < yPubKey ? -1 : xPubKey > yPubKey ? 1 : 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm. Using <
and >
doesn't seem right. The string may start with a number, causing it to be parsed as a number and then compared with another string (that may not start with a number).
From https://www.w3schools.com/js/js_comparisons.asp
When comparing a string with a number, JavaScript will convert the string to a number when doing the comparison. An empty string converts to
0
. A non-numeric string converts toNaN
which is alwaysfalse
.
Is this desired behavior?
I remember bringing this up when we made the last change to this code as seeming off (what locale could possibly affect the order materially) but we never ended up pulling on the thread. |
Also, I'm curious to know the details of the different behavior on RN. What engine? What strings produce different orders? |
To fix the RN mismatch: did we consider figuring out what the difference was and being explicit in our call to |
Problem
localeCompare
should be limited and not used when not required. For the sorting of the account metas, we don't specifically require the usage of it since those are Public Keys, and a direct comparison would work as expected.This is prone to issues in react native, depending on the JS engine being used.
Context: Conversation on the #21724.
Summary of Changes
This fix makes the sorting of account metas work predictably independent of the JS engine used, as
localeCompare
behaves differently depending on the JS engine (v8 vs JSC, for example).