[webkit-changes] cvs commit: JavaScriptCore/kjs date_object.cpp
Geoffrey
ggaren at opensource.apple.com
Wed Sep 7 16:27:28 PDT 2005
ggaren 05/09/07 16:27:28
Modified: . ChangeLog
kjs date_object.cpp
Log:
-fixed http://bugzilla.opendarwin.org/show_bug.cgi?id=4781
Date.setMonth fails with big values due to overflow
Reviewed by darin.
* kjs/date_object.cpp:
(timetUsingCF): for consistency, changed return statement to invalidDate instead of LONG_MAX
(KJS::fillStructuresUsingTimeArgs): modified for readability
(KJS::fillStructuresUsingDateArgs): new function analogous to fillStructuresUsingTimeArgs
(KJS::DateProtoFuncImp::callAsFunction): modified to use fillStructuresUsingDateArgs
(KJS::DateObjectImp::construct): moved variable declaration to proper scope
(KJS::DateObjectFuncImp::callAsFunction): moved variable declaration to proper scope
Revision Changes Path
1.818 +15 -0 JavaScriptCore/ChangeLog
Index: ChangeLog
===================================================================
RCS file: /cvs/root/JavaScriptCore/ChangeLog,v
retrieving revision 1.817
retrieving revision 1.818
diff -u -r1.817 -r1.818
--- ChangeLog 7 Sep 2005 22:08:54 -0000 1.817
+++ ChangeLog 7 Sep 2005 23:27:27 -0000 1.818
@@ -1,4 +1,19 @@
2005-09-07 Geoffrey Garen <ggaren at apple.com>
+
+ -fixed http://bugzilla.opendarwin.org/show_bug.cgi?id=4781
+ Date.setMonth fails with big values due to overflow
+
+ Reviewed by darin.
+
+ * kjs/date_object.cpp:
+ (timetUsingCF): for consistency, changed return statement to invalidDate instead of LONG_MAX
+ (KJS::fillStructuresUsingTimeArgs): modified for readability
+ (KJS::fillStructuresUsingDateArgs): new function analogous to fillStructuresUsingTimeArgs
+ (KJS::DateProtoFuncImp::callAsFunction): modified to use fillStructuresUsingDateArgs
+ (KJS::DateObjectImp::construct): moved variable declaration to proper scope
+ (KJS::DateObjectFuncImp::callAsFunction): moved variable declaration to proper scope
+
+2005-09-07 Geoffrey Garen <ggaren at apple.com>
-updated expected test results to reflect fix for
http://bugzilla.opendarwin.org/show_bug.cgi?id=4698
kjs does not allow named functions in function expressions
1.55 +71 -30 JavaScriptCore/kjs/date_object.cpp
Index: date_object.cpp
===================================================================
RCS file: /cvs/root/JavaScriptCore/kjs/date_object.cpp,v
retrieving revision 1.54
retrieving revision 1.55
diff -u -r1.54 -r1.55
--- date_object.cpp 4 Sep 2005 06:21:54 -0000 1.54
+++ date_object.cpp 7 Sep 2005 23:27:28 -0000 1.55
@@ -201,7 +201,7 @@
CFTimeInterval interval = absoluteTime + kCFAbsoluteTimeIntervalSince1970;
if (interval > LONG_MAX) {
- interval = LONG_MAX;
+ return invalidDate;
}
return (time_t) interval;
@@ -403,34 +403,81 @@
#endif
}
-static double timeFromArgs(ExecState *exec, const List &args, int maxArgs, double ms, struct tm *t)
+// Converts a list of arguments sent to a Date member function into milliseconds, updating
+// ms (representing milliseconds) and t (representing the rest of the date structure) appropriately.
+//
+// Format of member function: f([hour,] [min,] [sec,] [ms])
+static void fillStructuresUsingTimeArgs(ExecState *exec, const List &args, int maxArgs, double *ms, struct tm *t)
{
- double result = 0;
+ double milliseconds = 0;
int idx = 0;
int numArgs = args.size();
- // process up to max_args arguments
+ // JS allows extra trailing arguments -- ignore them
if (numArgs > maxArgs)
numArgs = maxArgs;
+
// hours
if (maxArgs >= 4 && idx < numArgs) {
t->tm_hour = 0;
- result = args[idx++]->toInt32(exec) * msPerHour;
+ milliseconds += args[idx++]->toInt32(exec) * msPerHour;
}
+
// minutes
if (maxArgs >= 3 && idx < numArgs) {
t->tm_min = 0;
- result += args[idx++]->toInt32(exec) * msPerMinute;
+ milliseconds += args[idx++]->toInt32(exec) * msPerMinute;
}
+
// seconds
if (maxArgs >= 2 && idx < numArgs) {
t->tm_sec = 0;
- result += args[idx++]->toInt32(exec) * msPerSecond;
+ milliseconds += args[idx++]->toInt32(exec) * msPerSecond;
}
- // read ms from args if present or add the old value
- result += idx < numArgs ? roundValue(exec, args[idx]) : ms;
-
- return result;
+
+ // milliseconds
+ if (idx < numArgs) {
+ milliseconds += roundValue(exec, args[idx]);
+ } else {
+ milliseconds += *ms;
+ }
+
+ *ms = milliseconds;
+}
+
+// Converts a list of arguments sent to a Date member function into years, months, and milliseconds, updating
+// ms (representing milliseconds) and t (representing the rest of the date structure) appropriately.
+//
+// Format of member function: f([years,] [months,] [days])
+static void fillStructuresUsingDateArgs(ExecState *exec, const List &args, int maxArgs, double *ms, struct tm *t)
+{
+ int idx = 0;
+ int numArgs = args.size();
+
+ // JS allows extra trailing arguments -- ignore them
+ if (numArgs > maxArgs)
+ numArgs = maxArgs;
+
+ // years
+ if (maxArgs >= 3 && idx < numArgs) {
+ t->tm_year = args[idx++]->toInt32(exec) - 1900;
+ }
+
+ // months
+ if (maxArgs >= 2 && idx < numArgs) {
+ int months = args[idx++]->toInt32(exec);
+
+ // t->tm_year must hold the bulk of the data to avoid overflow when converting
+ // to a CFGregorianDate. (CFGregorianDate.month is an SInt8; CFGregorianDate.year is an SInt32.)
+ t->tm_year += months / 12;
+ t->tm_mon = months % 12;
+ }
+
+ // days
+ if (idx < numArgs) {
+ t->tm_mday = 0;
+ *ms += args[idx]->toInt32(exec) * msPerDay;
+ }
}
// ------------------------------ DateInstanceImp ------------------------------
@@ -722,32 +769,25 @@
thisObj->setInternalValue(result);
break;
case SetMilliSeconds:
- ms = roundValue(exec, args[0]);
+ fillStructuresUsingTimeArgs(exec, args, 1, &ms, t);
break;
case SetSeconds:
- ms = timeFromArgs(exec, args, 2, ms, t);
+ fillStructuresUsingTimeArgs(exec, args, 2, &ms, t);
break;
case SetMinutes:
- ms = timeFromArgs(exec, args, 3, ms, t);
+ fillStructuresUsingTimeArgs(exec, args, 3, &ms, t);
break;
case SetHours:
- ms = timeFromArgs(exec, args, 4, ms, t);
+ fillStructuresUsingTimeArgs(exec, args, 4, &ms, t);
break;
case SetDate:
- t->tm_mday = 0;
- ms += args[0]->toInt32(exec) * msPerDay;
- break;
+ fillStructuresUsingDateArgs(exec, args, 1, &ms, t);
+ break;
case SetMonth:
- t->tm_mon = args[0]->toInt32(exec);
- if (args.size() >= 2)
- t->tm_mday = args[1]->toInt32(exec);
+ fillStructuresUsingDateArgs(exec, args, 2, &ms, t);
break;
case SetFullYear:
- t->tm_year = args[0]->toInt32(exec) - 1900;
- if (args.size() >= 2)
- t->tm_mon = args[1]->toInt32(exec);
- if (args.size() >= 3)
- t->tm_mday = args[2]->toInt32(exec);
+ fillStructuresUsingDateArgs(exec, args, 3, &ms, t);
break;
case SetYear:
t->tm_year = args[0]->toInt32(exec) >= 1900 ? args[0]->toInt32(exec) - 1900 : args[0]->toInt32(exec);
@@ -822,8 +862,6 @@
else
value = args[0]->toPrimitive(exec)->toNumber(exec);
} else {
- struct tm t;
- memset(&t, 0, sizeof(t));
if (isNaN(args[0]->toNumber(exec))
|| isNaN(args[1]->toNumber(exec))
|| (numArgs >= 3 && isNaN(args[2]->toNumber(exec)))
@@ -833,6 +871,8 @@
|| (numArgs >= 7 && isNaN(args[6]->toNumber(exec)))) {
value = NaN;
} else {
+ struct tm t;
+ memset(&t, 0, sizeof(t));
int year = args[0]->toInt32(exec);
t.tm_year = (year >= 0 && year <= 99) ? year : year - 1900;
t.tm_mon = args[1]->toInt32(exec);
@@ -892,8 +932,6 @@
return Number(parseDate(args[0]->toString(exec)));
}
else { // UTC
- struct tm t;
- memset(&t, 0, sizeof(t));
int n = args.size();
if (isNaN(args[0]->toNumber(exec))
|| isNaN(args[1]->toNumber(exec))
@@ -904,6 +942,9 @@
|| (n >= 7 && isNaN(args[6]->toNumber(exec)))) {
return Number(NaN);
}
+
+ struct tm t;
+ memset(&t, 0, sizeof(t));
int year = args[0]->toInt32(exec);
t.tm_year = (year >= 0 && year <= 99) ? year : year - 1900;
t.tm_mon = args[1]->toInt32(exec);
More information about the webkit-changes
mailing list