VirtualBox

Ignore:
Timestamp:
Apr 27, 2016 1:28:59 AM (9 years ago)
Author:
vboxsync
Message:

tarvfs.cpp: don't shift signed values, may lead to undefined behavior.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/zip/tarvfs.cpp

    r59747 r60710  
    231231         * is the signed bit. Bits 5:0 are the most significant value bits.
    232232         */
    233         int64_t i64 = !(0x40 & *puchField) ? 0 : -1;
    234         i64 = (i64 << 6) | (*puchField & 0x3f);
    235         cchField--;
    236         puchField++;
    237 
    238         /*
    239          * The remaining bytes are used in full.
    240          */
    241         while (cchField-- > 0)
     233        uint64_t u64;
     234        if (!(0x40 & *puchField))
    242235        {
    243             if (RT_UNLIKELY(i64 > INT64_MAX / 256))
    244                 return VERR_TAR_NUM_VALUE_TOO_LARGE;
    245             if (RT_UNLIKELY(i64 < INT64_MIN / 256))
    246                 return VERR_TAR_NUM_VALUE_TOO_LARGE;
    247             i64 = (i64 << 8) | *puchField++;
     236            /* Positive or zero value. */
     237            u64 = *puchField & 0x3f;
     238            cchField--;
     239            puchField++;
     240
     241            while (cchField-- > 0)
     242            {
     243                if (RT_LIKELY(u64 <= (uint64_t)INT64_MAX / 256))
     244                    u64 = (u64 << 8) | *puchField++;
     245                else
     246                    return VERR_TAR_NUM_VALUE_TOO_LARGE;
     247            }
    248248        }
    249         *pi64 = i64;
     249        else
     250        {
     251            /* Negative value (could be used in timestamp). We do manual sign extending here. */
     252            u64 = (UINT64_MAX << 6) | (*puchField & 0x3f);
     253            cchField--;
     254            puchField++;
     255
     256            while (cchField-- > 0)
     257            {
     258                if (RT_LIKELY(u64 >= (uint64_t)(INT64_MIN / 256)))
     259                    u64 = (u64 << 8) | *puchField++;
     260                else
     261                    return VERR_TAR_NUM_VALUE_TOO_LARGE;
     262            }
     263        }
     264        *pi64 = (int64_t)u64;
    250265    }
    251266
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette