VirtualBox

Changeset 34949 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Dec 10, 2010 1:29:32 PM (14 years ago)
Author:
vboxsync
Message:

Runtime-tar: base 256 support for files greater 8GB

File:
1 edited

Legend:

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

    r34919 r34949  
    193193 ******************************************************************************/
    194194
     195DECLINLINE(void) rtTarSizeToRec(PRTTARRECORD pRecord, uint64_t cbSize)
     196{
     197    /* Small enough for the standard octal string encoding? */
     198    if (cbSize <= 0x200000000)
     199        RTStrPrintf(pRecord->h.size, sizeof(pRecord->h.size), "%0.11llo", cbSize);
     200    else
     201    {
     202        /*
     203         * Base 256 extension. Set the highest bit of the left most character.
     204         * We don't deal with negatives here, cause the size have to be greater
     205         * than zero.
     206         */
     207        size_t cchField = sizeof(pRecord->h.size) - 1;
     208        unsigned char *puchField = (unsigned char*)pRecord->h.size;
     209        puchField[0] = 0x80;
     210        do
     211        {
     212            puchField[cchField--] = cbSize & ((1 << 8) - 1);
     213            cbSize = (cbSize >> 8);
     214        } while (cchField);
     215    }
     216}
     217
     218DECLINLINE(uint64_t) rtTarRecToSize(PRTTARRECORD pRecord)
     219{
     220    int64_t cbSize = 0;
     221        if (pRecord->h.size[0] & 0x80)
     222    {
     223        size_t cchField = sizeof(pRecord->h.size);
     224        unsigned char const *puchField = (unsigned char const *)pRecord->h.size;
     225        /*
     226         * The first byte has the bit 7 set to indicate base-256, while bit 6
     227         * is the signed bit. Bits 5:0 are the most significant value bits.
     228         */
     229        cbSize = !(0x40 & *puchField) ? 0 : -1;
     230        cbSize = (cbSize << 6) | (*puchField & 0x3f);
     231        cchField--;
     232        puchField++;
     233        /*
     234         * The remaining bytes are used in full.
     235         */
     236        while (cchField-- > 0)
     237        {
     238            if (RT_UNLIKELY(   cbSize > INT64_MAX / 256
     239                            || cbSize < INT64_MIN / 256))
     240            {
     241                cbSize = 0;
     242                break;
     243            }
     244            cbSize = (cbSize << 8) | *puchField++;
     245        }
     246    }else
     247        cbSize = rtTarRecToSize(pRecord);
     248
     249    if (cbSize < 0)
     250        cbSize = 0;
     251
     252    return (uint64_t)cbSize;
     253}
     254
    195255DECLINLINE(int) rtTarCalcChkSum(PRTTARRECORD pRecord, uint32_t *pChkSum)
    196256{
     
    264324    RTStrPrintf(pRecord->h.uid,   sizeof(pRecord->h.uid),   "%0.7o",    uid);
    265325    RTStrPrintf(pRecord->h.gid,   sizeof(pRecord->h.gid),   "%0.7o",    gid);
    266     RTStrPrintf(pRecord->h.size,  sizeof(pRecord->h.size),  "%0.11llo", cbSize);
     326    rtTarSizeToRec(pRecord, cbSize);
    267327    RTStrPrintf(pRecord->h.mtime, sizeof(pRecord->h.mtime), "%0.11o",   mtime);
    268328    RTStrPrintf(pRecord->h.magic, sizeof(pRecord->h.magic), "ustar  ");
     
    568628    int rc = VINF_SUCCESS;
    569629    /* Seek over the data parts (512 bytes aligned) */
    570     int64_t offSeek = RT_ALIGN(RTStrToInt64(pRecord->h.size), sizeof(RTTARRECORD));
     630    int64_t offSeek = RT_ALIGN(rtTarRecToSize(pRecord), sizeof(RTTARRECORD));
    571631    if (offSeek > 0)
    572632        rc = RTFileSeek(hFile, offSeek, RTFILE_SEEK_CURRENT, NULL);
     
    595655            {
    596656                /* Get the file size */
    597                 rc = RTStrToUInt64Full(record.h.size, 8, pcbSize);
    598                 if (RT_FAILURE(rc))
    599                     break;
    600 
     657                *pcbSize = rtTarRecToSize(&record);
    601658                /* Seek back, to position the file pointer at the start of the header. */
    602659                rc = RTFileSeek(hFile, -(int64_t)sizeof(RTTARRECORD), RTFILE_SEEK_CURRENT, poff);
     
    642699                if (!RTStrCmp(record.h.name, papszFiles[i]))
    643700                {
    644                     /* Get the file size */
    645                     uint64_t cbSize = 0;
    646                     rc = RTStrToUInt64Full(record.h.size, 8, &cbSize);
    647 
    648701                    /* Sum up the overall size */
    649                     *pcbOverallSize += cbSize;
     702                    *pcbOverallSize += rtTarRecToSize(&record);
    650703                    ++cFound;
    651704                    break;
     
    16201673
    16211674            /* Get the file size */
    1622             rc = RTStrToUInt64Full(record.h.size, 8, &pFileInt->cbSize);
    1623             if (RT_FAILURE(rc))
    1624                 break;
    1625 
     1675            pFileInt->cbSize = rtTarRecToSize(&record);
    16261676            /* The start is -512 from here. */
    16271677            pFileInt->offStart = RTFileTell(pInt->hTarFile) - sizeof(RTTARRECORD);
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