Changeset 30453 in webkit


Ignore:
Timestamp:
Feb 20, 2008 8:50:47 PM (16 years ago)
Author:
weinig@apple.com
Message:

JavaScriptCore:

Reviewed by Darin.

Fix for Bug 16753: date set methods with no args should result in NaN (Acid3 bug)
The set values result in NaN now when called with no args, NaN or +/- inf values.
The setYear, setFullYear and setUTCFullYear methods used on NaN dates work as
descripted in the standard.

  • kjs/date_object.cpp: (KJS::fillStructuresUsingTimeArgs): (KJS::fillStructuresUsingDateArgs): (KJS::setNewValueFromTimeArgs): (KJS::setNewValueFromDateArgs): (KJS::dateProtoFuncSetYear):

LayoutTests:

Reviewed by Darin.

  • test for Bug 16753: date set methods with no args should result in NaN (Acid3 bug)
  • fast/js/date-set-to-nan-expected.txt: Added.
  • fast/js/date-set-to-nan.html: Added.
  • fast/js/resources/date-set-to-nan.js: Added.
Location:
trunk
Files:
3 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r30413 r30453  
     12008-02-20  Michael Knaup  <michael.knaup@mac.com>
     2
     3        Reviewed by Darin.
     4
     5        Fix for Bug 16753: date set methods with no args should result in NaN (Acid3 bug)
     6        The set values result in NaN now when called with no args, NaN or +/- inf values.
     7        The setYear, setFullYear and setUTCFullYear methods used on NaN dates work as
     8        descripted in the standard.
     9
     10        * kjs/date_object.cpp:
     11        (KJS::fillStructuresUsingTimeArgs):
     12        (KJS::fillStructuresUsingDateArgs):
     13        (KJS::setNewValueFromTimeArgs):
     14        (KJS::setNewValueFromDateArgs):
     15        (KJS::dateProtoFuncSetYear):
     16
    1172008-02-19  Anders Carlsson  <andersca@apple.com>
    218
  • trunk/JavaScriptCore/kjs/date_object.cpp

    r30387 r30453  
    247247//
    248248// Format of member function: f([hour,] [min,] [sec,] [ms])
    249 static void fillStructuresUsingTimeArgs(ExecState* exec, const List& args, int maxArgs, double* ms, GregorianDateTime* t)
     249static bool fillStructuresUsingTimeArgs(ExecState* exec, const List& args, int maxArgs, double* ms, GregorianDateTime* t)
    250250{
    251251    double milliseconds = 0;
     252    bool ok = true;
    252253    int idx = 0;
    253254    int numArgs = args.size();
     
    260261    if (maxArgs >= 4 && idx < numArgs) {
    261262        t->hour = 0;
    262         milliseconds += args[idx++]->toInt32(exec) * msPerHour;
     263        milliseconds += args[idx++]->toInt32(exec, ok) * msPerHour;
    263264    }
    264265
    265266    // minutes
    266     if (maxArgs >= 3 && idx < numArgs) {
     267    if (maxArgs >= 3 && idx < numArgs && ok) {
    267268        t->minute = 0;
    268         milliseconds += args[idx++]->toInt32(exec) * msPerMinute;
     269        milliseconds += args[idx++]->toInt32(exec, ok) * msPerMinute;
    269270    }
    270271   
    271272    // seconds
    272     if (maxArgs >= 2 && idx < numArgs) {
     273    if (maxArgs >= 2 && idx < numArgs && ok) {
    273274        t->second = 0;
    274         milliseconds += args[idx++]->toInt32(exec) * msPerSecond;
    275     }
    276    
     275        milliseconds += args[idx++]->toInt32(exec, ok) * msPerSecond;
     276    }
     277   
     278    if (!ok)
     279        return false;
     280       
    277281    // milliseconds
    278     if (idx < numArgs)
    279         milliseconds += args[idx]->toNumber(exec);
    280     else
     282    if (idx < numArgs) {
     283        double millis = args[idx]->toNumber(exec);
     284        ok = isfinite(millis);
     285        milliseconds += millis;
     286    } else
    281287        milliseconds += *ms;
    282288   
    283289    *ms = milliseconds;
     290    return ok;
    284291}
    285292
     
    288295//
    289296// Format of member function: f([years,] [months,] [days])
    290 static void fillStructuresUsingDateArgs(ExecState *exec, const List &args, int maxArgs, double *ms, GregorianDateTime *t)
     297static bool fillStructuresUsingDateArgs(ExecState *exec, const List &args, int maxArgs, double *ms, GregorianDateTime *t)
    291298{
    292299    int idx = 0;
     300    bool ok = true;
    293301    int numArgs = args.size();
    294302 
     
    299307    // years
    300308    if (maxArgs >= 3 && idx < numArgs)
    301         t->year = args[idx++]->toInt32(exec) - 1900;
    302  
     309        t->year = args[idx++]->toInt32(exec, ok) - 1900;
     310   
    303311    // months
    304     if (maxArgs >= 2 && idx < numArgs)
    305         t->month = args[idx++]->toInt32(exec);
    306  
     312    if (maxArgs >= 2 && idx < numArgs && ok)   
     313        t->month = args[idx++]->toInt32(exec, ok);
     314   
    307315    // days
    308     if (idx < numArgs) {
     316    if (idx < numArgs && ok) {   
    309317        t->monthDay = 0;
    310         *ms += args[idx]->toInt32(exec) * msPerDay;
    311     }
     318        *ms += args[idx]->toInt32(exec, ok) * msPerDay;
     319    }
     320   
     321    return ok;
    312322}
    313323
     
    14501460    JSValue* v = thisDateObj->internalValue();
    14511461    double milli = v->toNumber(exec);
     1462   
     1463    if (args.isEmpty() || isnan(milli)) {
     1464        JSValue* result = jsNaN();
     1465        thisDateObj->setInternalValue(result);
     1466        return result;
     1467    }
     1468     
    14521469    double secs = floor(milli / msPerSecond);
    14531470    double ms = milli - secs * msPerSecond;
     
    14561473    msToGregorianDateTime(milli, inputIsUTC, t);
    14571474
    1458     fillStructuresUsingTimeArgs(exec, args, numArgsToUse, &ms, &t);
    1459 
     1475    if (!fillStructuresUsingTimeArgs(exec, args, numArgsToUse, &ms, &t)) {
     1476        JSValue* result = jsNaN();
     1477        thisDateObj->setInternalValue(result);
     1478        return result;
     1479    }
     1480   
    14601481    JSValue* result = jsNumber(gregorianDateTimeToMS(t, ms, inputIsUTC));
    14611482    thisDateObj->setInternalValue(result);
     
    14691490
    14701491    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj);
    1471     JSValue* v = thisDateObj->internalValue();
    1472     double milli = v->toNumber(exec);
    1473     double secs = floor(milli / msPerSecond);
    1474     double ms = milli - secs * msPerSecond;
    1475 
    1476     GregorianDateTime t;
    1477     msToGregorianDateTime(milli, inputIsUTC, t);
    1478 
    1479     fillStructuresUsingDateArgs(exec, args, numArgsToUse, &ms, &t);
    1480 
     1492    if (args.isEmpty()) {
     1493        JSValue* result = jsNaN();
     1494        thisDateObj->setInternalValue(result);
     1495        return result;
     1496    }     
     1497   
     1498    JSValue* v = thisDateObj->internalValue();
     1499    double milli = v->toNumber(exec);
     1500    double ms = 0;
     1501
     1502    GregorianDateTime t;
     1503    if (numArgsToUse == 3 && isnan(milli))
     1504        // Based on ECMA 262 15.9.5.40 - .41 (set[UTC]FullYear)
     1505        // the time must be reset to +0 if it is NaN.
     1506        msToGregorianDateTime(0, true, t);
     1507    else {
     1508        double secs = floor(milli / msPerSecond);
     1509        ms = milli - secs * msPerSecond;
     1510        msToGregorianDateTime(milli, inputIsUTC, t);
     1511    }
     1512   
     1513    if (!fillStructuresUsingDateArgs(exec, args, numArgsToUse, &ms, &t)) {
     1514        JSValue* result = jsNaN();
     1515        thisDateObj->setInternalValue(result);
     1516        return result;
     1517    }
     1518           
    14811519    JSValue* result = jsNumber(gregorianDateTimeToMS(t, ms, inputIsUTC));
    14821520    thisDateObj->setInternalValue(result);
     
    15751613    const bool utc = false;
    15761614
    1577     DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj);
    1578     JSValue* v = thisDateObj->internalValue();
    1579     double milli = v->toNumber(exec);
    1580     double secs = floor(milli / msPerSecond);
    1581     double ms = milli - secs * msPerSecond;
    1582 
    1583     GregorianDateTime t;
    1584     msToGregorianDateTime(milli, utc, t);
    1585 
    1586     t.year = (args[0]->toInt32(exec) > 99 || args[0]->toInt32(exec) < 0) ? args[0]->toInt32(exec) - 1900 : args[0]->toInt32(exec);
    1587 
     1615    DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj);     
     1616    if (args.isEmpty()) {
     1617        JSValue* result = jsNaN();
     1618        thisDateObj->setInternalValue(result);
     1619        return result;
     1620    }
     1621   
     1622    JSValue* v = thisDateObj->internalValue();
     1623    double milli = v->toNumber(exec);
     1624    double ms = 0;
     1625
     1626    GregorianDateTime t;
     1627    if (isnan(milli))
     1628        // Based on ECMA 262 B.2.5 (setYear)
     1629        // the time must be reset to +0 if it is NaN.
     1630        msToGregorianDateTime(0, true, t);
     1631    else {   
     1632        double secs = floor(milli / msPerSecond);
     1633        ms = milli - secs * msPerSecond;
     1634        msToGregorianDateTime(milli, utc, t);
     1635    }
     1636   
     1637    bool ok = true;
     1638    int32_t year = args[0]->toInt32(exec, ok);
     1639    if (!ok) {
     1640        JSValue* result = jsNaN();
     1641        thisDateObj->setInternalValue(result);
     1642        return result;
     1643    }
     1644           
     1645    t.year = (year > 99 || year < 0) ? year - 1900 : year;
    15881646    JSValue* result = jsNumber(gregorianDateTimeToMS(t, ms, utc));
    15891647    thisDateObj->setInternalValue(result);
  • trunk/LayoutTests/ChangeLog

    r30452 r30453  
     12008-02-20  Michael Knaup  <michael.knaup@mac.com>
     2
     3        Reviewed by Darin.
     4
     5        - test for Bug 16753: date set methods with no args should result in NaN (Acid3 bug)
     6
     7        * fast/js/date-set-to-nan-expected.txt: Added.
     8        * fast/js/date-set-to-nan.html: Added.
     9        * fast/js/resources/date-set-to-nan.js: Added.
     10
    1112008-02-20  Oliver Hunt  <oliver@apple.com>
    212
Note: See TracChangeset for help on using the changeset viewer.