facebook / hermes

A JavaScript engine optimized for running React Native.
https://hermesengine.dev/
MIT License
9.91k stars 641 forks source link

(FATAL) Invalid RegExp: Invalid escape #480

Closed hannojg closed 3 years ago

hannojg commented 3 years ago

Bug Description

The package icu-messageformat-parser caused our app to throw errors when we tried to use its features. The error:

The stack trace ``` ERROR [12:49:12.476] {?} (FATAL) GlobalErrorHandler: An uncaught exception occured. Invalid RegExp: Invalid escape at ProfileCounters (http://192.168.0.213:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.cuvent.experiences.friend:418302:28) at RCTView at View at RCTView at View at RCTScrollContentView at RCTScrollView at ScrollView (http://192.168.0.213:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.cuvent.experiences.friend:63738:36) at ScrollView at AnimatedComponent(ScrollView) (http://192.168.0.213:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.cuvent.experiences.friend:259739:38) at AnimatedComponentWrapper at UserProfileCard (http://192.168.0.213:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.cuvent.experiences.friend:501674:22) at Connect(UserProfileCard) (http://192.168.0.213:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.cuvent.experiences.friend:181303:43) at RCTView at View at UserProfilePageContainer (http://192.168.0.213:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.cuvent.experiences.friend:501450:22) at Connect(UserProfilePageContainer) (http://192.168.0.213:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.cuvent.experiences.friend:181303:43) at withIntlProvider(Connect(UserProfilePageContainer)) at ApolloProvider (http://192.168.0.213:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.cuvent.experiences.friend:167485:22) at withApolloClientProvider(withIntlProvider(Connect(UserProfilePageContainer))) at Provider (http://192.168.0.213:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.cuvent.experiences.friend:180893:21) at withReduxProvider(withApolloClientProvider(withIntlProvider(Connect(UserProfilePageContainer)))) at RCTView at View at gestureHandlerRootHOC(withReduxProvider(withApolloClientProvider(withIntlProvider(Connect(UserProfilePageContainer))))) at WrappedComponent (http://192.168.0.213:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.cuvent.experiences.friend:207045:84) at RCTView at View at ChildrenWrapper (http://192.168.0.213:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.cuvent.experiences.friend:412248:77) at _default (http://192.168.0.213:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.cuvent.experiences.friend:412423:36) at Root at RCTView at View at AppContainer (http://192.168.0.213:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.cuvent.experiences.friend:68599:36) ERROR SyntaxError: Invalid RegExp: Invalid escape, js engine: hermes at ProfileCounters (http://192.168.0.213:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.cuvent.experiences.friend:418302:28) at RCTView at View at RCTView at View at RCTScrollContentView at RCTScrollView at ScrollView (http://192.168.0.213:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.cuvent.experiences.friend:63738:36) at ScrollView at AnimatedComponent(ScrollView) (http://192.168.0.213:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.cuvent.experiences.friend:259739:38) at AnimatedComponentWrapper at UserProfileCard (http://192.168.0.213:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.cuvent.experiences.friend:501674:22) at Connect(UserProfileCard) (http://192.168.0.213:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.cuvent.experiences.friend:181303:43) at RCTView at View at UserProfilePageContainer (http://192.168.0.213:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.cuvent.experiences.friend:501450:22) at Connect(UserProfilePageContainer) (http://192.168.0.213:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.cuvent.experiences.friend:181303:43) at withIntlProvider(Connect(UserProfilePageContainer)) at ApolloProvider (http://192.168.0.213:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.cuvent.experiences.friend:167485:22) at withApolloClientProvider(withIntlProvider(Connect(UserProfilePageContainer))) at Provider (http://192.168.0.213:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.cuvent.experiences.friend:180893:21) at withReduxProvider(withApolloClientProvider(withIntlProvider(Connect(UserProfilePageContainer)))) at RCTView at View at gestureHandlerRootHOC(withReduxProvider(withApolloClientProvider(withIntlProvider(Connect(UserProfilePageContainer))))) at WrappedComponent (http://192.168.0.213:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.cuvent.experiences.friend:207045:84) at RCTView at View at ChildrenWrapper (http://192.168.0.213:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.cuvent.experiences.friend:412248:77) at _default (http://192.168.0.213:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.cuvent.experiences.friend:412423:36) at Root at RCTView at View at AppContainer (http://192.168.0.213:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.cuvent.experiences.friend:68599:36) ```

This happens when the lib calls this regexp:

new RegExp('([^\\p{White_Space}\\p{Pattern_Syntax}]*)', 'yu')

which causes the above crashes.

Hermes version: 0.7.2 React Native version (if any): 0.64 OS version (if any): ios & android Platform (most likely one of arm64-v8a, armeabi-v7a, x86, x86_64): doesn't matter I guess

Steps To Reproduce

A reproduction could be:

  1. Create a react native app using newest react native version
  2. Use hermes engine instead of default engine
  3. To the entry point of the app add once
    const test = new RegExp("", "yu");

    which works without throwing error.

  4. Change this to the pattern:
    const test = new RegExp("([^\\p{White_Space}\\p{Pattern_Syntax}]*)", "yu");

    which will cause the application to throw errors.

The Expected Behavior

I am not sure if this is due to the fact that "yu" are not supported or something different. If "yu" are not supported as options it should throw when calling new RegExp("", "yu"). If "yu" is supported then I think the regex should just work 🤔

// Edit:

when not adding "yu" as option the regex works without throwing.

neildhar commented 3 years ago

Hi @hannojg, thanks for bringing this up. We target ES2015 and do support the "y" and "u" flags. However, Unicode property escapes (the \p{} syntax) was introduced in ES2018, and is currently unsupported.

You may be able to get this functionality with a babel transform. Is that an option for you?

hannojg commented 3 years ago

Hmm, currently we just use this kind of regex through the named library. We created a PR at the lib to better handle the case when their regex isn't supported, so we currently have no need to get this functionality with a babel transform, but it's good to know that we could achieve it this way, thx.