From: mvstanton@chromium.org Date: Wed, 30 Apr 2014 07:36:12 +0000 (+0000) Subject: Bugfix: internationalization routines fail on monkeypatching. X-Git-Tag: upstream/4.7.83~9338 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0c3e70a3b6ae14d9eb15e097f5d4115b2caa18b0;p=platform%2Fupstream%2Fv8.git Bugfix: internationalization routines fail on monkeypatching. Calls to Object.defineProperty() and Object.apply() are not safe. R=mstarzinger@chromium.org Review URL: https://codereview.chromium.org/253903003 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@21071 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/i18n.js b/src/i18n.js index b251e29..5819d2c 100644 --- a/src/i18n.js +++ b/src/i18n.js @@ -258,7 +258,7 @@ function addBoundMethod(obj, methodName, implementation, length) { %FunctionRemovePrototype(getter); %SetNativeFlag(getter); - $Object.defineProperty(obj.prototype, methodName, { + ObjectDefineProperty(obj.prototype, methodName, { get: getter, enumerable: false, configurable: true @@ -593,15 +593,14 @@ function setOptions(inOptions, extensionMap, keyValues, getOption, outOptions) { */ function freezeArray(array) { array.forEach(function(element, index) { - $Object.defineProperty(array, index, {value: element, + ObjectDefineProperty(array, index, {value: element, configurable: false, writable: false, enumerable: true}); }); - $Object.defineProperty(array, 'length', {value: array.length, - writable: false}); - + ObjectDefineProperty(array, 'length', {value: array.length, + writable: false}); return array; } @@ -662,8 +661,8 @@ function getAvailableLocalesOf(service) { * Configurable is false by default. */ function defineWEProperty(object, property, value) { - $Object.defineProperty(object, property, - {value: value, writable: true, enumerable: true}); + ObjectDefineProperty(object, property, + {value: value, writable: true, enumerable: true}); } @@ -682,11 +681,11 @@ function addWEPropertyIfDefined(object, property, value) { * Defines a property and sets writable, enumerable and configurable to true. */ function defineWECProperty(object, property, value) { - $Object.defineProperty(object, property, - {value: value, - writable: true, - enumerable: true, - configurable: true}); + ObjectDefineProperty(object, property, + {value: value, + writable: true, + enumerable: true, + configurable: true}); } @@ -925,8 +924,8 @@ function initializeCollator(collator, locales, options) { // We define all properties C++ code may produce, to prevent security // problems. If malicious user decides to redefine Object.prototype.locale // we can't just use plain x.locale = 'us' or in C++ Set("locale", "us"). - // Object.defineProperties will either succeed defining or throw an error. - var resolved = $Object.defineProperties({}, { + // ObjectDefineProperties will either succeed defining or throw an error. + var resolved = ObjectDefineProperties({}, { caseFirst: {writable: true}, collation: {value: internalOptions.collation, writable: true}, ignorePunctuation: {writable: true}, @@ -944,7 +943,7 @@ function initializeCollator(collator, locales, options) { // Writable, configurable and enumerable are set to false by default. %MarkAsInitializedIntlObjectOfType(collator, 'collator', internalCollator); - $Object.defineProperty(collator, 'resolved', {value: resolved}); + ObjectDefineProperty(collator, 'resolved', {value: resolved}); return collator; } @@ -1141,7 +1140,7 @@ function initializeNumberFormat(numberFormat, locales, options) { getOption, internalOptions); var requestedLocale = locale.locale + extension; - var resolved = $Object.defineProperties({}, { + var resolved = ObjectDefineProperties({}, { currency: {writable: true}, currencyDisplay: {writable: true}, locale: {writable: true}, @@ -1166,12 +1165,12 @@ function initializeNumberFormat(numberFormat, locales, options) { // We can't get information about number or currency style from ICU, so we // assume user request was fulfilled. if (internalOptions.style === 'currency') { - $Object.defineProperty(resolved, 'currencyDisplay', {value: currencyDisplay, - writable: true}); + ObjectDefineProperty(resolved, 'currencyDisplay', {value: currencyDisplay, + writable: true}); } %MarkAsInitializedIntlObjectOfType(numberFormat, 'numberformat', formatter); - $Object.defineProperty(numberFormat, 'resolved', {value: resolved}); + ObjectDefineProperty(numberFormat, 'resolved', {value: resolved}); return numberFormat; } @@ -1443,13 +1442,11 @@ function appendToDateTimeObject(options, option, match, pairs) { */ function toDateTimeOptions(options, required, defaults) { if (options === undefined) { - options = null; + options = {}; } else { - options = toObject(options); + options = TO_OBJECT_INLINE(options); } - options = $Object.apply(this, [options]); - var needsDefault = true; if ((required === 'date' || required === 'any') && (options.weekday !== undefined || options.year !== undefined || @@ -1464,30 +1461,30 @@ function toDateTimeOptions(options, required, defaults) { } if (needsDefault && (defaults === 'date' || defaults === 'all')) { - $Object.defineProperty(options, 'year', {value: 'numeric', - writable: true, - enumerable: true, - configurable: true}); - $Object.defineProperty(options, 'month', {value: 'numeric', - writable: true, - enumerable: true, - configurable: true}); - $Object.defineProperty(options, 'day', {value: 'numeric', + ObjectDefineProperty(options, 'year', {value: 'numeric', + writable: true, + enumerable: true, + configurable: true}); + ObjectDefineProperty(options, 'month', {value: 'numeric', writable: true, enumerable: true, configurable: true}); + ObjectDefineProperty(options, 'day', {value: 'numeric', + writable: true, + enumerable: true, + configurable: true}); } if (needsDefault && (defaults === 'time' || defaults === 'all')) { - $Object.defineProperty(options, 'hour', {value: 'numeric', + ObjectDefineProperty(options, 'hour', {value: 'numeric', writable: true, enumerable: true, configurable: true}); - $Object.defineProperty(options, 'minute', {value: 'numeric', + ObjectDefineProperty(options, 'minute', {value: 'numeric', writable: true, enumerable: true, configurable: true}); - $Object.defineProperty(options, 'second', {value: 'numeric', + ObjectDefineProperty(options, 'second', {value: 'numeric', writable: true, enumerable: true, configurable: true}); @@ -1538,7 +1535,7 @@ function initializeDateTimeFormat(dateFormat, locales, options) { getOption, internalOptions); var requestedLocale = locale.locale + extension; - var resolved = $Object.defineProperties({}, { + var resolved = ObjectDefineProperties({}, { calendar: {writable: true}, day: {writable: true}, era: {writable: true}, @@ -1566,7 +1563,7 @@ function initializeDateTimeFormat(dateFormat, locales, options) { } %MarkAsInitializedIntlObjectOfType(dateFormat, 'dateformat', formatter); - $Object.defineProperty(dateFormat, 'resolved', {value: resolved}); + ObjectDefineProperty(dateFormat, 'resolved', {value: resolved}); return dateFormat; } @@ -1760,7 +1757,7 @@ function initializeBreakIterator(iterator, locales, options) { 'type', 'string', ['character', 'word', 'sentence', 'line'], 'word')); var locale = resolveLocale('breakiterator', locales, options); - var resolved = $Object.defineProperties({}, { + var resolved = ObjectDefineProperties({}, { requestedLocale: {value: locale.locale, writable: true}, type: {value: internalOptions.type, writable: true}, locale: {writable: true} @@ -1772,7 +1769,7 @@ function initializeBreakIterator(iterator, locales, options) { %MarkAsInitializedIntlObjectOfType(iterator, 'breakiterator', internalIterator); - $Object.defineProperty(iterator, 'resolved', {value: resolved}); + ObjectDefineProperty(iterator, 'resolved', {value: resolved}); return iterator; } @@ -1938,7 +1935,7 @@ function cachedOrNewService(service, locales, options, defaults) { * Compares this and that, and returns less than 0, 0 or greater than 0 value. * Overrides the built-in method. */ -$Object.defineProperty($String.prototype, 'localeCompare', { +ObjectDefineProperty($String.prototype, 'localeCompare', { value: function(that) { if (%_IsConstructCall()) { throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); @@ -1969,7 +1966,7 @@ $Object.defineProperty($String.prototype, 'localeCompare', { * If the form is not one of "NFC", "NFD", "NFKC", or "NFKD", then throw * a RangeError Exception. */ -$Object.defineProperty($String.prototype, 'normalize', { +ObjectDefineProperty($String.prototype, 'normalize', { value: function(that) { if (%_IsConstructCall()) { throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); @@ -2000,7 +1997,7 @@ $Object.defineProperty($String.prototype, 'normalize', { * Formats a Number object (this) using locale and options values. * If locale or options are omitted, defaults are used. */ -$Object.defineProperty($Number.prototype, 'toLocaleString', { +ObjectDefineProperty($Number.prototype, 'toLocaleString', { value: function() { if (%_IsConstructCall()) { throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); @@ -2050,7 +2047,7 @@ function toLocaleDateTime(date, locales, options, required, defaults, service) { * If locale or options are omitted, defaults are used - both date and time are * present in the output. */ -$Object.defineProperty($Date.prototype, 'toLocaleString', { +ObjectDefineProperty($Date.prototype, 'toLocaleString', { value: function() { if (%_IsConstructCall()) { throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); @@ -2075,7 +2072,7 @@ $Object.defineProperty($Date.prototype, 'toLocaleString', { * If locale or options are omitted, defaults are used - only date is present * in the output. */ -$Object.defineProperty($Date.prototype, 'toLocaleDateString', { +ObjectDefineProperty($Date.prototype, 'toLocaleDateString', { value: function() { if (%_IsConstructCall()) { throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); @@ -2100,7 +2097,7 @@ $Object.defineProperty($Date.prototype, 'toLocaleDateString', { * If locale or options are omitted, defaults are used - only time is present * in the output. */ -$Object.defineProperty($Date.prototype, 'toLocaleTimeString', { +ObjectDefineProperty($Date.prototype, 'toLocaleTimeString', { value: function() { if (%_IsConstructCall()) { throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); diff --git a/test/mjsunit/regress/regress-builtinbust-7.js b/test/mjsunit/regress/regress-builtinbust-7.js new file mode 100644 index 0000000..7d883b8 --- /dev/null +++ b/test/mjsunit/regress/regress-builtinbust-7.js @@ -0,0 +1,30 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +function overflow() { + return overflow() + 1; +} +Object.defineProperty = overflow; +assertDoesNotThrow(function() { Intl.Collator.supportedLocalesOf("en"); }); + +var date = new Date(Date.UTC(2004, 12, 25, 3, 0, 0)); +var options = { + weekday: "long", + year: "numeric", + month: "long", + day: "numeric" +}; + +Object.apply = overflow; +assertDoesNotThrow(function() { date.toLocaleDateString("de-DE", options); }); + +var options_incomplete = {}; +assertDoesNotThrow(function() { + date.toLocaleDateString("de-DE", options_incomplete); +}); +assertTrue(options_incomplete.hasOwnProperty("year")); + +assertDoesNotThrow(function() { date.toLocaleDateString("de-DE", undefined); }); +assertDoesNotThrow(function() { date.toLocaleDateString("de-DE"); }); +assertThrows(function() { date.toLocaleDateString("de-DE", null); }, TypeError);