icu-messageformat-parser: unguarded \p{White_Space}/\p{Pattern_Syntax} RegExp crashes at module load on engines without those property names (regression vs. the old REGEX_SUPPORTS_U_AND_Y detection)
What happens
@formatjs/[email protected] throws at module evaluation time on JS engines that support the u / y regex flags but do not recognise the White_Space / Pattern_Syntax Unicode property names.
Observed on a real Android device running a WeChat Mini Program (WeChat's Android JS runtime is V8):
MiniProgramError
Invalid regular expression: /([^\p{White_Space}\p{Pattern_Syntax}]*)/uy: Invalid property name in character class
SyntaxError: Invalid regular expression: ...
at new RegExp (<anonymous>)
at 7801 (https://usr/appservice.app.js:6113:38216)
...Because it happens while the module graph is still being evaluated, it is not catchable by the application:
[wxapplib] Error during require queue flushing
TypeError: Cannot read properties of null (reading 'mount')
TypeError: Cannot read properties of null (reading 'unmount')The result is a completely blank app. React never mounts, so error boundaries never run and nothing is logged by the app itself. iOS (JavaScriptCore) and the desktop simulator (Chromium) are unaffected — the bug is invisible outside that one engine family.
Where
@formatjs/[email protected], ESM build, index.js:1409:
const IDENTIFIER_PREFIX_RE = new RegExp("([^\\p{White_Space}\\p{Pattern_Syntax}]*)", "yu");Top level, unconditional, const.
Why this looks like a regression
Older bundled copies of this parser guarded exactly this case. For example the parser vendored inside [email protected] still contains:
// IE11 does not support y and u.
var REGEX_SUPPORTS_U_AND_Y = true;
try {
var re = RE('([^\\p{White_Space}\\p{Pattern_Syntax}]*)', 'yu');
/**
* legacy Edge or Xbox One browser
* Unicode flag support: supported
* Pattern_Syntax support: not supported
* See https://github.com/formatjs/formatjs/issues/2822
*/
REGEX_SUPPORTS_U_AND_Y = re.exec('a')?.[0] === 'a';
} catch (_) {
REGEX_SUPPORTS_U_AND_Y = false;
}…together with a hand-written fallback that the comments describe as the code point equivalent of \p{White_Space} and \p{Pattern_Syntax}, selected by if (REGEX_SUPPORTS_U_AND_Y) { … } else { … }.
In 3.5.17 the detection variable does not appear at all (grep -c REGEX_SUPPORTS_U_AND_Y → 0), and the regex is constructed unconditionally. So engines in precisely the category that the old comment called out — "Unicode flag support: supported / Pattern_Syntax support: not supported", the case tracked in #2822 — went from degrading to the fallback to crashing on import.
Impact
For bundled targets this is unrecoverable from the application side: the throw happens during module evaluation, before any application code runs, so it cannot be caught, feature-detected around, or reported by the app. Consumers only see a blank screen on the affected engine.
It is also invisible to static checks. The regex is built from a string via new RegExp, so transpilation targets, browserslist, and AST-level linting all pass — the bundle is valid ES5 and still crashes at runtime.
Suggested fix
Restore the runtime detection and the code-point fallback that earlier versions shipped, or construct IDENTIFIER_PREFIX_RE lazily inside a try/catch so that a failure can fall back rather than take down module evaluation.
Environment
@formatjs/icu-messageformat-parser3.5.17 (reached viaintl-messageformat←[email protected])- WeChat Mini Program, Android client (V8); confirmed working on iOS (JavaScriptCore) and in the desktop simulator with the identical bundle
- Bundled with webpack via Taro 4.2.1; the ESM entry is the one selected
Source: formatjs/formatjs