From d5d69fd39a1bfdf3cb263a96f37f2afdab485c29 Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Mon, 10 Oct 2016 16:44:23 -0700 Subject: [PATCH] intl: Don't crash if v8BreakIterator not available If the undocumented v8BreakIterator does not have data available, monkeypatch it to throw an error instead of crashing. Fixes: https://github.com/nodejs/node/issues/3111 Ref: https://github.com/nodejs/node/pull/9008 PR-URL: https://github.com/nodejs/node/pull/4253 Reviewed-By: James M Snell Reviewed-By: Ben Noordhuis --- src/node.cc | 7 +++++++ src/node.js | 16 ++++++++++++++++ test/parallel/test-intl-v8BreakIterator.js | 15 +++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 test/parallel/test-intl-v8BreakIterator.js diff --git a/src/node.cc b/src/node.cc index 23b1009616466f..0501372490188c 100644 --- a/src/node.cc +++ b/src/node.cc @@ -2858,6 +2858,13 @@ void SetupProcessObject(Environment* env, READONLY_PROPERTY(versions, "icu", OneByteString(env->isolate(), U_ICU_VERSION)); + + if (icu_data_dir != nullptr) { + // Did the user attempt (via env var or parameter) to set an ICU path? + READONLY_PROPERTY(process, + "icu_data_dir", + OneByteString(env->isolate(), icu_data_dir)); + } #endif const char node_modules_version[] = NODE_STRINGIFY(NODE_MODULE_VERSION); diff --git a/src/node.js b/src/node.js index a4d86da6a93a69..7772942de79ca1 100644 --- a/src/node.js +++ b/src/node.js @@ -266,6 +266,22 @@ process.config = JSON.parse(config, function(key, value) { if (value === 'true') return true; if (value === 'false') return false; + + // Intl.v8BreakIterator() would crash w/ fatal error, so throw instead. + if (value.icu_small && + global.hasOwnProperty('Intl') && + Intl.hasOwnProperty('v8BreakIterator') && + !process.icu_data_dir) { + const des = Object.getOwnPropertyDescriptor(Intl, 'v8BreakIterator'); + des.value = function v8BreakIterator() { + throw new Error('v8BreakIterator: full ICU data not installed. ' + + 'See https://github.com/nodejs/node/wiki/Intl'); + }; + Object.defineProperty(Intl, 'v8BreakIterator', des); + } + // Don’t let icu_data_dir leak through. + delete process.icu_data_dir; + return value; }); }; diff --git a/test/parallel/test-intl-v8BreakIterator.js b/test/parallel/test-intl-v8BreakIterator.js new file mode 100644 index 00000000000000..6e25c32cd743d3 --- /dev/null +++ b/test/parallel/test-intl-v8BreakIterator.js @@ -0,0 +1,15 @@ +'use strict'; +require('../common'); +const assert = require('assert'); + +if (global.Intl === undefined || Intl.v8BreakIterator === undefined) { + return console.log('1..0 # Skipped: no Intl'); +} + +try { + new Intl.v8BreakIterator(); + // May succeed if data is available - OK +} catch (e) { + // May throw this error if ICU data is not available - OK + assert.throws(() => new Intl.v8BreakIterator(), /ICU data/); +}