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

Different String.startsWith behaviour on Android vs iOS #11370

Closed
jdmunro opened this issue Dec 8, 2016 · 30 comments
Closed

Different String.startsWith behaviour on Android vs iOS #11370

jdmunro opened this issue Dec 8, 2016 · 30 comments
Labels
Ran Commands One of our bots successfully processed a command. Resolution: Locked This issue was locked by the bot.

Comments

@jdmunro
Copy link
Contributor

jdmunro commented Dec 8, 2016

Description

I'm using the startsWith method on JavaScript strings to compare some values. Specifically the string contains emoji characters, but not at the beginning of the string.

On iOS:

'Fish and Chips 🐟🍟'.startsWith('F') // true

The exact same code on Android:

'Fish and Chips 🐟🍟'.startsWith('F') // false

This may not be an issue of React Native but the underlying JS implementation - just a guess.

Reproduction

Here's a reproduction of the issue: https://rnplay.org/apps/yKn2qA

If you delete the emoji characters from the string the bug goes away.

Additional Information

  • React Native version: v0.33 to v0.39
  • Platform: Android
@MatthewAwesome
Copy link

Issue persists in RN version 42, and I get it even with usual characters :( More of annoyance than anything, as String.indexOf('subString') == 0 as suffices as a workaround.

@blaues0cke
Copy link
Contributor

blaues0cke commented May 31, 2017

Can confirm that this issue exists in RN 42, too. Also have no emojis (but the text is encoded to support emojis). In my case this occurs in a regular JSON response. And it only appears when no debugger is attached.

rn-fail

@zhuyifan2013
Copy link

Still exists in RN 44

@ide
Copy link
Contributor

ide commented Jun 5, 2017

This issue exists because iOS uses many different versions of JavaScriptCore (a different version of iOS 8, 9, 10, 11) and RN Android uses its own JSC version. So there will always be some differences between different platforms until JSC completely stabilizes (maybe never, since JS changes each year).

To work around this you could write a polyfill or your own startsWith function instead.

@levsero
Copy link
Contributor

levsero commented Aug 3, 2017

@ide String.startsWith is already polyfilled in rn so I believe it should work regardless of the platform - https://github.com/facebook/react-native/blob/master/Libraries/polyfills/String.prototype.es6.js#L20

@artdent
Copy link
Contributor

artdent commented Aug 3, 2017

As you can see, the polyfill is only installed if the native version does not exist.

In this case, either the JSC implementation on Android should be fixed or the polyfill should be uninstalled unconditionally. It's disconcerting to encounter bugs in the JS standard library.

@jlangr
Copy link

jlangr commented Aug 25, 2017

In my case, the following expression returns false:
if (url.toLowerCase().startsWith('this://'))
... when no debugger is attached, and when url (loaded from a GET request) has the value 'this://44'. The byte codes of all the chars match, too.
When a debugger is attached, the expression returns true.

If I explicitly set String.prototype.startsWith to the version defined in the polyfill source-- https://github.com/facebook/react-native/blob/master/Libraries/polyfills/String.prototype.es6.js#L20 -- the expression returns true when expected. (The polyfill also matches the source I can view from my browser when attached to the debugger.)

(I'd like to see the source used for startsWith when not attached to a debugger, but calling toString() against the function just tells me that it's picking up native code--same result as when the debugger is attached. Is there another technique?)

Thanks MatthewAwesome for the (successful) workaround tip.

@ide
Copy link
Contributor

ide commented Aug 25, 2017

The debugger has different behavior because it runs on a different computer and on a different VM. Currently I really recommend that you use it only to debug specific issues rather than the way you develop.

This startsWith issue may get fixed in a few months if we are able to upgrade JSC. There is no real ETA though and if this issue is pressing for you I recommend you use your own String polyfill.

@jlangr
Copy link

jlangr commented Aug 25, 2017

Thanks for the quick response ide!

I get the bit about the debugger, thanks. The curiosity I have: (When I was not attached to the debugger,) I substituted the RN source as above (supposedly the polyfill used) and things worked just fine. So without this substitution, when startsWith does not behave correctly, some other source must be getting used--is there an easy way to know where that's coming from?

@ide
Copy link
Contributor

ide commented Aug 25, 2017

You could print ''.startsWith.toString() to see its source and then grep for that in node_modules.

@jlangr
Copy link

jlangr commented Aug 25, 2017

Unfortunately it just tells me it's [native code]. In node_modules it looks like there are at least a few definitions of String.prototype.startsWith.

@ide
Copy link
Contributor

ide commented Aug 25, 2017

That means it's using the native startsWith implementation then.

@stale
Copy link

stale bot commented Oct 24, 2017

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Maybe the issue has been fixed in a recent release, or perhaps it is not affecting a lot of people. If you think this issue should definitely remain open, please let us know why. Thank you for your contributions.

@stale stale bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Oct 24, 2017
@artdent
Copy link
Contributor

artdent commented Oct 24, 2017

This issue has not been fixed. In this case, two months of inactivity just means that there's nothing more to describe about the bug. Please keep it open.

@stale stale bot removed the Stale There has been a lack of activity on this issue and it may be closed soon. label Oct 24, 2017
@jdmunro
Copy link
Contributor Author

jdmunro commented Oct 25, 2017

I'd forgotten all about this issue but it actually still impacts my app. Can add a temporary work around to my code, but it looks like there are 2 longer term solutions for RN:

  1. Update to more modern version of JSC as @ide mentioned
  2. Always polyfill startsWith

Is there any reason not to do 2. as this seems to be a legitimate bug potentially affecting any app that uses startsWith on Android?

As another temporary workaround it might be worth trying this newer version of JSC for Android: https://github.com/SoftwareMansion/jsc-android-buildscripts#how-to-use-it-with-my-react-native-app

@stale
Copy link

stale bot commented Dec 24, 2017

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Maybe the issue has been fixed in a recent release, or perhaps it is not affecting a lot of people. If you think this issue should definitely remain open, please let us know why. Thank you for your contributions.

@stale stale bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Dec 24, 2017
@artdent
Copy link
Contributor

artdent commented Dec 24, 2017

Please keep it open.

This issue has not been fixed. In this case, two months of inactivity just means that there's nothing more to describe about the bug.

@stale stale bot removed the Stale There has been a lack of activity on this issue and it may be closed soon. label Dec 24, 2017
@stale
Copy link

stale bot commented Feb 22, 2018

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Maybe the issue has been fixed in a recent release, or perhaps it is not affecting a lot of people. If you think this issue should definitely remain open, please let us know why. Thank you for your contributions.

@stale stale bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Feb 22, 2018
@jdmunro
Copy link
Contributor Author

jdmunro commented Feb 23, 2018

Please keep this open 👍
There's nothing else to describe about the bug at this stage.

@stale stale bot removed the Stale There has been a lack of activity on this issue and it may be closed soon. label Feb 23, 2018
@react-native-bot
Copy link
Collaborator

Thanks for posting this! It looks like you may not be using the latest version of React Native, v0.53.0, released on January 2018. Can you make sure this issue can still be reproduced in the latest version?

I am going to close this, but please feel free to open a new issue if you are able to confirm that this is still a problem in v0.53.0 or newer.

How to ContributeWhat to Expect from Maintainers

@react-native-bot react-native-bot added Ran Commands One of our bots successfully processed a command. and removed Android labels Feb 24, 2018
@react-native-bot react-native-bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Feb 24, 2018
@stale stale bot removed the Stale There has been a lack of activity on this issue and it may be closed soon. label Feb 24, 2018
@blaues0cke
Copy link
Contributor

Cannot reproduce this in v0.53.0 using the Android simulator, tested on:

  • Nexus_6P_API_23(AVD) - 6.0
  • Nexus_4_API_22(AVD) - 5.1.1

@ziyafenn
Copy link

Using v0.55.4 and problem still exist in Android version.

@patrickkempff
Copy link
Contributor

Thank you @ziyafenn. Can you verify if the issue also exists if you use the JavaScriptCode from https://github.com/react-community/jsc-android-buildscripts?

@hey99xx
Copy link

hey99xx commented Oct 3, 2018

I tried "this://44" thing mentioned above but couldn't get incorrect results with that. I could only see incorrect values when emojis are included. Also String.prototype.endsWith() seems broken symmetrically.

Rather than checking jsc-android-buildscripts that is not production-ready yet, I'd be more curious to know if this issue happens on iOS 8/9 devices or not, but I don't have any devices to test. If it does not happen this bug might also mean FB's android-jsc is truly incompatible with standard iOS JSC runtimes.

@ziyafenn
Copy link

ziyafenn commented Dec 1, 2018

Hi @patrickkempff. Sorry for a VERY late answer. I checked it with jsc-android and there was no issue with it.

@ahmetabdi
Copy link

Same issue with latest RN

corporateanon pushed a commit to jskalama/kalama that referenced this issue Jan 7, 2019
@yernandus
Copy link

Still facing this problem. url.startsWith('http') returns true on IOS and false on Android

@ahmetabdi
Copy link

ahmetabdi commented Jan 22, 2019

@yernandus An alternative (till they fix the issue) that works on both is:

url.indexOf('http') === 0

@yernandus
Copy link

@ahmetabdi, thank you. I used lodash startsWith, since lodash was used for other things already.

@hey99xx
Copy link

hey99xx commented Jan 23, 2019

RN made the JSC upgrade in master branch, expected release is 0.59 #19737 (comment) This should likely be fixed with that.

@facebook facebook locked as resolved and limited conversation to collaborators Dec 11, 2019
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Dec 11, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Ran Commands One of our bots successfully processed a command. Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests