Skip to content

Commit 5839167

Browse files
committed
[Robustness] cache Date getUTC* methods so that Date#toISOString doesn’t observably look them up on the receiver.
- Date#getUTCFullYear - Date#getUTCMonth - Date#getUTCDate - Date#getUTCHours - Date#getUTCMinutes - Date#getUTCSeconds - Date#getUTCMilliseconds This should also help expose the true cause of es-shims#365.
1 parent 6ec68d1 commit 5839167

File tree

1 file changed

+44
-62
lines changed

1 file changed

+44
-62
lines changed

es5-shim.js

Lines changed: 44 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,42 +1091,30 @@ if (timeZoneOffset < -720) {
10911091
hasToStringFormatBug = !(/^Wed Dec 09 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/).test(aPositiveTestDate.toString());
10921092
}
10931093

1094-
var originalGetFullYear;
1095-
var originalGetMonth;
1096-
var originalGetDate;
1097-
var originalGetUTCFullYear;
1098-
var originalGetUTCMonth;
1099-
var originalGetUTCDate;
1100-
var originalToUTCString;
1101-
var originalToDateString;
1102-
var originalToString;
1103-
var dayName;
1104-
var monthName;
1105-
var daysInMonth;
1106-
if (hasNegativeMonthYearBug || hasToDateStringFormatBug || hasToUTCStringFormatBug || hasToStringFormatBug) {
1107-
originalGetFullYear = Date.prototype.getFullYear;
1108-
originalGetMonth = Date.prototype.getMonth;
1109-
originalGetDate = Date.prototype.getDate;
1110-
originalGetUTCFullYear = Date.prototype.getUTCFullYear;
1111-
originalGetUTCMonth = Date.prototype.getUTCMonth;
1112-
originalGetUTCDate = Date.prototype.getUTCDate;
1113-
originalToUTCString = Date.prototype.toUTCString;
1114-
originalToDateString = Date.prototype.toDateString;
1115-
originalToString = Date.prototype.toString;
1116-
dayName = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri'];
1117-
monthName = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
1118-
daysInMonth = function dim(month, year) {
1119-
return originalGetDate.call(new Date(year, month, 0));
1120-
};
1121-
}
1094+
var originalGetFullYear = call.bind(Date.prototype.getFullYear);
1095+
var originalGetMonth = call.bind(Date.prototype.getMonth);
1096+
var originalGetDate = call.bind(Date.prototype.getDate);
1097+
var originalGetUTCFullYear = call.bind(Date.prototype.getUTCFullYear);
1098+
var originalGetUTCMonth = call.bind(Date.prototype.getUTCMonth);
1099+
var originalGetUTCDate = call.bind(Date.prototype.getUTCDate);
1100+
var originalGetUTCDay = call.bind(Date.prototype.getUTCDay);
1101+
var originalGetUTCHours = call.bind(Date.prototype.getUTCHours);
1102+
var originalGetUTCMinutes = call.bind(Date.prototype.getUTCMinutes);
1103+
var originalGetUTCSeconds = call.bind(Date.prototype.getUTCSeconds);
1104+
var originalGetUTCMilliseconds = call.bind(Date.prototype.getUTCMilliseconds);
1105+
var dayName = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri'];
1106+
var monthName = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
1107+
var daysInMonth = function daysInMonth(month, year) {
1108+
return originalGetDate(new Date(year, month, 0));
1109+
};
11221110

11231111
defineProperties(Date.prototype, {
11241112
getFullYear: function getFullYear() {
11251113
if (!this || !(this instanceof Date)) {
11261114
throw new TypeError('this is not a Date object.');
11271115
}
1128-
var year = originalGetFullYear.call(this);
1129-
if (year < 0 && originalGetMonth.call(this) > 11) {
1116+
var year = originalGetFullYear(this);
1117+
if (year < 0 && originalGetMonth(this) > 11) {
11301118
return year + 1;
11311119
}
11321120
return year;
@@ -1135,8 +1123,8 @@ defineProperties(Date.prototype, {
11351123
if (!this || !(this instanceof Date)) {
11361124
throw new TypeError('this is not a Date object.');
11371125
}
1138-
var year = originalGetFullYear.call(this);
1139-
var month = originalGetMonth.call(this);
1126+
var year = originalGetFullYear(this);
1127+
var month = originalGetMonth(this);
11401128
if (year < 0 && month > 11) {
11411129
return 0;
11421130
}
@@ -1146,9 +1134,9 @@ defineProperties(Date.prototype, {
11461134
if (!this || !(this instanceof Date)) {
11471135
throw new TypeError('this is not a Date object.');
11481136
}
1149-
var year = originalGetFullYear.call(this);
1150-
var month = originalGetMonth.call(this);
1151-
var date = originalGetDate.call(this);
1137+
var year = originalGetFullYear(this);
1138+
var month = originalGetMonth(this);
1139+
var date = originalGetDate(this);
11521140
if (year < 0 && month > 11) {
11531141
if (month === 12) {
11541142
return date;
@@ -1162,8 +1150,8 @@ defineProperties(Date.prototype, {
11621150
if (!this || !(this instanceof Date)) {
11631151
throw new TypeError('this is not a Date object.');
11641152
}
1165-
var year = originalGetUTCFullYear.call(this);
1166-
if (year < 0 && originalGetUTCMonth.call(this) > 11) {
1153+
var year = originalGetUTCFullYear(this);
1154+
if (year < 0 && originalGetUTCMonth(this) > 11) {
11671155
return year + 1;
11681156
}
11691157
return year;
@@ -1172,8 +1160,8 @@ defineProperties(Date.prototype, {
11721160
if (!this || !(this instanceof Date)) {
11731161
throw new TypeError('this is not a Date object.');
11741162
}
1175-
var year = originalGetUTCFullYear.call(this);
1176-
var month = originalGetUTCMonth.call(this);
1163+
var year = originalGetUTCFullYear(this);
1164+
var month = originalGetUTCMonth(this);
11771165
if (year < 0 && month > 11) {
11781166
return 0;
11791167
}
@@ -1183,9 +1171,9 @@ defineProperties(Date.prototype, {
11831171
if (!this || !(this instanceof Date)) {
11841172
throw new TypeError('this is not a Date object.');
11851173
}
1186-
var year = originalGetUTCFullYear.call(this);
1187-
var month = originalGetUTCMonth.call(this);
1188-
var date = originalGetUTCDate.call(this);
1174+
var year = originalGetUTCFullYear(this);
1175+
var month = originalGetUTCMonth(this);
1176+
var date = originalGetUTCDate(this);
11891177
if (year < 0 && month > 11) {
11901178
if (month === 12) {
11911179
return date;
@@ -1202,13 +1190,13 @@ defineProperties(Date.prototype, {
12021190
if (!this || !(this instanceof Date)) {
12031191
throw new TypeError('this is not a Date object.');
12041192
}
1205-
var day = this.getUTCDay();
1206-
var date = this.getUTCDate();
1207-
var month = this.getUTCMonth();
1208-
var year = this.getUTCFullYear();
1209-
var hour = this.getUTCHours();
1210-
var minute = this.getUTCMinutes();
1211-
var second = this.getUTCSeconds();
1193+
var day = originalGetUTCDay(this);
1194+
var date = originalGetUTCDate(this);
1195+
var month = originalGetUTCMonth(this);
1196+
var year = originalGetUTCFullYear(this);
1197+
var hour = originalGetUTCHours(this);
1198+
var minute = originalGetUTCMinutes(this);
1199+
var second = originalGetUTCSeconds(this);
12121200
return dayName[day] + ', ' +
12131201
(date < 10 ? '0' + date : date) + ' ' +
12141202
monthName[month] + ' ' +
@@ -1286,39 +1274,33 @@ var hasSafari51DateBug = Date.prototype.toISOString && new Date(-1).toISOString(
12861274

12871275
defineProperties(Date.prototype, {
12881276
toISOString: function toISOString() {
1289-
var result, length, value, year, month;
12901277
if (!isFinite(this)) {
12911278
throw new RangeError('Date.prototype.toISOString called on non-finite value.');
12921279
}
12931280

1294-
year = this.getUTCFullYear();
1281+
var year = originalGetUTCFullYear(this);
12951282

1296-
month = this.getUTCMonth();
1283+
var month = originalGetUTCMonth(this);
12971284
// see https://github.com/es-shims/es5-shim/issues/111
12981285
year += Math.floor(month / 12);
12991286
month = (month % 12 + 12) % 12;
13001287

13011288
// the date time string format is specified in 15.9.1.15.
1302-
result = [month + 1, this.getUTCDate(), this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds()];
1289+
var result = [month + 1, originalGetUTCDate(this), originalGetUTCHours(this), originalGetUTCMinutes(this), originalGetUTCSeconds(this)];
13031290
year = (
13041291
(year < 0 ? '-' : (year > 9999 ? '+' : '')) +
13051292
strSlice('00000' + Math.abs(year), (0 <= year && year <= 9999) ? -4 : -6)
13061293
);
13071294

1308-
length = result.length;
1309-
while (length--) {
1310-
value = result[length];
1311-
// pad months, days, hours, minutes, and seconds to have two
1312-
// digits.
1313-
if (value < 10) {
1314-
result[length] = '0' + value;
1315-
}
1295+
for (var i = 0; i < result.length; ++i) {
1296+
// pad months, days, hours, minutes, and seconds to have two digits.
1297+
result[i] = strSlice('00' + result[i], -2);
13161298
}
13171299
// pad milliseconds to have three digits.
13181300
return (
13191301
year + '-' + arraySlice(result, 0, 2).join('-') +
13201302
'T' + arraySlice(result, 2).join(':') + '.' +
1321-
strSlice('000' + this.getUTCMilliseconds(), -3) + 'Z'
1303+
strSlice('000' + originalGetUTCMilliseconds(this), -3) + 'Z'
13221304
);
13231305
}
13241306
}, hasNegativeDateBug || hasSafari51DateBug);

0 commit comments

Comments
 (0)