Changeset 45696 in webkit for trunk/JavaScriptCore/wtf/dtoa.cpp


Ignore:
Timestamp:
Jul 9, 2009, 8:45:23 PM (16 years ago)
Author:
[email protected]
Message:

2009-07-09 Maciej Stachowiak <[email protected]>

Reviewed by Darin Adler.

REGRESSION: crash in edge cases of floating point parsing.
https://bugs.webkit.org/show_bug.cgi?id=27110
<rdar://problem/7044458>


Tests: fast/css/number-parsing-crash.html

fast/css/number-parsing-crash.html
fast/js/number-parsing-crash.html


  • wtf/dtoa.cpp: (WTF::BigInt::BigInt): Converted this to more a proper class, using a Vector with inline capacity

(WTF::lshift): Rearranged logic somewhat nontrivially to deal with the new way of sizing BigInts.
Added an assertion to verify that invariants are maintained.

All other functions are adapted fairly mechanically to the above changes.
(WTF::BigInt::clear):
(WTF::BigInt::size):
(WTF::BigInt::resize):
(WTF::BigInt::words):
(WTF::BigInt::append):
(WTF::multadd):
(WTF::s2b):
(WTF::i2b):
(WTF::mult):
(WTF::cmp):
(WTF::diff):
(WTF::b2d):
(WTF::d2b):
(WTF::ratio):
(WTF::strtod):
(WTF::quorem):
(WTF::dtoa):

2009-07-09 Maciej Stachowiak <[email protected]>

Reviewed by Darin Adler.


REGRESSION: crash in edge cases of floating point parsing.
<rdar://problem/7044458>
https://bugs.webkit.org/show_bug.cgi?id=27110


Test cases for both JavaScript and CSS use of dtoa.

  • fast/css/number-parsing-crash-2-expected.txt: Added.
  • fast/css/number-parsing-crash-2.html: Added.
  • fast/css/number-parsing-crash-expected.txt: Added.
  • fast/css/number-parsing-crash.html: Added.
  • fast/js/number-parsing-crash-expected.txt: Added.
  • fast/js/number-parsing-crash.html: Added.
  • fast/js/resources/number-parsing-crash.js: Added.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/wtf/dtoa.cpp

    r44224 r45696  
    256256#define Big1 0xffffffff
    257257
     258
     259// FIXME: we should remove non-Pack_32 mode since it is unused and unmaintained
    258260#ifndef Pack_32
    259261#define Pack_32
     
    279281
    280282struct BigInt {
    281     BigInt() : sign(0), wds(0) { }
    282     BigInt(const BigInt& other) : sign(other.sign), wds(other.wds)
     283    BigInt() : sign(0) { }
     284    int sign;
     285
     286    void clear()
    283287    {
    284         for (int i = 0; i < 64; ++i)
    285             x[i] = other.x[i];
    286     }
    287 
    288     BigInt& operator=(const BigInt& other)
     288        sign = 0;
     289        m_words.clear();
     290    }
     291   
     292    size_t size() const
    289293    {
    290         sign = other.sign;
    291         wds = other.wds;
    292         for (int i = 0; i < 64; ++i)
    293             x[i] = other.x[i];       
    294         return *this;
     294        return m_words.size();
     295    }
     296
     297    void resize(size_t s)
     298    {
     299        m_words.resize(s);
     300    }
     301           
     302    uint32_t* words()
     303    {
     304        return m_words.data();
     305    }
     306
     307    const uint32_t* words() const
     308    {
     309        return m_words.data();
    295310    }
    296311   
    297     int sign;
    298     int wds;
    299     uint32_t x[64];
     312    void append(uint32_t w)
     313    {
     314        m_words.append(w);
     315    }
     316   
     317    Vector<uint32_t, 16> m_words;
    300318};
    301319
     
    308326#endif
    309327
    310     int wds = b.wds;
    311     uint32_t* x = b.x;
     328    int wds = b.size();
     329    uint32_t* x = b.words();
    312330    int i = 0;
    313331    carry = a;
     
    332350    } while (++i < wds);
    333351
    334     if (carry) {
    335         b.x[wds++] = (uint32_t)carry;
    336         b.wds = wds;
    337     }
     352    if (carry)
     353        b.append((uint32_t)carry);
    338354}
    339355
     
    347363#ifdef Pack_32
    348364    b.sign = 0;
    349     b.x[0] = y9;
    350     b.wds = 1;
     365    b.resize(1);
     366    b.words()[0] = y9;
    351367#else
    352368    b.sign = 0;
    353     b.x[0] = y9 & 0xffff;
    354     b.wds = (b->x[1] = y9 >> 16) ? 2 : 1;
     369    b.resize((b->x[1] = y9 >> 16) ? 2 : 1);
     370    b.words()[0] = y9 & 0xffff;
    355371#endif
    356372
     
    441457{
    442458    b.sign = 0;
    443     b.x[0] = i;
    444     b.wds = 1;
     459    b.resize(1);
     460    b.words()[0] = i;
    445461}
    446462
     
    460476#endif
    461477
    462     if (a->wds < b->wds) {
     478    if (a->size() < b->size()) {
    463479        const BigInt* tmp = a;
    464480        a = b;
     
    466482    }
    467483   
    468     wa = a->wds;
    469     wb = b->wds;
     484    wa = a->size();
     485    wb = b->size();
    470486    wc = wa + wb;
    471 
    472     for (xc = c.x, xa = xc + wc; xc < xa; xc++)
     487    c.resize(wc);
     488
     489    for (xc = c.words(), xa = xc + wc; xc < xa; xc++)
    473490        *xc = 0;
    474     xa = a->x;
     491    xa = a->words();
    475492    xae = xa + wa;
    476     xb = b->x;
     493    xb = b->words();
    477494    xbe = xb + wb;
    478     xc0 = c.x;
     495    xc0 = c.words();
    479496#ifdef USE_LONG_LONG
    480497    for (; xb < xbe; xc0++) {
     
    538555#endif
    539556#endif
    540     for (xc0 = c.x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) { }
    541     c.wds = wc;
     557    for (xc0 = c.words(), xc = xc0 + wc; wc > 0 && !*--xc; --wc) { }
     558    c.resize(wc);
    542559    aRef = c;
    543560}
     
    618635#endif
    619636
    620     int n1 = n + b.wds + 1;
    621 
    622     const uint32_t* srcStart = b.x;
    623     uint32_t* dstStart = b.x;
    624     const uint32_t* src = srcStart + b.wds - 1;
     637    int origSize = b.size();
     638    int n1 = n + origSize + 1;
     639
     640    if (k &= 0x1f)
     641        b.resize(b.size() + n + 1);
     642    else
     643        b.resize(b.size() + n);
     644
     645    const uint32_t* srcStart = b.words();
     646    uint32_t* dstStart = b.words();
     647    const uint32_t* src = srcStart + origSize - 1;
    625648    uint32_t* dst = dstStart + n1 - 1;
    626649#ifdef Pack_32
    627     if (k &= 0x1f) {
     650    if (k) {
    628651        uint32_t hiSubword = 0;
    629652        int s = 32 - k;
     
    634657        *dst = hiSubword;
    635658        ASSERT(dst == dstStart + n);
    636         b.wds = b.wds + n + (b.x[n1 - 1] != 0);
     659
     660        b.resize(origSize + n + (b.words()[n1 - 1] != 0));
    637661    }
    638662#else
     
    653677            *--dst = *src--;
    654678        } while (src >= srcStart);
    655         b.wds = b.wds + n;
    656679    }
    657680    for (dst = dstStart + n; dst != dstStart; )
    658681        *--dst = 0;
     682
     683    ASSERT(b.size() <= 1 || b.words()[b.size() - 1]);
    659684}
    660685
     
    664689    int i, j;
    665690
    666     i = a.wds;
    667     j = b.wds;
    668     ASSERT(i <= 1 || a.x[i - 1]);
    669     ASSERT(j <= 1 || b.x[j - 1]);
     691    i = a.size();
     692    j = b.size();
     693    ASSERT(i <= 1 || a.words()[i - 1]);
     694    ASSERT(j <= 1 || b.words()[j - 1]);
    670695    if (i -= j)
    671696        return i;
    672     xa0 = a.x;
     697    xa0 = a.words();
    673698    xa = xa0 + j;
    674     xb0 = b.x;
     699    xb0 = b.words();
    675700    xb = xb0 + j;
    676701    for (;;) {
     
    693718    if (!i) {
    694719        c.sign = 0;
    695         c.wds = 1;
    696         c.x[0] = 0;
     720        c.resize(1);
     721        c.words()[0] = 0;
    697722        return;
    698723    }
     
    705730        i = 0;
    706731
    707     c.wds = 0;
     732    wa = a->size();
     733    const uint32_t* xa = a->words();
     734    const uint32_t* xae = xa + wa;
     735    wb = b->size();
     736    const uint32_t* xb = b->words();
     737    const uint32_t* xbe = xb + wb;
     738
     739    c.resize(wa);
    708740    c.sign = i;
    709     wa = a->wds;
    710     const uint32_t* xa = a->x;
    711     const uint32_t* xae = xa + wa;
    712     wb = b->wds;
    713     const uint32_t* xb = b->x;
    714     const uint32_t* xbe = xb + wb;
    715     xc = c.x;
     741    xc = c.words();
    716742#ifdef USE_LONG_LONG
    717743    unsigned long long borrow = 0;
     
    758784    while (!*--xc)
    759785        wa--;
    760     c.wds = wa;
     786    c.resize(wa);
    761787}
    762788
     
    805831#define d1 word1(&d)
    806832
    807     xa0 = a.x;
    808     xa = xa0 + a.wds;
     833    xa0 = a.words();
     834    xa = xa0 + a.size();
    809835    y = *--xa;
    810836    ASSERT(y);
     
    861887    b.sign = 0;
    862888#ifdef Pack_32
    863     b.wds = 1;
    864 #else
    865     b.wds = 2;
    866 #endif
    867     x = b.x;
     889    b.resize(1);
     890#else
     891    b.resize(2);
     892#endif
     893    x = b.words();
    868894
    869895    z = d0 & Frac_mask;
     
    882908        } else
    883909            x[0] = y;
     910            if (z) {
     911                b.resize(2);
     912                x[1] = z;
     913            }
     914
    884915#ifndef Sudden_Underflow
    885         i =
    886 #endif
    887             b.wds = (x[1] = z) ? 2 : 1;
     916        i = b.size();
     917#endif
    888918    } else {
    889919        k = lo0bits(&z);
    890920        x[0] = z;
    891921#ifndef Sudden_Underflow
    892         i =
    893 #endif
    894             b.wds = 1;
     922        i = 1;
     923#endif
     924        b.resize(1);
    895925        k += 32;
    896926    }
     
    930960    } while (!x[i])
    931961        --i;
    932     b->wds = i + 1;
     962    b->resize(i + 1);
    933963#endif
    934964#ifndef Sudden_Underflow
     
    959989    dval(&db) = b2d(b, &kb);
    960990#ifdef Pack_32
    961     k = ka - kb + 32 * (a.wds - b.wds);
    962 #else
    963     k = ka - kb + 16 * (a.wds - b.wds);
     991    k = ka - kb + 32 * (a.size() - b.size());
     992#else
     993    k = ka - kb + 16 * (a.size() - b.size());
    964994#endif
    965995    if (k > 0)
     
    14531483                ) {
    14541484#ifdef SET_INEXACT
    1455                 if (!delta->x[0] && delta->wds <= 1)
     1485                if (!delta->words()[0] && delta->size() <= 1)
    14561486                    inexact = 0;
    14571487#endif
    14581488                break;
    14591489            }
    1460             if (!delta.x[0] && delta.wds <= 1) {
     1490            if (!delta.words()[0] && delta.size() <= 1) {
    14611491                /* exact result */
    14621492#ifdef SET_INEXACT
     
    17011731static ALWAYS_INLINE int quorem(BigInt& b, BigInt& S)
    17021732{
    1703     int n;
     1733    size_t n;
    17041734    uint32_t *bx, *bxe, q, *sx, *sxe;
    17051735#ifdef USE_LONG_LONG
     
    17111741#endif
    17121742#endif
    1713 
    1714     n = S.wds;
    1715     ASSERT_WITH_MESSAGE(b.wds <= n, "oversize b in quorem");
    1716     if (b.wds < n)
     1743    ASSERT(b.size() <= 1 || b.words()[b.size() - 1]);
     1744    ASSERT(S.size() <= 1 || S.words()[S.size() - 1]);
     1745
     1746    n = S.size();
     1747    ASSERT_WITH_MESSAGE(b.size() <= n, "oversize b in quorem");
     1748    if (b.size() < n)
    17171749        return 0;
    1718     sx = S.x;
     1750    sx = S.words();
    17191751    sxe = sx + --n;
    1720     bx = b.x;
     1752    bx = b.words();
    17211753    bxe = bx + n;
    17221754    q = *bxe / (*sxe + 1);    /* ensure q <= true quotient */
     
    17531785        } while (sx <= sxe);
    17541786        if (!*bxe) {
    1755             bx = b.x;
     1787            bx = b.words();
    17561788            while (--bxe > bx && !*bxe)
    17571789                --n;
    1758             b.wds = n;
     1790            b.resize(n);
    17591791        }
    17601792    }
     
    17631795        borrow = 0;
    17641796        carry = 0;
    1765         bx = b.x;
    1766         sx = S.x;
     1797        bx = b.words();
     1798        sx = S.words();
    17671799        do {
    17681800#ifdef USE_LONG_LONG
     
    17921824#endif
    17931825        } while (sx <= sxe);
    1794         bx = b.x;
     1826        bx = b.words();
    17951827        bxe = bx + n;
    17961828        if (!*bxe) {
    17971829            while (--bxe > bx && !*bxe)
    17981830                --n;
    1799             b.wds = n;
     1831            b.resize(n);
    18001832        }
    18011833    }
     
    20282060        word0(&eps) -= (P - 1) * Exp_msk1;
    20292061        if (ilim == 0) {
    2030             S = mhi = BigInt();
     2062            S.clear();
     2063            mhi.clear();
    20312064            dval(&u) -= 5.;
    20322065            if (dval(&u) > dval(&eps))
     
    20912124        ds = tens[k];
    20922125        if (ndigits < 0 && ilim <= 0) {
    2093             S = mhi = BigInt();
     2126            S.clear();
     2127            mhi.clear();
    20942128            if (ilim < 0 || dval(&u) <= 5 * ds)
    20952129                goto no_digits;
     
    21332167    m2 = b2;
    21342168    m5 = b5;
    2135     mhi = mlo = BigInt();
     2169    mhi.clear();
     2170    mlo.clear();
    21362171    if (leftright) {
    21372172        i =
     
    21872222     */
    21882223#ifdef Pack_32
    2189     if ((i = ((s5 ? 32 - hi0bits(S.x[S.wds - 1]) : 1) + s2) & 0x1f))
     2224    if ((i = ((s5 ? 32 - hi0bits(S.words()[S.size() - 1]) : 1) + s2) & 0x1f))
    21902225        i = 32 - i;
    21912226#else
    2192     if ((i = ((s5 ? 32 - hi0bits(S.x[S.wds - 1]) : 1) + s2) & 0xf))
     2227    if ((i = ((s5 ? 32 - hi0bits(S.words()[S.size() - 1]) : 1) + s2) & 0xf))
    21932228        i = 16 - i;
    21942229#endif
     
    22532288            }
    22542289            if (j < 0 || (j == 0 && !(word1(&u) & 1))) {
    2255                 if (!b.x[0] && b.wds <= 1) {
     2290                if (!b.words()[0] && b.size() <= 1) {
    22562291#ifdef SET_INEXACT
    22572292                    inexact = 0;
     
    22882323        for (i = 1;; i++) {
    22892324            *s++ = dig = quorem(b,S) + '0';
    2290             if (!b.x[0] && b.wds <= 1) {
     2325            if (!b.words()[0] && b.size() <= 1) {
    22912326#ifdef SET_INEXACT
    22922327                inexact = 0;
Note: See TracChangeset for help on using the changeset viewer.