VirtualBox

Changeset 48780 in vbox for trunk


Ignore:
Timestamp:
Oct 1, 2013 2:18:49 AM (11 years ago)
Author:
vboxsync
Message:

Started on a XAR file system stream similar to what we have for TAR already.

Location:
trunk
Files:
1 added
5 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/err.h

    r46971 r48780  
    17891789/** @} */
    17901790
     1791/** @name RTZipXar status codes.
     1792 * @{ */
     1793/** Wrong magic value. */
     1794#define VERR_XAR_WRONG_MAGIC                        (-22700)
     1795/** Bad header size. */
     1796#define VERR_XAR_BAD_HDR_SIZE                       (-22701)
     1797/** Unsupported version. */
     1798#define VERR_XAR_UNSUPPORTED_VERSION                (-22702)
     1799/** Unsupported hashing function. */
     1800#define VERR_XAR_UNSUPPORTED_HASH_FUNCTION          (-22703)
     1801/** The table of content (TOC) is too small and therefore can't be valid. */
     1802#define VERR_XAR_TOC_TOO_SMALL                      (-22704)
     1803/** The table of content (TOC) is too big. */
     1804#define VERR_XAR_TOC_TOO_BIG                        (-22705)
     1805/** The compressed table of content is too big. */
     1806#define VERR_XAR_TOC_TOO_BIG_COMPRESSED             (-22706)
     1807/** The uncompressed table of content size in the header didn't match what
     1808 * ZLib returned. */
     1809#define VERR_XAR_TOC_UNCOMP_SIZE_MISMATCH           (-22707)
     1810/** The table of content string length didn't match the size specified in the
     1811 *  header. */
     1812#define VERR_XAR_TOC_STRLEN_MISMATCH                (-22708)
     1813/** The table of content isn't valid UTF-8. */
     1814#define VERR_XAR_TOC_UTF8_ENCODING                  (-22709)
     1815/** XML error while parsing the table of content. */
     1816#define VERR_XAR_TOC_XML_PARSE_ERROR                (-22710)
     1817/** The table of content XML document does not have a toc element. */
     1818#define VERR_XML_TOC_ELEMENT_MISSING                (-22711)
     1819/** The table of content XML element (toc) has sibilings, we expected it to be
     1820 *  an only child or the root element (xar). */
     1821#define VERR_XML_TOC_ELEMENT_HAS_SIBLINGS           (-22712)
     1822/** The XAR table of content digest doesn't match. */
     1823#define VERR_XAR_TOC_DIGEST_MISMATCH                (-22713)
     1824/** Bad or missing XAR checksum element. */
     1825#define VERR_XAR_BAD_CHECKSUM_ELEMENT               (-22714)
     1826/** The hash function in the header doesn't match the one in the table of
     1827 *  content. */
     1828#define VERR_XAR_HASH_FUNCTION_MISMATCH             (-22715)
     1829/** Bad digest length encountered in the table of content.  */
     1830#define VERR_XAR_BAD_DIGEST_LENGTH                  (-22716)
     1831/** The order of elements in the XAR file does not lend it self to expansion
     1832 *  from via an I/O stream. */
     1833#define VERR_XAR_NOT_STREAMBLE_ELEMENT_ORDER        (-22717)
     1834/** Missing offset element in table of content sub-element. */
     1835#define VERR_XAR_MISSING_OFFSET_ELEMENT             (-22718)
     1836/** Bad offset element in table of content sub-element. */
     1837#define VERR_XAR_BAD_OFFSET_ELEMENT                 (-22719)
     1838/** Missing size element in table of content sub-element. */
     1839#define VERR_XAR_MISSING_SIZE_ELEMENT               (-22720)
     1840/** Bad size element in table of content sub-element. */
     1841#define VERR_XAR_BAD_SIZE_ELEMENT                   (-22721)
     1842/** @} */
     1843
    17911844
    17921845/* SED-END */
  • trunk/include/iprt/zip.h

    r47516 r48780  
    271271RTDECL(RTEXITCODE) RTZipTarCmd(unsigned cArgs, char **papszArgs);
    272272
     273/**
     274 * Opens a XAR filesystem stream.
     275 *
     276 * This is used to extract, list or check a XAR archive.
     277 *
     278 * @returns IPRT status code.
     279 *
     280 * @param   hVfsIosIn           The compressed input stream.  The reference is
     281 *                              not consumed, instead another one is retained.
     282 * @param   fFlags              Flags, MBZ.
     283 * @param   phVfsFss            Where to return the handle to the XAR filesystem
     284 *                              stream.
     285 */
     286RTDECL(int) RTZipXarFsStreamFromIoStream(RTVFSIOSTREAM hVfsIosIn, uint32_t fFlags, PRTVFSFSSTREAM phVfsFss);
     287
    273288/** @} */
    274289
  • trunk/src/VBox/Runtime/Makefile.kmk

    r48768 r48780  
    12901290VBoxRT_INST                    = $(INST_DLL) $(INST_TESTCASE)
    12911291endif
    1292 VBoxRT_DEFS                   := $(filter-out RT_NO_GIP,$(RuntimeR3_DEFS)) IN_SUP_R3 IN_SUP_R3
     1292VBoxRT_DEFS                   := $(filter-out RT_NO_GIP,$(RuntimeR3_DEFS)) IN_SUP_R3 IN_SUP_R3 IPRT_WITH_XAR
    12931293ifn1of ($(KBUILD_TARGET_ARCH), amd64 x86)
    12941294 VBoxRT_DEFS                  += RT_NO_GIP
     
    13031303        $(filter-out common/checksum/crc32.cpp, $(RuntimeR3_SOURCES)) \
    13041304        common/checksum/crc32-zlib.cpp \
    1305         common/misc/aiomgr.cpp
     1305        common/misc/aiomgr.cpp \
     1306        common/zip/xarvfs.cpp
    13061307ifdef VBOX_WITH_LIBCURL
    13071308 VBoxRT_SOURCES               += common/misc/s3.cpp
  • trunk/src/VBox/Runtime/common/zip/tarcmd.cpp

    r47359 r48780  
    6060#define RTZIPTARCMD_OPT_DIR_MODE_AND_MASK   1007
    6161#define RTZIPTARCMD_OPT_DIR_MODE_OR_MASK    1008
     62#define RTZIPTARCMD_OPT_FORMAT              1009
     63
     64/** File format. */
     65typedef enum RTZIPTARFORMAT
     66{
     67    RTZIPTARFORMAT_INVALID = 0,
     68    /** Autodetect if possible, defaulting to TAR. */
     69    RTZIPTARFORMAT_AUTO_DEFAULT,
     70    /** TAR.  */
     71    RTZIPTARFORMAT_TAR,
     72    /** XAR.  */
     73    RTZIPTARFORMAT_XAR
     74} RTZIPTARFORMAT;
    6275
    6376
     
    7083typedef struct RTZIPTARCMDOPS
    7184{
     85    /** The file format. */
     86    RTZIPTARFORMAT  enmFormat;
     87
    7288    /** The operation (Acdrtux or RTZIPTARCMD_OPT_DELETE). */
    7389    int             iOperation;
     
    247263
    248264    /*
    249      * Open the tar filesystem stream.
    250      */
    251     rc = RTZipTarFsStreamFromIoStream(hVfsIos, 0/*fFlags*/, phVfsFss);
     265     * Open the filesystem stream.
     266     */
     267    if (pOpts->enmFormat == RTZIPTARFORMAT_TAR)
     268        rc = RTZipTarFsStreamFromIoStream(hVfsIos, 0/*fFlags*/, phVfsFss);
     269    else if (pOpts->enmFormat == RTZIPTARFORMAT_XAR)
     270#ifdef IPRT_WITH_XAR /* Requires C++ and XML, so only in some configruation of IPRT. */
     271        rc = RTZipXarFsStreamFromIoStream(hVfsIos, 0/*fFlags*/, phVfsFss);
     272#else
     273        rc = VERR_NOT_SUPPORTED;
     274#endif
     275    else /** @todo make RTZipTarFsStreamFromIoStream fail if not tar file! */
     276        rc = RTZipTarFsStreamFromIoStream(hVfsIos, 0/*fFlags*/, phVfsFss);
    252277    RTVfsIoStrmRelease(hVfsIos);
    253278    if (RT_FAILURE(rc))
     
    950975        { "--owner",                RTZIPTARCMD_OPT_OWNER, RTGETOPT_REQ_STRING },
    951976        { "--group",                RTZIPTARCMD_OPT_GROUP, RTGETOPT_REQ_STRING },
    952         { "--utc",                  RTZIPTARCMD_OPT_UTC,  RTGETOPT_REQ_NOTHING },
     977        { "--utc",                  RTZIPTARCMD_OPT_UTC,   RTGETOPT_REQ_NOTHING },
    953978
    954979        /* IPRT extensions */
     
    958983        { "--dir-mode-and-mask",    RTZIPTARCMD_OPT_DIR_MODE_AND_MASK,  RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_OCT },
    959984        { "--dir-mode-or-mask",     RTZIPTARCMD_OPT_DIR_MODE_OR_MASK,   RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_OCT },
     985        { "--format",               RTZIPTARCMD_OPT_FORMAT,             RTGETOPT_REQ_STRING },
    960986    };
    961987
     
    968994    RTZIPTARCMDOPS Opts;
    969995    RT_ZERO(Opts);
     996    Opts.enmFormat = RTZIPTARFORMAT_AUTO_DEFAULT;
    970997    Opts.uidOwner = NIL_RTUID;
    971998    Opts.gidGroup = NIL_RTUID;
     
    10941121                break;
    10951122
     1123            case RTZIPTARCMD_OPT_FORMAT:
     1124                if (!strcmp(ValueUnion.psz, "auto") || !strcmp(ValueUnion.psz, "default"))
     1125                    Opts.enmFormat = RTZIPTARFORMAT_AUTO_DEFAULT;
     1126                else if (!strcmp(ValueUnion.psz, "tar"))
     1127                    Opts.enmFormat = RTZIPTARFORMAT_TAR;
     1128                else if (!strcmp(ValueUnion.psz, "xar"))
     1129                    Opts.enmFormat = RTZIPTARFORMAT_XAR;
     1130                else
     1131                    return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown archive format: '%s'", ValueUnion.psz);
     1132                break;
    10961133
    10971134            /* Standard bits. */
  • trunk/src/VBox/Runtime/common/zip/xarvfs.cpp

    r48757 r48780  
    11/* $Id$ */
    22/** @file
    3  * IPRT - TAR Virtual Filesystem.
     3 * IPRT - XAR Virtual Filesystem.
    44 */
    55
    66/*
    7  * Copyright (C) 2010-2011 Oracle Corporation
     7 * Copyright (C) 2010-2013 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3636#include <iprt/ctype.h>
    3737#include <iprt/err.h>
     38#include <iprt/md5.h>
    3839#include <iprt/poll.h>
    3940#include <iprt/file.h>
     41#include <iprt/sha.h>
    4042#include <iprt/string.h>
    4143#include <iprt/vfs.h>
    4244#include <iprt/vfslowlevel.h>
    43 
    44 #include "tar.h"
     45#include <iprt/formats/xar.h>
     46#include <iprt/cpp/xml.h>
     47
    4548
    4649
     
    4952*******************************************************************************/
    5053/**
    51  * TAR reader state machine states.
    52  */
    53 typedef enum RTZIPTARREADERSTATE
    54 {
    55     /** Invalid state. */
    56     RTZIPTARREADERSTATE_INVALID = 0,
    57     /** Expecting the next file/dir/whatever entry. */
    58     RTZIPTARREADERSTATE_FIRST,
    59     /** Expecting more zero headers or the end of the stream. */
    60     RTZIPTARREADERSTATE_ZERO,
    61     /** Expecting a GNU long name. */
    62     RTZIPTARREADERSTATE_GNU_LONGNAME,
    63     /** Expecting a GNU long link. */
    64     RTZIPTARREADERSTATE_GNU_LONGLINK,
    65     /** Expecting a normal header or another GNU specific one. */
    66     RTZIPTARREADERSTATE_GNU_NEXT,
    67     /** End of valid states (not included). */
    68     RTZIPTARREADERSTATE_END
    69 } RTZIPTARREADERSTATE;
    70 
    71 /**
    72  * Tar reader instance data.
    73  */
    74 typedef struct RTZIPTARREADER
    75 {
    76     /** Zero header counter. */
    77     uint32_t                cZeroHdrs;
    78     /** The state machine state. */
    79     RTZIPTARREADERSTATE     enmState;
    80     /** The type of the previous TAR header. */
    81     RTZIPTARTYPE            enmPrevType;
    82     /** The type of the current TAR header. */
    83     RTZIPTARTYPE            enmType;
    84     /** The current header. */
    85     RTZIPTARHDR             Hdr;
    86     /** The expected long name/link length (GNU). */
    87     uint32_t                cbGnuLongExpect;
    88     /** The current long name/link length (GNU). */
    89     uint32_t                offGnuLongCur;
    90     /** The name of the current object.
    91      * This is for handling GNU and PAX long names. */
    92     char                    szName[RTPATH_MAX];
    93     /** The current link target if symlink or hardlink. */
    94     char                    szTarget[RTPATH_MAX];
    95 } RTZIPTARREADER;
    96 /** Pointer to the TAR reader instance data. */
    97 typedef RTZIPTARREADER *PRTZIPTARREADER;
    98 
    99 /**
    100  * Tar directory, character device, block device, fifo socket or symbolic link.
    101  */
    102 typedef struct RTZIPTARBASEOBJ
     54 * Hash digest value union for the supported XAR hash functions.
     55 */
     56typedef union RTZIPXARHASHDIGEST
     57{
     58    uint8_t abMd5[RTMD5_HASH_SIZE];
     59    uint8_t abSha1[RTSHA1_HASH_SIZE];
     60} RTZIPXARHASHDIGEST;
     61/** Pointer to a XAR hash digest union. */
     62typedef RTZIPXARHASHDIGEST *PRTZIPXARHASHDIGEST;
     63/** Pointer to a const XAR hash digest union. */
     64typedef RTZIPXARHASHDIGEST *PCRTZIPXARHASHDIGEST;
     65
     66/**
     67 * XAR reader instance data.
     68 */
     69typedef struct RTZIPXARREADER
     70{
     71    /** The TOC XML element. */
     72    xml::ElementNode const *pToc;
     73    /** The TOC XML document. */
     74    xml::Document          *pDoc;
     75    /** The current file ID. */
     76    uint32_t            idCurFile;
     77} RTZIPXARREADER;
     78/** Pointer to the XAR reader instance data. */
     79typedef RTZIPXARREADER *PRTZIPXARREADER;
     80
     81/**
     82 * Xar directory, character device, block device, fifo socket or symbolic link.
     83 */
     84typedef struct RTZIPXARBASEOBJ
    10385{
    10486    /** The stream offset of the (first) header.  */
     
    10789     * stream).
    10890     * @todo Fix this so it won't go stale... Back ref from this obj to fss? */
    109     PRTZIPTARREADER         pTarReader;
     91    PRTZIPXARREADER         pXarReader;
    11092    /** The object info with unix attributes. */
    11193    RTFSOBJINFO             ObjInfo;
    112 } RTZIPTARBASEOBJ;
    113 /** Pointer to a TAR filesystem stream base object. */
    114 typedef RTZIPTARBASEOBJ *PRTZIPTARBASEOBJ;
    115 
    116 
    117 /**
    118  * Tar file represented as a VFS I/O stream.
    119  */
    120 typedef struct RTZIPTARIOSTREAM
    121 {
    122     /** The basic TAR object data. */
    123     RTZIPTARBASEOBJ         BaseObj;
     94} RTZIPXARBASEOBJ;
     95/** Pointer to a XAR filesystem stream base object. */
     96typedef RTZIPXARBASEOBJ *PRTZIPXARBASEOBJ;
     97
     98
     99/**
     100 * Xar file represented as a VFS I/O stream.
     101 */
     102typedef struct RTZIPXARIOSTREAM
     103{
     104    /** The basic XAR object data. */
     105    RTZIPXARBASEOBJ         BaseObj;
    124106    /** The number of bytes in the file. */
    125107    RTFOFF                  cbFile;
     
    132114    /** The input I/O stream. */
    133115    RTVFSIOSTREAM           hVfsIos;
    134 } RTZIPTARIOSTREAM;
    135 /** Pointer to a the private data of a TAR file I/O stream. */
    136 typedef RTZIPTARIOSTREAM *PRTZIPTARIOSTREAM;
    137 
    138 
    139 /**
    140  * Tar filesystem stream private data.
    141  */
    142 typedef struct RTZIPTARFSSTREAM
     116} RTZIPXARIOSTREAM;
     117/** Pointer to a the private data of a XAR file I/O stream. */
     118typedef RTZIPXARIOSTREAM *PRTZIPXARIOSTREAM;
     119
     120
     121/**
     122 * Xar filesystem stream private data.
     123 */
     124typedef struct RTZIPXARFSSTREAM
    143125{
    144126    /** The input I/O stream. */
    145127    RTVFSIOSTREAM           hVfsIos;
     128    /** The input file, if the stream is actually a file. */
     129    RTVFSFILE               hVfsFile;
    146130
    147131    /** The current object (referenced). */
    148132    RTVFSOBJ                hVfsCurObj;
    149133    /** Pointer to the private data if hVfsCurObj is representing a file. */
    150     PRTZIPTARIOSTREAM       pCurIosData;
    151 
    152     /** The start offset. */
     134    PRTZIPXARIOSTREAM       pCurIosData;
     135
     136    /** The start offset in the input I/O stream. */
    153137    RTFOFF                  offStart;
    154     /** The offset of the next header. */
    155     RTFOFF                  offNextHdr;
     138    /** The zero offset in the file which all others are relative to. */
     139    RTFOFF                  offZero;
     140
     141    /** The hash function we're using (XAR_HASH_XXX). */
     142    uint8_t                 uHashFunction;
     143    /** The size of the digest produced by the hash function we're using. */
     144    uint8_t                 cbHashDigest;
    156145
    157146    /** Set if we've reached the end of the stream. */
     
    160149    int                     rcFatal;
    161150
    162     /** The TAR reader instance data. */
    163     RTZIPTARREADER          TarReader;
    164 } RTZIPTARFSSTREAM;
    165 /** Pointer to a the private data of a TAR filesystem stream. */
    166 typedef RTZIPTARFSSTREAM *PRTZIPTARFSSTREAM;
    167 
    168 
    169 
    170 /**
    171  * Converts a numeric header field to the C native type.
     151
     152    /** The XAR reader instance data. */
     153    RTZIPXARREADER          XarReader;
     154} RTZIPXARFSSTREAM;
     155/** Pointer to a the private data of a XAR filesystem stream. */
     156typedef RTZIPXARFSSTREAM *PRTZIPXARFSSTREAM;
     157
     158
     159/**
     160 * Hashes a block of data.
    172161 *
    173  * @returns IPRT status code.
    174  *
    175  * @param   pszField            The TAR header field.
    176  * @param   cchField            The length of the field.
    177  * @param   fOctalOnly          Must be octal.
    178  * @param   pi64                Where to store the value.
    179  */
    180 static int rtZipTarHdrFieldToNum(const char *pszField, size_t cchField, bool fOctalOnly, int64_t *pi64)
    181 {
    182     unsigned char const *puchField   = (unsigned char const *)pszField;
    183     size_t const         cchFieldOrg = cchField;
    184     if (   fOctalOnly
    185         || !(*puchField & 0x80))
    186     {
    187         /*
    188          * Skip leading spaces. Include zeros to save a few slower loops below.
    189          */
    190         unsigned char ch;
    191         while (cchField > 0 && ((ch = *puchField) == ' '|| ch == '0'))
    192             cchField--, puchField++;
    193 
    194         /*
    195          * Convert octal digits.
    196          */
    197         int64_t i64 = 0;
    198         while (cchField > 0)
    199         {
    200             unsigned char uDigit = *puchField - '0';
    201             if (uDigit >= 8)
    202                 break;
    203             i64 <<= 3;
    204             i64 |= uDigit;
    205 
    206             puchField++;
    207             cchField--;
    208         }
    209         *pi64 = i64;
    210 
    211         /*
    212          * Was it terminated correctly?
    213          */
    214         while (cchField > 0)
    215         {
    216             ch = *puchField++;
    217             if (ch != 0 && ch != ' ')
    218                 return cchField < cchFieldOrg
    219                      ? VERR_TAR_BAD_NUM_FIELD_TERM
    220                      : VERR_TAR_BAD_NUM_FIELD;
    221             cchField--;
    222         }
    223     }
    224     else
    225     {
    226         /*
    227          * The first byte has the bit 7 set to indicate base-256, while bit 6
    228          * is the signed bit. Bits 5:0 are the most significant value bits.
    229          */
    230         int64_t i64 = !(0x40 & *puchField) ? 0 : -1;
    231         i64 = (i64 << 6) | (*puchField & 0x3f);
    232         cchField--;
    233         puchField++;
    234 
    235         /*
    236          * The remaining bytes are used in full.
    237          */
    238         while (cchField-- > 0)
    239         {
    240             if (RT_UNLIKELY(i64 > INT64_MAX / 256))
    241                 return VERR_TAR_NUM_VALUE_TOO_LARGE;
    242             if (RT_UNLIKELY(i64 < INT64_MIN / 256))
    243                 return VERR_TAR_NUM_VALUE_TOO_LARGE;
    244             i64 = (i64 << 8) | *puchField++;
    245         }
    246         *pi64 = i64;
    247     }
     162 * @param   uHashFunction   The hash function to use.
     163 * @param   pvSrc           The data to hash.
     164 * @param   cbSrc           The size of the data to hash.
     165 * @param   pHashDigest     Where to return the hash digest.
     166 */
     167static void rtZipXarCalcHash(uint32_t uHashFunction, void const *pvSrc, size_t cbSrc, PRTZIPXARHASHDIGEST pHashDigest)
     168{
     169    switch (uHashFunction)
     170    {
     171        case XAR_HASH_SHA1:
     172            RTSha1(pvSrc, cbSrc, pHashDigest->abSha1);
     173            break;
     174        case XAR_HASH_MD5:
     175            RTMd5(pvSrc, cbSrc, pHashDigest->abMd5);
     176            break;
     177        default:
     178            RT_ZERO(*pHashDigest);
     179            break;
     180    }
     181}
     182
     183
     184static int rtZipXarGetOffsetSizeFromElem(xml::ElementNode const *pElement, PRTFOFF poff, uint64_t *pcb)
     185{
     186    /*
     187     * The offset.
     188     */
     189    xml::ElementNode const *pElem = pElement->findChildElement("offset");
     190    if (!pElem)
     191        return VERR_XAR_MISSING_OFFSET_ELEMENT;
     192    const char *pszValue = pElem->getValue();
     193    if (!pszValue)
     194        return VERR_XAR_BAD_OFFSET_ELEMENT;
     195
     196    int rc = RTStrToInt64Full(pszValue, 0, poff);
     197    if (   RT_FAILURE(rc)
     198        || rc == VWRN_NUMBER_TOO_BIG
     199        || *poff > RTFOFF_MAX / 2 /* make sure to not overflow calculating offsets. */
     200        || *poff < 0)
     201        return VERR_XAR_BAD_OFFSET_ELEMENT;
     202
     203    /*
     204     * The size.
     205     */
     206    pElem = pElement->findChildElement("size");
     207    if (!pElem)
     208        return VERR_XAR_MISSING_SIZE_ELEMENT;
     209
     210    pszValue = pElem->getValue();
     211    if (!pszValue)
     212        return VERR_XAR_BAD_SIZE_ELEMENT;
     213
     214    rc = RTStrToUInt64Full(pszValue, 0, pcb);
     215    if (   RT_FAILURE(rc)
     216        || rc == VWRN_NUMBER_TOO_BIG
     217        || *pcb > UINT64_MAX / 2 /* prevent overflow should be use it for calcuations later. */)
     218        return VERR_XAR_BAD_SIZE_ELEMENT;
    248219
    249220    return VINF_SUCCESS;
     
    252223
    253224/**
    254  * Calculates the TAR header checksums and detects if it's all zeros.
    255  *
    256  * @returns true if all zeros, false if not.
    257  * @param   pHdr                The header to checksum.
    258  * @param   pi32Unsigned        Where to store the checksum calculated using
    259  *                              unsigned chars.   This is the one POSIX
    260  *                              specifies.
    261  * @param   pi32Signed          Where to store the checksum calculated using
    262  *                              signed chars.
    263  *
    264  * @remarks The reason why we calculate the checksum as both signed and unsigned
    265  *          has to do with various the char C type being signed on some hosts
    266  *          and unsigned on others.
    267  */
    268 static bool rtZipTarCalcChkSum(PCRTZIPTARHDR pHdr, int32_t *pi32Unsigned, int32_t *pi32Signed)
    269 {
    270     int32_t i32Unsigned = 0;
    271     int32_t i32Signed   = 0;
    272 
    273     /*
    274      * Sum up the entire header.
    275      */
    276     const char *pch    = (const char *)pHdr;
    277     const char *pchEnd = pch + sizeof(*pHdr);
    278     do
    279     {
    280         i32Unsigned += *(unsigned char *)pch;
    281         i32Signed   += *(signed   char *)pch;
    282     } while (++pch != pchEnd);
    283 
    284     /*
    285      * Check if it's all zeros and replace the chksum field with spaces.
    286      */
    287     bool const fZeroHdr = i32Unsigned == 0;
    288 
    289     pch    = pHdr->Common.chksum;
    290     pchEnd = pch + sizeof(pHdr->Common.chksum);
    291     do
    292     {
    293         i32Unsigned -= *(unsigned char *)pch;
    294         i32Signed   -= *(signed   char *)pch;
    295     } while (++pch != pchEnd);
    296 
    297     i32Unsigned += (unsigned char)' ' * sizeof(pHdr->Common.chksum);
    298     i32Signed   += (signed   char)' ' * sizeof(pHdr->Common.chksum);
    299 
    300     *pi32Unsigned = i32Unsigned;
    301     if (pi32Signed)
    302         *pi32Signed = i32Signed;
    303     return fZeroHdr;
    304 }
    305 
    306 
    307 /**
    308  * Validates the TAR header.
    309  *
    310  * @returns VINF_SUCCESS if valid, VERR_TAR_ZERO_HEADER if all zeros, and
    311  *          the appropriate VERR_TAR_XXX otherwise.
    312  * @param   pTar                The TAR header.
    313  * @param   penmType            Where to return the type of header on success.
    314  */
    315 static int rtZipTarHdrValidate(PCRTZIPTARHDR pTar, PRTZIPTARTYPE penmType)
    316 {
    317     /*
    318      * Calc the checksum first since this enables us to detect zero headers.
    319      */
    320     int32_t i32ChkSum;
    321     int32_t i32ChkSumSignedAlt;
    322     if (rtZipTarCalcChkSum(pTar, &i32ChkSum, &i32ChkSumSignedAlt))
    323         return VERR_TAR_ZERO_HEADER;
    324 
    325     /*
    326      * Read the checksum field and match the checksums.
    327      */
    328     int64_t i64HdrChkSum;
    329     int rc = rtZipTarHdrFieldToNum(pTar->Common.chksum, sizeof(pTar->Common.chksum), true /*fOctalOnly*/, &i64HdrChkSum);
    330     if (RT_FAILURE(rc))
    331         return VERR_TAR_BAD_CHKSUM_FIELD;
    332     if (   i32ChkSum          != i64HdrChkSum
    333         && i32ChkSumSignedAlt != i64HdrChkSum) /** @todo test this */
    334         return VERR_TAR_CHKSUM_MISMATCH;
    335 
    336     /*
    337      * Detect the TAR type.
    338      */
    339     RTZIPTARTYPE enmType;
    340     if (   pTar->Common.magic[0] == 'u'
    341         && pTar->Common.magic[1] == 's'
    342         && pTar->Common.magic[2] == 't'
    343         && pTar->Common.magic[3] == 'a'
    344         && pTar->Common.magic[4] == 'r')
    345     {
    346 /** @todo detect star headers */
    347         if (   pTar->Common.magic[5]   == '\0'
    348             && pTar->Common.version[0] == '0'
    349             && pTar->Common.version[1] == '0')
    350             enmType = RTZIPTARTYPE_POSIX;
    351         else if (   pTar->Common.magic[5]   == ' '
    352                 && pTar->Common.version[0] == ' '
    353                 && pTar->Common.version[1] == '\0')
    354             enmType = RTZIPTARTYPE_GNU;
    355         else
    356             return VERR_TAR_NOT_USTAR_V00;
    357     }
    358     else
    359         enmType = RTZIPTARTYPE_ANCIENT;
    360     *penmType = enmType;
    361 
    362     /*
    363      * Perform some basic checks.
    364      */
    365     switch (enmType)
    366     {
    367         case RTZIPTARTYPE_POSIX:
    368             if (   !RT_C_IS_ALNUM(pTar->Common.typeflag)
    369                 && !pTar->Common.typeflag == '\0')
    370                 return VERR_TAR_UNKNOWN_TYPE_FLAG;
    371             break;
    372 
    373         case RTZIPTARTYPE_GNU:
    374             switch (pTar->Common.typeflag)
    375             {
    376                 case RTZIPTAR_TF_OLDNORMAL:
    377                 case RTZIPTAR_TF_NORMAL:
    378                 case RTZIPTAR_TF_CONTIG:
    379                 case RTZIPTAR_TF_DIR:
    380                 case RTZIPTAR_TF_CHR:
    381                 case RTZIPTAR_TF_BLK:
    382                 case RTZIPTAR_TF_LINK:
    383                 case RTZIPTAR_TF_SYMLINK:
    384                 case RTZIPTAR_TF_FIFO:
    385                     break;
    386 
    387                 case RTZIPTAR_TF_GNU_LONGLINK:
    388                 case RTZIPTAR_TF_GNU_LONGNAME:
    389                     break;
    390 
    391                 case RTZIPTAR_TF_GNU_DUMPDIR:
    392                 case RTZIPTAR_TF_GNU_MULTIVOL:
    393                 case RTZIPTAR_TF_GNU_SPARSE:
    394                 case RTZIPTAR_TF_GNU_VOLDHR:
    395                     /** @todo Implement full GNU TAR support. .*/
    396                     return VERR_TAR_UNSUPPORTED_GNU_HDR_TYPE;
    397 
    398                 default:
    399                     return VERR_TAR_UNKNOWN_TYPE_FLAG;
    400             }
    401             break;
    402 
    403         case RTZIPTARTYPE_ANCIENT:
    404             switch (pTar->Common.typeflag)
    405             {
    406                 case RTZIPTAR_TF_OLDNORMAL:
    407                 case RTZIPTAR_TF_NORMAL:
    408                 case RTZIPTAR_TF_CONTIG:
    409                 case RTZIPTAR_TF_DIR:
    410                 case RTZIPTAR_TF_LINK:
    411                 case RTZIPTAR_TF_SYMLINK:
    412                 case RTZIPTAR_TF_FIFO:
    413                     break;
    414                 default:
    415                     return VERR_TAR_UNKNOWN_TYPE_FLAG;
    416             }
    417             break;
    418         default: /* shut up gcc */
    419             AssertFailedReturn(VERR_INTERNAL_ERROR_3);
    420     }
    421 
    422     return VINF_SUCCESS;
    423 }
    424 
    425 
    426 /**
    427  * Parses and validates the first TAR header of a archive/file/dir/whatever.
    428  *
    429  * @returns IPRT status code.
    430  * @param   pThis               The TAR reader stat.
    431  * @param   pTar                The TAR header that has been read.
    432  * @param   fFirst              Set if this is the first header, otherwise
    433  *                              clear.
    434  */
    435 static int rtZipTarReaderParseNextHeader(PRTZIPTARREADER pThis, PCRTZIPTARHDR pHdr, bool fFirst)
    436 {
    437     int rc;
    438 
    439     /*
    440      * Basic header validation and detection first.
    441      */
    442     RTZIPTARTYPE enmType;
    443     rc = rtZipTarHdrValidate(pHdr, &enmType);
    444     if (RT_FAILURE_NP(rc))
    445     {
    446         if (rc == VERR_TAR_ZERO_HEADER)
    447         {
    448             pThis->cZeroHdrs = 1;
    449             pThis->enmState = RTZIPTARREADERSTATE_ZERO;
    450             return VINF_SUCCESS;
    451         }
    452         return rc;
    453     }
    454     if (fFirst)
    455         pThis->enmType = enmType;
    456 
    457     /*
    458      * Handle the header by type.
    459      */
    460     switch (pHdr->Common.typeflag)
    461     {
    462         case RTZIPTAR_TF_OLDNORMAL:
    463         case RTZIPTAR_TF_NORMAL:
    464         case RTZIPTAR_TF_CONTIG:
    465         case RTZIPTAR_TF_LINK:
    466         case RTZIPTAR_TF_SYMLINK:
    467         case RTZIPTAR_TF_CHR:
    468         case RTZIPTAR_TF_BLK:
    469         case RTZIPTAR_TF_FIFO:
    470         case RTZIPTAR_TF_DIR:
    471             /*
    472              * Extract the name first.
    473              */
    474             if (!pHdr->Common.name[0])
    475                 return VERR_TAR_EMPTY_NAME;
    476             if (pThis->enmType == RTZIPTARTYPE_POSIX)
    477             {
    478                 Assert(pThis->offGnuLongCur == 0); Assert(pThis->szName[0] == '\0');
    479                 pThis->szName[0] = '\0';
    480                 if (pHdr->Posix.prefix[0])
    481                 {
    482                     rc = RTStrCopyEx(pThis->szName, sizeof(pThis->szName), pHdr->Posix.prefix, sizeof(pHdr->Posix.prefix));
    483                     AssertRC(rc); /* shall not fail */
    484                     rc = RTStrCat(pThis->szName, sizeof(pThis->szName), "/");
    485                     AssertRC(rc); /* ditto */
    486                 }
    487                 rc = RTStrCatEx(pThis->szName, sizeof(pThis->szName), pHdr->Common.name, sizeof(pHdr->Common.name));
    488                 AssertRCReturn(rc, rc);
    489             }
    490             else if (pThis->enmType == RTZIPTARTYPE_GNU)
    491             {
    492                 if (!pThis->szName[0])
    493                 {
    494                     rc = RTStrCopyEx(pThis->szName, sizeof(pThis->szName), pHdr->Common.name, sizeof(pHdr->Common.name));
    495                     AssertRCReturn(rc, rc);
    496                 }
    497             }
    498             else
    499             {
    500                 /* Old TAR */
    501                 Assert(pThis->offGnuLongCur == 0); Assert(pThis->szName[0] == '\0');
    502                 rc = RTStrCopyEx(pThis->szName, sizeof(pThis->szName), pHdr->Common.name, sizeof(pHdr->Common.name));
    503                 AssertRCReturn(rc, rc);
    504             }
    505 
    506             /*
    507              * Extract the link target.
    508              */
    509             if (   pHdr->Common.typeflag == RTZIPTAR_TF_LINK
    510                 || pHdr->Common.typeflag == RTZIPTAR_TF_SYMLINK)
    511             {
    512                 if (   pThis->enmType == RTZIPTARTYPE_POSIX
    513                     || pThis->enmType == RTZIPTARTYPE_ANCIENT
    514                     || (pThis->enmType == RTZIPTARTYPE_GNU && pThis->szTarget[0] == '\0')
    515                    )
    516                 {
    517                     Assert(pThis->szTarget[0] == '\0');
    518                     rc = RTStrCopyEx(pThis->szTarget, sizeof(pThis->szTarget),
    519                                      pHdr->Common.linkname, sizeof(pHdr->Common.linkname));
    520                     AssertRCReturn(rc, rc);
    521                 }
    522             }
    523             else
    524                 pThis->szTarget[0] = '\0';
    525 
    526             pThis->Hdr = *pHdr;
    527             break;
    528 
    529         case RTZIPTAR_TF_X_HDR:
    530         case RTZIPTAR_TF_X_GLOBAL:
    531             /** @todo implement PAX */
    532             return VERR_TAR_UNSUPPORTED_PAX_TYPE;
    533 
    534         case RTZIPTAR_TF_SOLARIS_XHDR:
    535             /** @todo implement solaris / pax attribute lists. */
    536             return VERR_TAR_UNSUPPORTED_SOLARIS_HDR_TYPE;
    537 
    538 
    539         /*
    540          * A GNU long name or long link is a dummy record followed by one or
    541          * more 512 byte string blocks holding the long name/link.  The name
    542          * lenght is encoded in the size field, null terminator included.  If
    543          * it is a symlink or hard link the long name may be followed by a
    544          * long link sequence.
    545          */
    546         case RTZIPTAR_TF_GNU_LONGNAME:
    547         case RTZIPTAR_TF_GNU_LONGLINK:
    548         {
    549             if (strcmp(pHdr->Gnu.name, "././@LongLink"))
    550                 return VERR_TAR_MALFORMED_GNU_LONGXXXX;
    551 
    552             int64_t cb64;
    553             rc = rtZipTarHdrFieldToNum(pHdr->Gnu.size, sizeof(pHdr->Gnu.size), false /*fOctalOnly*/, &cb64);
    554             if (RT_FAILURE(rc) || cb64 < 0 || cb64 > _1M)
    555                 return VERR_TAR_MALFORMED_GNU_LONGXXXX;
    556             uint32_t cb = (uint32_t)cb64;
    557             if (cb >= sizeof(pThis->szName))
    558                 return VERR_TAR_NAME_TOO_LONG;
    559 
    560             pThis->cbGnuLongExpect  = cb;
    561             pThis->offGnuLongCur    = 0;
    562             pThis->enmState         = pHdr->Common.typeflag == RTZIPTAR_TF_GNU_LONGNAME
    563                                     ? RTZIPTARREADERSTATE_GNU_LONGNAME
    564                                     : RTZIPTARREADERSTATE_GNU_LONGLINK;
    565             break;
    566         }
    567 
    568         case RTZIPTAR_TF_GNU_DUMPDIR:
    569         case RTZIPTAR_TF_GNU_MULTIVOL:
    570         case RTZIPTAR_TF_GNU_SPARSE:
    571         case RTZIPTAR_TF_GNU_VOLDHR:
    572             /** @todo Implement or skip GNU headers */
    573             return VERR_TAR_UNSUPPORTED_GNU_HDR_TYPE;
    574 
    575         default:
    576             return VERR_TAR_UNKNOWN_TYPE_FLAG;
    577     }
    578 
    579     return VINF_SUCCESS;
    580 }
    581 
    582 
    583 /**
    584  * Parses and validates a TAR header.
    585  *
    586  * @returns IPRT status code.
    587  * @param   pThis               The TAR reader stat.
    588  * @param   pTar                The TAR header that has been read.
    589  */
    590 static int rtZipTarReaderParseHeader(PRTZIPTARREADER pThis, PCRTZIPTARHDR pHdr)
    591 {
    592     switch (pThis->enmState)
    593     {
    594         /*
    595          * The first record for a file/directory/whatever.
    596          */
    597         case RTZIPTARREADERSTATE_FIRST:
    598             pThis->Hdr.Common.typeflag  = 0x7f;
    599             pThis->enmPrevType          = pThis->enmType;
    600             pThis->enmType              = RTZIPTARTYPE_INVALID;
    601             pThis->offGnuLongCur        = 0;
    602             pThis->cbGnuLongExpect      = 0;
    603             pThis->szName[0]            = '\0';
    604             pThis->szTarget[0]          = '\0';
    605             return rtZipTarReaderParseNextHeader(pThis, pHdr, true /*fFirst*/);
    606 
    607         /*
    608          * There should only be so many zero headers at the end of the file as
    609          * it is a function of the block size used when writing.  Don't go on
    610          * reading them forever in case someone points us to /dev/zero.
    611          */
    612         case RTZIPTARREADERSTATE_ZERO:
    613             if (ASMMemIsAllU32(pHdr, sizeof(*pHdr), 0) != NULL)
    614                 return VERR_TAR_ZERO_HEADER;
    615             pThis->cZeroHdrs++;
    616             if (pThis->cZeroHdrs <= _64K / 512 + 2)
    617                 return VINF_SUCCESS;
    618             return VERR_TAR_ZERO_HEADER;
    619 
    620         case RTZIPTARREADERSTATE_GNU_LONGNAME:
    621         case RTZIPTARREADERSTATE_GNU_LONGLINK:
    622         {
    623             size_t cbIncoming = RTStrNLen((const char *)pHdr->ab, sizeof(*pHdr));
    624             if (cbIncoming < sizeof(*pHdr))
    625                 cbIncoming += 1;
    626 
    627             if (cbIncoming + pThis->offGnuLongCur > pThis->cbGnuLongExpect)
    628                 return VERR_TAR_MALFORMED_GNU_LONGXXXX;
    629             if (   cbIncoming < sizeof(*pHdr)
    630                 && cbIncoming + pThis->offGnuLongCur != pThis->cbGnuLongExpect)
    631                 return VERR_TAR_MALFORMED_GNU_LONGXXXX;
    632 
    633             char *pszDst = pThis->enmState == RTZIPTARREADERSTATE_GNU_LONGNAME ? pThis->szName : pThis->szTarget;
    634             pszDst += pThis->offGnuLongCur;
    635             memcpy(pszDst, pHdr->ab, cbIncoming);
    636 
    637             pThis->offGnuLongCur += (uint32_t)cbIncoming;
    638             if (pThis->offGnuLongCur == pThis->cbGnuLongExpect)
    639                 pThis->enmState = RTZIPTARREADERSTATE_GNU_NEXT;
    640             return VINF_SUCCESS;
    641         }
    642 
    643         case RTZIPTARREADERSTATE_GNU_NEXT:
    644             pThis->enmState = RTZIPTARREADERSTATE_FIRST;
    645             return rtZipTarReaderParseNextHeader(pThis, pHdr, false /*fFirst*/);
    646 
    647         default:
    648             return VERR_INTERNAL_ERROR_5;
    649     }
    650 }
    651 
    652 
    653 /**
    654  * Translate a TAR header to an IPRT object info structure with additional UNIX
     225 * Translate a XAR header to an IPRT object info structure with additional UNIX
    655226 * attributes.
    656227 *
    657  * This completes the validation done by rtZipTarHdrValidate.
     228 * This completes the validation done by rtZipXarHdrValidate.
    658229 *
    659  * @returns VINF_SUCCESS if valid, appropriate VERR_TAR_XXX if not.
    660  * @param   pThis               The TAR reader instance.
     230 * @returns VINF_SUCCESS if valid, appropriate VERR_XAR_XXX if not.
     231 * @param   pThis               The XAR reader instance.
    661232 * @param   pObjInfo            The object info structure (output).
    662233 */
    663 static int rtZipTarReaderGetFsObjInfo(PRTZIPTARREADER pThis, PRTFSOBJINFO pObjInfo)
     234static int rtZipXarReaderGetFsObjInfo(PRTZIPXARREADER pThis, PRTFSOBJINFO pObjInfo)
    664235{
    665236    /*
     
    668239    RT_ZERO(*pObjInfo);
    669240
    670     /*
    671      * Convert the TAR field in RTFSOBJINFO order.
     241#if 0
     242    /*
     243     * Convert the XAR field in RTFSOBJINFO order.
    672244     */
    673245    int         rc;
    674246    int64_t     i64Tmp;
    675 #define GET_TAR_NUMERIC_FIELD_RET(a_Var, a_Field) \
     247#define GET_XAR_NUMERIC_FIELD_RET(a_Var, a_Field) \
    676248        do { \
    677             rc = rtZipTarHdrFieldToNum(a_Field, sizeof(a_Field), false /*fOctalOnly*/, &i64Tmp); \
     249            rc = rtZipXarHdrFieldToNum(a_Field, sizeof(a_Field), false /*fOctalOnly*/, &i64Tmp); \
    678250            if (RT_FAILURE(rc)) \
    679251                return rc; \
    680252            (a_Var) = i64Tmp; \
    681253            if ((a_Var) != i64Tmp) \
    682                 return VERR_TAR_NUM_VALUE_TOO_LARGE; \
     254                return VERR_XAR_NUM_VALUE_TOO_LARGE; \
    683255        } while (0)
    684256
    685     GET_TAR_NUMERIC_FIELD_RET(pObjInfo->cbObject,        pThis->Hdr.Common.size);
     257    GET_XAR_NUMERIC_FIELD_RET(pObjInfo->cbObject,        pThis->Hdr.Common.size);
    686258    pObjInfo->cbAllocated = RT_ALIGN_64(pObjInfo->cbObject, 512);
    687259    int64_t c64SecModTime;
    688     GET_TAR_NUMERIC_FIELD_RET(c64SecModTime,             pThis->Hdr.Common.mtime);
     260    GET_XAR_NUMERIC_FIELD_RET(c64SecModTime,             pThis->Hdr.Common.mtime);
    689261    RTTimeSpecSetSeconds(&pObjInfo->ChangeTime,          c64SecModTime);
    690262    RTTimeSpecSetSeconds(&pObjInfo->ModificationTime,    c64SecModTime);
     
    692264    RTTimeSpecSetSeconds(&pObjInfo->BirthTime,           c64SecModTime);
    693265    if (c64SecModTime != RTTimeSpecGetSeconds(&pObjInfo->ModificationTime))
    694         return VERR_TAR_NUM_VALUE_TOO_LARGE;
    695     GET_TAR_NUMERIC_FIELD_RET(pObjInfo->Attr.fMode,      pThis->Hdr.Common.mode);
     266        return VERR_XAR_NUM_VALUE_TOO_LARGE;
     267    GET_XAR_NUMERIC_FIELD_RET(pObjInfo->Attr.fMode,      pThis->Hdr.Common.mode);
    696268    pObjInfo->Attr.enmAdditional = RTFSOBJATTRADD_UNIX;
    697     GET_TAR_NUMERIC_FIELD_RET(pObjInfo->Attr.u.Unix.uid, pThis->Hdr.Common.uid);
    698     GET_TAR_NUMERIC_FIELD_RET(pObjInfo->Attr.u.Unix.gid, pThis->Hdr.Common.gid);
     269    GET_XAR_NUMERIC_FIELD_RET(pObjInfo->Attr.u.Unix.uid, pThis->Hdr.Common.uid);
     270    GET_XAR_NUMERIC_FIELD_RET(pObjInfo->Attr.u.Unix.gid, pThis->Hdr.Common.gid);
    699271    pObjInfo->Attr.u.Unix.cHardlinks    = 1;
    700272    pObjInfo->Attr.u.Unix.INodeIdDevice = 0;
     
    705277    switch (pThis->enmType)
    706278    {
    707         case RTZIPTARTYPE_POSIX:
    708         case RTZIPTARTYPE_GNU:
    709             if (   pThis->Hdr.Common.typeflag == RTZIPTAR_TF_CHR
    710                 || pThis->Hdr.Common.typeflag == RTZIPTAR_TF_BLK)
     279        case RTZIPXARTYPE_POSIX:
     280        case RTZIPXARTYPE_GNU:
     281            if (   pThis->Hdr.Common.typeflag == RTZIPXAR_TF_CHR
     282                || pThis->Hdr.Common.typeflag == RTZIPXAR_TF_BLK)
    711283            {
    712284                uint32_t uMajor, uMinor;
    713                 GET_TAR_NUMERIC_FIELD_RET(uMajor,        pThis->Hdr.Common.devmajor);
    714                 GET_TAR_NUMERIC_FIELD_RET(uMinor,        pThis->Hdr.Common.devminor);
     285                GET_XAR_NUMERIC_FIELD_RET(uMajor,        pThis->Hdr.Common.devmajor);
     286                GET_XAR_NUMERIC_FIELD_RET(uMinor,        pThis->Hdr.Common.devminor);
    715287                pObjInfo->Attr.u.Unix.Device    = RTDEV_MAKE(uMajor, uMinor);
    716288                if (   uMajor != RTDEV_MAJOR(pObjInfo->Attr.u.Unix.Device)
    717289                    || uMinor != RTDEV_MINOR(pObjInfo->Attr.u.Unix.Device))
    718                     return VERR_TAR_DEV_VALUE_TOO_LARGE;
     290                    return VERR_XAR_DEV_VALUE_TOO_LARGE;
    719291            }
    720292            break;
    721293
    722294        default:
    723             if (   pThis->Hdr.Common.typeflag == RTZIPTAR_TF_CHR
    724                 || pThis->Hdr.Common.typeflag == RTZIPTAR_TF_BLK)
    725                 return VERR_TAR_UNKNOWN_TYPE_FLAG;
    726     }
    727 
    728 #undef GET_TAR_NUMERIC_FIELD_RET
     295            if (   pThis->Hdr.Common.typeflag == RTZIPXAR_TF_CHR
     296                || pThis->Hdr.Common.typeflag == RTZIPXAR_TF_BLK)
     297                return VERR_XAR_UNKNOWN_TYPE_FLAG;
     298    }
     299
     300#undef GET_XAR_NUMERIC_FIELD_RET
    729301
    730302    /*
     
    733305     */
    734306    if (   (pObjInfo->Attr.fMode & ~RTFS_UNIX_MASK)
    735         && pThis->enmType == RTZIPTARTYPE_POSIX)
    736         return VERR_TAR_BAD_MODE_FIELD;
     307        && pThis->enmType == RTZIPXARTYPE_POSIX)
     308        return VERR_XAR_BAD_MODE_FIELD;
    737309    pObjInfo->Attr.fMode &= RTFS_UNIX_MASK;
    738310
     
    740312    switch (pThis->Hdr.Common.typeflag)
    741313    {
    742         case RTZIPTAR_TF_OLDNORMAL:
    743         case RTZIPTAR_TF_NORMAL:
    744         case RTZIPTAR_TF_CONTIG:
     314        case RTZIPXAR_TF_OLDNORMAL:
     315        case RTZIPXAR_TF_NORMAL:
     316        case RTZIPXAR_TF_CONTIG:
    745317        {
    746318            const char *pszEnd = strchr(pThis->szName, '\0');
     
    752324        }
    753325
    754         case RTZIPTAR_TF_LINK:
     326        case RTZIPXAR_TF_LINK:
    755327            if (pObjInfo->cbObject != 0)
    756328#if 0 /* too strict */
    757                 return VERR_TAR_SIZE_NOT_ZERO;
     329                return VERR_XAR_SIZE_NOT_ZERO;
    758330#else
    759331                pObjInfo->cbObject = pObjInfo->cbAllocated = 0;
     
    762334            break;
    763335
    764         case RTZIPTAR_TF_SYMLINK:
     336        case RTZIPXAR_TF_SYMLINK:
    765337            fModeType |= RTFS_TYPE_SYMLINK;
    766338            break;
    767339
    768         case RTZIPTAR_TF_CHR:
     340        case RTZIPXAR_TF_CHR:
    769341            fModeType |= RTFS_TYPE_DEV_CHAR;
    770342            break;
    771343
    772         case RTZIPTAR_TF_BLK:
     344        case RTZIPXAR_TF_BLK:
    773345            fModeType |= RTFS_TYPE_DEV_BLOCK;
    774346            break;
    775347
    776         case RTZIPTAR_TF_DIR:
     348        case RTZIPXAR_TF_DIR:
    777349            fModeType |= RTFS_TYPE_DIRECTORY;
    778350            break;
    779351
    780         case RTZIPTAR_TF_FIFO:
     352        case RTZIPXAR_TF_FIFO:
    781353            fModeType |= RTFS_TYPE_FIFO;
    782354            break;
    783355
    784         case RTZIPTAR_TF_GNU_LONGLINK:
    785         case RTZIPTAR_TF_GNU_LONGNAME:
     356        case RTZIPXAR_TF_GNU_LONGLINK:
     357        case RTZIPXAR_TF_GNU_LONGNAME:
    786358            /* ASSUMES RTFS_TYPE_XXX uses the same values as GNU stored in the mode field. */
    787359            fModeType = pObjInfo->Attr.fMode & RTFS_TYPE_MASK;
     
    798370                default:
    799371                case 0:
    800                     return VERR_TAR_UNKNOWN_TYPE_FLAG; /** @todo new status code */
     372                    return VERR_XAR_UNKNOWN_TYPE_FLAG; /** @todo new status code */
    801373            }
    802374
    803375        default:
    804             return VERR_TAR_UNKNOWN_TYPE_FLAG; /* Should've been caught in validate. */
     376            return VERR_XAR_UNKNOWN_TYPE_FLAG; /* Should've been caught in validate. */
    805377    }
    806378    if (   (pObjInfo->Attr.fMode & RTFS_TYPE_MASK)
    807379        && (pObjInfo->Attr.fMode & RTFS_TYPE_MASK) != fModeType)
    808         return VERR_TAR_MODE_WITH_TYPE;
     380        return VERR_XAR_MODE_WITH_TYPE;
    809381    pObjInfo->Attr.fMode &= ~RTFS_TYPE_MASK;
    810382    pObjInfo->Attr.fMode |= fModeType;
     
    812384    switch (pThis->Hdr.Common.typeflag)
    813385    {
    814         case RTZIPTAR_TF_CHR:
    815         case RTZIPTAR_TF_BLK:
    816         case RTZIPTAR_TF_DIR:
    817         case RTZIPTAR_TF_FIFO:
     386        case RTZIPXAR_TF_CHR:
     387        case RTZIPXAR_TF_BLK:
     388        case RTZIPXAR_TF_DIR:
     389        case RTZIPXAR_TF_FIFO:
    818390            pObjInfo->cbObject    = 0;
    819391            pObjInfo->cbAllocated = 0;
    820392            break;
    821393    }
     394#endif
    822395
    823396    return VINF_SUCCESS;
    824397}
    825398
    826 
    827 /**
    828  * Checks if the reader is expecting more headers.
    829  *
    830  * @returns true / false.
    831  * @param   pThis               The TAR reader instance.
    832  */
    833 static bool rtZipTarReaderExpectingMoreHeaders(PRTZIPTARREADER pThis)
    834 {
    835     return pThis->enmState != RTZIPTARREADERSTATE_FIRST;
    836 }
    837 
    838 
    839 /**
    840  * Checks if we're at the end of the TAR file.
    841  *
    842  * @returns true / false.
    843  * @param   pThis               The TAR reader instance.
    844  */
    845 static bool rtZipTarReaderIsAtEnd(PRTZIPTARREADER pThis)
    846 {
    847     if (!pThis->cZeroHdrs)
    848         return false;
    849 
    850     /* Here is a kludge to try deal with archivers not putting at least two
    851        zero headers at the end.  Afraid it may require further relaxing
    852        later on, but let's try be strict about things for now. */
    853     return pThis->cZeroHdrs >= (pThis->enmPrevType == RTZIPTARTYPE_POSIX ? 2U : 1U);
    854 }
    855 
    856 
    857 /**
    858  * Checks if the current TAR object is a hard link or not.
    859  *
    860  * @returns true if it is, false if not.
    861  * @param   pThis               The TAR reader instance.
    862  */
    863 static bool rtZipTarReaderIsHardlink(PRTZIPTARREADER pThis)
    864 {
    865     return pThis->Hdr.Common.typeflag == RTZIPTAR_TF_LINK;
    866 }
    867 
    868 
    869 /**
    870  * Checks if the TAR header includes a POSIX or GNU user name field.
    871  *
    872  * @returns true / false.
    873  * @param   pThis               The TAR reader instance.
    874  */
    875 DECLINLINE(bool) rtZipTarReaderHasUserName(PRTZIPTARREADER pThis)
    876 {
    877     return pThis->Hdr.Common.uname[0] != '\0'
    878         && (   pThis->enmType == RTZIPTARTYPE_POSIX
    879             || pThis->enmType == RTZIPTARTYPE_GNU);
    880 }
    881 
    882 
    883 /**
    884  * Checks if the TAR header includes a POSIX or GNU group name field.
    885  *
    886  * @returns true / false.
    887  * @param   pThis               The TAR reader instance.
    888  */
    889 DECLINLINE(bool) rtZipTarReaderHasGroupName(PRTZIPTARREADER pThis)
    890 {
    891     return pThis->Hdr.Common.gname[0] != '\0'
    892         && (   pThis->enmType == RTZIPTARTYPE_POSIX
    893             || pThis->enmType == RTZIPTARTYPE_GNU);
    894 }
    895399
    896400
     
    906410 * @interface_method_impl{RTVFSOBJOPS,pfnClose}
    907411 */
    908 static DECLCALLBACK(int) rtZipTarFssBaseObj_Close(void *pvThis)
    909 {
    910     PRTZIPTARBASEOBJ pThis = (PRTZIPTARBASEOBJ)pvThis;
     412static DECLCALLBACK(int) rtZipXarFssBaseObj_Close(void *pvThis)
     413{
     414    PRTZIPXARBASEOBJ pThis = (PRTZIPXARBASEOBJ)pvThis;
    911415
    912416    /* Currently there is nothing we really have to do here. */
     
    920424 * @interface_method_impl{RTVFSOBJOPS,pfnQueryInfo}
    921425 */
    922 static DECLCALLBACK(int) rtZipTarFssBaseObj_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
    923 {
    924     PRTZIPTARBASEOBJ pThis = (PRTZIPTARBASEOBJ)pvThis;
    925 
     426static DECLCALLBACK(int) rtZipXarFssBaseObj_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
     427{
     428    PRTZIPXARBASEOBJ pThis = (PRTZIPXARBASEOBJ)pvThis;
     429
     430#if 0
    926431    /*
    927432     * Copy the desired data.
     
    939444            pObjInfo->Attr.u.UnixOwner.uid       = pThis->ObjInfo.Attr.u.Unix.uid;
    940445            pObjInfo->Attr.u.UnixOwner.szName[0] = '\0';
    941             if (rtZipTarReaderHasUserName(pThis->pTarReader))
     446            if (rtZipXarReaderHasUserName(pThis->pXarReader))
    942447                RTStrCopy(pObjInfo->Attr.u.UnixOwner.szName, sizeof(pObjInfo->Attr.u.UnixOwner.szName),
    943                           pThis->pTarReader->Hdr.Common.uname);
     448                          pThis->pXarReader->Hdr.Common.uname);
    944449            break;
    945450
     
    949454            pObjInfo->Attr.u.UnixGroup.gid       = pThis->ObjInfo.Attr.u.Unix.gid;
    950455            pObjInfo->Attr.u.UnixGroup.szName[0] = '\0';
    951             if (rtZipTarReaderHasGroupName(pThis->pTarReader))
     456            if (rtZipXarReaderHasGroupName(pThis->pXarReader))
    952457                RTStrCopy(pObjInfo->Attr.u.UnixGroup.szName, sizeof(pObjInfo->Attr.u.UnixGroup.szName),
    953                           pThis->pTarReader->Hdr.Common.gname);
     458                          pThis->pXarReader->Hdr.Common.gname);
    954459            break;
    955460
     
    963468            return VERR_NOT_SUPPORTED;
    964469    }
     470#endif
    965471
    966472    return VINF_SUCCESS;
     
    969475
    970476/**
    971  * Tar filesystem base object operations.
    972  */
    973 static const RTVFSOBJOPS g_rtZipTarFssBaseObjOps =
     477 * Xar filesystem base object operations.
     478 */
     479static const RTVFSOBJOPS g_rtZipXarFssBaseObjOps =
    974480{
    975481    RTVFSOBJOPS_VERSION,
    976482    RTVFSOBJTYPE_BASE,
    977     "TarFsStream::Obj",
    978     rtZipTarFssBaseObj_Close,
    979     rtZipTarFssBaseObj_QueryInfo,
     483    "XarFsStream::Obj",
     484    rtZipXarFssBaseObj_Close,
     485    rtZipXarFssBaseObj_QueryInfo,
    980486    RTVFSOBJOPS_VERSION
    981487};
     
    985491 * @interface_method_impl{RTVFSOBJOPS,pfnClose}
    986492 */
    987 static DECLCALLBACK(int) rtZipTarFssIos_Close(void *pvThis)
    988 {
    989     PRTZIPTARIOSTREAM pThis = (PRTZIPTARIOSTREAM)pvThis;
     493static DECLCALLBACK(int) rtZipXarFssIos_Close(void *pvThis)
     494{
     495    PRTZIPXARIOSTREAM pThis = (PRTZIPXARIOSTREAM)pvThis;
    990496
    991497    RTVfsIoStrmRelease(pThis->hVfsIos);
    992498    pThis->hVfsIos = NIL_RTVFSIOSTREAM;
    993499
    994     return rtZipTarFssBaseObj_Close(&pThis->BaseObj);
     500    return rtZipXarFssBaseObj_Close(&pThis->BaseObj);
    995501}
    996502
     
    999505 * @interface_method_impl{RTVFSOBJOPS,pfnQueryInfo}
    1000506 */
    1001 static DECLCALLBACK(int) rtZipTarFssIos_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
    1002 {
    1003     PRTZIPTARIOSTREAM pThis = (PRTZIPTARIOSTREAM)pvThis;
    1004     return rtZipTarFssBaseObj_QueryInfo(&pThis->BaseObj, pObjInfo, enmAddAttr);
     507static DECLCALLBACK(int) rtZipXarFssIos_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
     508{
     509    PRTZIPXARIOSTREAM pThis = (PRTZIPXARIOSTREAM)pvThis;
     510    return rtZipXarFssBaseObj_QueryInfo(&pThis->BaseObj, pObjInfo, enmAddAttr);
    1005511}
    1006512
     
    1016522 * @param   pcbRead         Where to store the number of bytes actually read.
    1017523 */
    1018 static int rtZipTarFssIos_ReadOneSeg(PRTZIPTARIOSTREAM pThis, void *pvBuf, size_t cbToRead, bool fBlocking, size_t *pcbRead)
     524static int rtZipXarFssIos_ReadOneSeg(PRTZIPXARIOSTREAM pThis, void *pvBuf, size_t cbToRead, bool fBlocking, size_t *pcbRead)
    1019525{
    1020526    /*
     
    1055561 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnRead}
    1056562 */
    1057 static DECLCALLBACK(int) rtZipTarFssIos_Read(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead)
    1058 {
    1059     PRTZIPTARIOSTREAM pThis = (PRTZIPTARIOSTREAM)pvThis;
     563static DECLCALLBACK(int) rtZipXarFssIos_Read(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead)
     564{
     565    PRTZIPXARIOSTREAM pThis = (PRTZIPXARIOSTREAM)pvThis;
    1060566    int               rc;
    1061567    AssertReturn(off == -1, VERR_INVALID_PARAMETER);
    1062568
    1063569    if (pSgBuf->cSegs == 1)
    1064         rc = rtZipTarFssIos_ReadOneSeg(pThis, pSgBuf->paSegs[0].pvSeg, pSgBuf->paSegs[0].cbSeg, fBlocking, pcbRead);
     570        rc = rtZipXarFssIos_ReadOneSeg(pThis, pSgBuf->paSegs[0].pvSeg, pSgBuf->paSegs[0].cbSeg, fBlocking, pcbRead);
    1065571    else
    1066572    {
     
    1072578        {
    1073579            cbReadSeg = 0;
    1074             rc = rtZipTarFssIos_ReadOneSeg(pThis, pSgBuf->paSegs[iSeg].pvSeg, pSgBuf->paSegs[iSeg].cbSeg, fBlocking, pcbReadSeg);
     580            rc = rtZipXarFssIos_ReadOneSeg(pThis, pSgBuf->paSegs[iSeg].pvSeg, pSgBuf->paSegs[iSeg].cbSeg, fBlocking, pcbReadSeg);
    1075581            if (RT_FAILURE(rc))
    1076582                break;
     
    1093599 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnWrite}
    1094600 */
    1095 static DECLCALLBACK(int) rtZipTarFssIos_Write(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten)
     601static DECLCALLBACK(int) rtZipXarFssIos_Write(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten)
    1096602{
    1097603    /* Cannot write to a read-only I/O stream. */
     
    1104610 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnFlush}
    1105611 */
    1106 static DECLCALLBACK(int) rtZipTarFssIos_Flush(void *pvThis)
     612static DECLCALLBACK(int) rtZipXarFssIos_Flush(void *pvThis)
    1107613{
    1108614    /* It's a read only stream, nothing dirty to flush. */
     
    1115621 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnPollOne}
    1116622 */
    1117 static DECLCALLBACK(int) rtZipTarFssIos_PollOne(void *pvThis, uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr,
     623static DECLCALLBACK(int) rtZipXarFssIos_PollOne(void *pvThis, uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr,
    1118624                                                uint32_t *pfRetEvents)
    1119625{
    1120     PRTZIPTARIOSTREAM pThis = (PRTZIPTARIOSTREAM)pvThis;
     626    PRTZIPXARIOSTREAM pThis = (PRTZIPXARIOSTREAM)pvThis;
    1121627
    1122628    /* When we've reached the end, read will be set to indicate it. */
     
    1139645 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnTell}
    1140646 */
    1141 static DECLCALLBACK(int) rtZipTarFssIos_Tell(void *pvThis, PRTFOFF poffActual)
    1142 {
    1143     PRTZIPTARIOSTREAM pThis = (PRTZIPTARIOSTREAM)pvThis;
     647static DECLCALLBACK(int) rtZipXarFssIos_Tell(void *pvThis, PRTFOFF poffActual)
     648{
     649    PRTZIPXARIOSTREAM pThis = (PRTZIPXARIOSTREAM)pvThis;
    1144650    *poffActual = pThis->offFile;
    1145651    return VINF_SUCCESS;
     
    1148654
    1149655/**
    1150  * Tar I/O stream operations.
    1151  */
    1152 static const RTVFSIOSTREAMOPS g_rtZipTarFssIosOps =
     656 * Xar I/O stream operations.
     657 */
     658static const RTVFSIOSTREAMOPS g_rtZipXarFssIosOps =
    1153659{
    1154660    { /* Obj */
    1155661        RTVFSOBJOPS_VERSION,
    1156662        RTVFSOBJTYPE_IO_STREAM,
    1157         "TarFsStream::IoStream",
    1158         rtZipTarFssIos_Close,
    1159         rtZipTarFssIos_QueryInfo,
     663        "XarFsStream::IoStream",
     664        rtZipXarFssIos_Close,
     665        rtZipXarFssIos_QueryInfo,
    1160666        RTVFSOBJOPS_VERSION
    1161667    },
    1162668    RTVFSIOSTREAMOPS_VERSION,
    1163669    0,
    1164     rtZipTarFssIos_Read,
    1165     rtZipTarFssIos_Write,
    1166     rtZipTarFssIos_Flush,
    1167     rtZipTarFssIos_PollOne,
    1168     rtZipTarFssIos_Tell,
     670    rtZipXarFssIos_Read,
     671    rtZipXarFssIos_Write,
     672    rtZipXarFssIos_Flush,
     673    rtZipXarFssIos_PollOne,
     674    rtZipXarFssIos_Tell,
    1169675    NULL /*Skip*/,
    1170676    NULL /*ZeroFill*/,
     
    1176682 * @interface_method_impl{RTVFSOBJOPS,pfnClose}
    1177683 */
    1178 static DECLCALLBACK(int) rtZipTarFssSym_Close(void *pvThis)
    1179 {
    1180     PRTZIPTARBASEOBJ pThis = (PRTZIPTARBASEOBJ)pvThis;
    1181     return rtZipTarFssBaseObj_Close(pThis);
     684static DECLCALLBACK(int) rtZipXarFssSym_Close(void *pvThis)
     685{
     686    PRTZIPXARBASEOBJ pThis = (PRTZIPXARBASEOBJ)pvThis;
     687    return rtZipXarFssBaseObj_Close(pThis);
    1182688}
    1183689
     
    1186692 * @interface_method_impl{RTVFSOBJOPS,pfnQueryInfo}
    1187693 */
    1188 static DECLCALLBACK(int) rtZipTarFssSym_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
    1189 {
    1190     PRTZIPTARBASEOBJ pThis = (PRTZIPTARBASEOBJ)pvThis;
    1191     return rtZipTarFssBaseObj_QueryInfo(pThis, pObjInfo, enmAddAttr);
     694static DECLCALLBACK(int) rtZipXarFssSym_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
     695{
     696    PRTZIPXARBASEOBJ pThis = (PRTZIPXARBASEOBJ)pvThis;
     697    return rtZipXarFssBaseObj_QueryInfo(pThis, pObjInfo, enmAddAttr);
    1192698}
    1193699
     
    1195701 * @interface_method_impl{RTVFSOBJSETOPS,pfnMode}
    1196702 */
    1197 static DECLCALLBACK(int) rtZipTarFssSym_SetMode(void *pvThis, RTFMODE fMode, RTFMODE fMask)
     703static DECLCALLBACK(int) rtZipXarFssSym_SetMode(void *pvThis, RTFMODE fMode, RTFMODE fMask)
    1198704{
    1199705    NOREF(pvThis); NOREF(fMode); NOREF(fMask);
     
    1205711 * @interface_method_impl{RTVFSOBJSETOPS,pfnSetTimes}
    1206712 */
    1207 static DECLCALLBACK(int) rtZipTarFssSym_SetTimes(void *pvThis, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
     713static DECLCALLBACK(int) rtZipXarFssSym_SetTimes(void *pvThis, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
    1208714                                                 PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime)
    1209715{
     
    1216722 * @interface_method_impl{RTVFSOBJSETOPS,pfnSetOwner}
    1217723 */
    1218 static DECLCALLBACK(int) rtZipTarFssSym_SetOwner(void *pvThis, RTUID uid, RTGID gid)
     724static DECLCALLBACK(int) rtZipXarFssSym_SetOwner(void *pvThis, RTUID uid, RTGID gid)
    1219725{
    1220726    NOREF(pvThis); NOREF(uid); NOREF(gid);
     
    1226732 * @interface_method_impl{RTVFSSYMLINKOPS,pfnRead}
    1227733 */
    1228 static DECLCALLBACK(int) rtZipTarFssSym_Read(void *pvThis, char *pszTarget, size_t cbTarget)
    1229 {
    1230     PRTZIPTARBASEOBJ pThis = (PRTZIPTARBASEOBJ)pvThis;
    1231     return RTStrCopy(pszTarget, cbTarget, pThis->pTarReader->szTarget);
    1232 }
    1233 
    1234 
    1235 /**
    1236  * Tar symbolic (and hardlink) operations.
    1237  */
    1238 static const RTVFSSYMLINKOPS g_rtZipTarFssSymOps =
     734static DECLCALLBACK(int) rtZipXarFssSym_Read(void *pvThis, char *pszTarget, size_t cbXarget)
     735{
     736    PRTZIPXARBASEOBJ pThis = (PRTZIPXARBASEOBJ)pvThis;
     737#if 0
     738    return RTStrCopy(pszTarget, cbXarget, pThis->pXarReader->szTarget);
     739#else
     740    return VERR_NOT_IMPLEMENTED;
     741#endif
     742}
     743
     744
     745/**
     746 * Xar symbolic (and hardlink) operations.
     747 */
     748static const RTVFSSYMLINKOPS g_rtZipXarFssSymOps =
    1239749{
    1240750    { /* Obj */
    1241751        RTVFSOBJOPS_VERSION,
    1242752        RTVFSOBJTYPE_SYMLINK,
    1243         "TarFsStream::Symlink",
    1244         rtZipTarFssSym_Close,
    1245         rtZipTarFssSym_QueryInfo,
     753        "XarFsStream::Symlink",
     754        rtZipXarFssSym_Close,
     755        rtZipXarFssSym_QueryInfo,
    1246756        RTVFSOBJOPS_VERSION
    1247757    },
     
    1251761        RTVFSOBJSETOPS_VERSION,
    1252762        RT_OFFSETOF(RTVFSSYMLINKOPS, Obj) - RT_OFFSETOF(RTVFSSYMLINKOPS, ObjSet),
    1253         rtZipTarFssSym_SetMode,
    1254         rtZipTarFssSym_SetTimes,
    1255         rtZipTarFssSym_SetOwner,
     763        rtZipXarFssSym_SetMode,
     764        rtZipXarFssSym_SetTimes,
     765        rtZipXarFssSym_SetOwner,
    1256766        RTVFSOBJSETOPS_VERSION
    1257767    },
    1258     rtZipTarFssSym_Read,
     768    rtZipXarFssSym_Read,
    1259769    RTVFSSYMLINKOPS_VERSION
    1260770};
     
    1264774 * @interface_method_impl{RTVFSOBJOPS,pfnClose}
    1265775 */
    1266 static DECLCALLBACK(int) rtZipTarFss_Close(void *pvThis)
    1267 {
    1268     PRTZIPTARFSSTREAM pThis = (PRTZIPTARFSSTREAM)pvThis;
     776static DECLCALLBACK(int) rtZipXarFss_Close(void *pvThis)
     777{
     778    PRTZIPXARFSSTREAM pThis = (PRTZIPXARFSSTREAM)pvThis;
    1269779
    1270780    RTVfsObjRelease(pThis->hVfsCurObj);
     
    1282792 * @interface_method_impl{RTVFSOBJOPS,pfnQueryInfo}
    1283793 */
    1284 static DECLCALLBACK(int) rtZipTarFss_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
    1285 {
    1286     PRTZIPTARFSSTREAM pThis = (PRTZIPTARFSSTREAM)pvThis;
     794static DECLCALLBACK(int) rtZipXarFss_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
     795{
     796    PRTZIPXARFSSTREAM pThis = (PRTZIPXARFSSTREAM)pvThis;
    1287797    /* Take the lazy approach here, with the sideffect of providing some info
    1288798       that is actually kind of useful. */
     
    1294804 * @interface_method_impl{RTVFSFSSTREAMOPS,pfnNext}
    1295805 */
    1296 static DECLCALLBACK(int) rtZipTarFss_Next(void *pvThis, char **ppszName, RTVFSOBJTYPE *penmType, PRTVFSOBJ phVfsObj)
    1297 {
    1298     PRTZIPTARFSSTREAM pThis = (PRTZIPTARFSSTREAM)pvThis;
     806static DECLCALLBACK(int) rtZipXarFss_Next(void *pvThis, char **ppszName, RTVFSOBJTYPE *penmType, PRTVFSOBJ phVfsObj)
     807{
     808    PRTZIPXARFSSTREAM pThis = (PRTZIPXARFSSTREAM)pvThis;
    1299809
    1300810    /*
     
    1322832        return pThis->rcFatal;
    1323833
     834#if 0
    1324835    /*
    1325836     * Make sure the input stream is in the right place.
     
    1345856
    1346857    /*
    1347      * Consume TAR headers.
     858     * Consume XAR headers.
    1348859     */
    1349860    size_t cbHdrs = 0;
     
    1354865         * Read the next header.
    1355866         */
    1356         RTZIPTARHDR Hdr;
     867        RTZIPXARHDR Hdr;
    1357868        size_t cbRead;
    1358869        rc = RTVfsIoStrmRead(pThis->hVfsIos, &Hdr, sizeof(Hdr), true /*fBlocking*/, &cbRead);
     
    1362873        {
    1363874            pThis->fEndOfStream = true;
    1364             return rtZipTarReaderIsAtEnd(&pThis->TarReader) ? VERR_EOF : VERR_TAR_UNEXPECTED_EOS;
     875            return rtZipXarReaderIsAtEnd(&pThis->XarReader) ? VERR_EOF : VERR_XAR_UNEXPECTED_EOS;
    1365876        }
    1366877        if (cbRead != sizeof(Hdr))
    1367             return pThis->rcFatal = VERR_TAR_UNEXPECTED_EOS;
     878            return pThis->rcFatal = VERR_XAR_UNEXPECTED_EOS;
    1368879
    1369880        cbHdrs += sizeof(Hdr);
     
    1372883         * Parse the it.
    1373884         */
    1374         rc = rtZipTarReaderParseHeader(&pThis->TarReader, &Hdr);
     885        rc = rtZipXarReaderParseHeader(&pThis->XarReader, &Hdr);
    1375886        if (RT_FAILURE(rc))
    1376887            return pThis->rcFatal = rc;
    1377     } while (rtZipTarReaderExpectingMoreHeaders(&pThis->TarReader));
     888    } while (rtZipXarReaderExpectingMoreHeaders(&pThis->XarReader));
    1378889
    1379890    pThis->offNextHdr = offHdr + cbHdrs;
    1380891
    1381892    /*
    1382      * Fill an object info structure from the current TAR state.
     893     * Fill an object info structure from the current XAR state.
    1383894     */
    1384895    RTFSOBJINFO Info;
    1385     rc = rtZipTarReaderGetFsObjInfo(&pThis->TarReader, &Info);
     896    rc = rtZipXarReaderGetFsObjInfo(&pThis->XarReader, &Info);
    1386897    if (RT_FAILURE(rc))
    1387898        return pThis->rcFatal = rc;
     
    1393904    RTVFSOBJ        hVfsObj;
    1394905    RTFMODE         fType = Info.Attr.fMode & RTFS_TYPE_MASK;
    1395     if (rtZipTarReaderIsHardlink(&pThis->TarReader))
     906    if (rtZipXarReaderIsHardlink(&pThis->XarReader))
    1396907        fType = RTFS_TYPE_SYMLINK;
    1397908    switch (fType)
     
    1403914        {
    1404915            RTVFSIOSTREAM       hVfsIos;
    1405             PRTZIPTARIOSTREAM   pIosData;
    1406             rc = RTVfsNewIoStream(&g_rtZipTarFssIosOps,
     916            PRTZIPXARIOSTREAM   pIosData;
     917            rc = RTVfsNewIoStream(&g_rtZipXarFssIosOps,
    1407918                                  sizeof(*pIosData),
    1408919                                  RTFILE_O_READ | RTFILE_O_DENY_NONE | RTFILE_O_OPEN,
     
    1415926
    1416927            pIosData->BaseObj.offHdr    = offHdr;
    1417             pIosData->BaseObj.pTarReader= &pThis->TarReader;
     928            pIosData->BaseObj.pXarReader= &pThis->XarReader;
    1418929            pIosData->BaseObj.ObjInfo   = Info;
    1419930            pIosData->cbFile            = Info.cbObject;
     
    1435946        /*
    1436947         * We represent hard links using a symbolic link object.  This fits
    1437          * best with the way TAR stores it and there is currently no better
     948         * best with the way XAR stores it and there is currently no better
    1438949         * fitting VFS type alternative.
    1439950         */
     
    1441952        {
    1442953            RTVFSSYMLINK        hVfsSym;
    1443             PRTZIPTARBASEOBJ    pBaseObjData;
    1444             rc = RTVfsNewSymlink(&g_rtZipTarFssSymOps,
     954            PRTZIPXARBASEOBJ    pBaseObjData;
     955            rc = RTVfsNewSymlink(&g_rtZipXarFssSymOps,
    1445956                                 sizeof(*pBaseObjData),
    1446957                                 NIL_RTVFS,
     
    1452963
    1453964            pBaseObjData->offHdr    = offHdr;
    1454             pBaseObjData->pTarReader= &pThis->TarReader;
     965            pBaseObjData->pXarReader= &pThis->XarReader;
    1455966            pBaseObjData->ObjInfo   = Info;
    1456967
     
    1463974        /*
    1464975         * All other objects are repesented using a VFS base object since they
    1465          * carry no data streams (unless some TAR extension implements extended
     976         * carry no data streams (unless some XAR extension implements extended
    1466977         * attributes / alternative streams).
    1467978         */
     
    1471982        case RTFS_TYPE_FIFO:
    1472983        {
    1473             PRTZIPTARBASEOBJ pBaseObjData;
    1474             rc = RTVfsNewBaseObj(&g_rtZipTarFssBaseObjOps,
     984            PRTZIPXARBASEOBJ pBaseObjData;
     985            rc = RTVfsNewBaseObj(&g_rtZipXarFssBaseObjOps,
    1475986                                 sizeof(*pBaseObjData),
    1476987                                 NIL_RTVFS,
     
    1482993
    1483994            pBaseObjData->offHdr    = offHdr;
    1484             pBaseObjData->pTarReader= &pThis->TarReader;
     995            pBaseObjData->pXarReader= &pThis->XarReader;
    1485996            pBaseObjData->ObjInfo   = Info;
    1486997
     
    15001011    if (ppszName)
    15011012    {
    1502         rc = RTStrDupEx(ppszName, pThis->TarReader.szName);
     1013        rc = RTStrDupEx(ppszName, pThis->XarReader.szName);
    15031014        if (RT_FAILURE(rc))
    15041015            return rc;
     
    15131024    if (penmType)
    15141025        *penmType = enmType;
     1026#endif
    15151027
    15161028    return VINF_SUCCESS;
     
    15201032
    15211033/**
    1522  * Tar filesystem stream operations.
    1523  */
    1524 static const RTVFSFSSTREAMOPS rtZipTarFssOps =
     1034 * Xar filesystem stream operations.
     1035 */
     1036static const RTVFSFSSTREAMOPS rtZipXarFssOps =
    15251037{
    15261038    { /* Obj */
    15271039        RTVFSOBJOPS_VERSION,
    15281040        RTVFSOBJTYPE_FS_STREAM,
    1529         "TarFsStream",
    1530         rtZipTarFss_Close,
    1531         rtZipTarFss_QueryInfo,
     1041        "XarFsStream",
     1042        rtZipXarFss_Close,
     1043        rtZipXarFss_QueryInfo,
    15321044        RTVFSOBJOPS_VERSION
    15331045    },
    15341046    RTVFSFSSTREAMOPS_VERSION,
    15351047    0,
    1536     rtZipTarFss_Next,
     1048    rtZipXarFss_Next,
    15371049    RTVFSFSSTREAMOPS_VERSION
    15381050};
    15391051
    15401052
    1541 RTDECL(int) RTZipTarFsStreamFromIoStream(RTVFSIOSTREAM hVfsIosIn, uint32_t fFlags, PRTVFSFSSTREAM phVfsFss)
     1053
     1054/**
     1055 * TOC validation part 2.
     1056 *
     1057 * Will advance the input stream past the TOC hash and signature data.
     1058 *
     1059 * @returns IPRT status code.
     1060 * @param   pThis       The FS stream instance being created.
     1061 * @param   pXarHdr     The XAR header.
     1062 * @param   pTocDigest  The TOC input data digest.
     1063 */
     1064static int rtZipXarValidateTocPart2(PRTZIPXARFSSTREAM pThis, PCXARHEADER pXarHdr, PCRTZIPXARHASHDIGEST pTocDigest)
     1065{
     1066    int rc;
     1067
     1068    /*
     1069     * Check that the hash function in the TOC matches the one in the XAR header.
     1070     */
     1071    const xml::ElementNode *pChecksumElem = pThis->XarReader.pToc->findChildElement("checksum");
     1072    if (pChecksumElem)
     1073    {
     1074        const xml::AttributeNode *pAttr = pChecksumElem->findAttribute("style");
     1075        if (!pAttr)
     1076            return VERR_XAR_BAD_CHECKSUM_ELEMENT;
     1077
     1078        const char *pszStyle = pAttr->getValue();
     1079        if (!pszStyle)
     1080            return VERR_XAR_BAD_CHECKSUM_ELEMENT;
     1081
     1082        uint8_t uHashFunction;
     1083        if (!strcmp(pszStyle, "sha1"))
     1084            uHashFunction = XAR_HASH_SHA1;
     1085        else if (!strcmp(pszStyle, "md5"))
     1086            uHashFunction = XAR_HASH_MD5;
     1087        else if (!strcmp(pszStyle, "none"))
     1088            uHashFunction = XAR_HASH_NONE;
     1089        else
     1090            return VERR_XAR_BAD_CHECKSUM_ELEMENT;
     1091        if (uHashFunction != pThis->uHashFunction)
     1092            return VERR_XAR_HASH_FUNCTION_MISMATCH;
     1093
     1094        /*
     1095         * Verify the checksum if we got one.
     1096         */
     1097        if (pThis->uHashFunction != XAR_HASH_NONE)
     1098        {
     1099            RTFOFF   offChecksum;
     1100            uint64_t cbChecksum;
     1101            rc = rtZipXarGetOffsetSizeFromElem(pChecksumElem, &offChecksum, &cbChecksum);
     1102            if (RT_FAILURE(rc))
     1103                return rc;
     1104            if (cbChecksum != pThis->cbHashDigest)
     1105                return VERR_XAR_BAD_DIGEST_LENGTH;
     1106            if (offChecksum != 0 && pThis->hVfsFile == NIL_RTVFSFILE)
     1107                return VERR_XAR_NOT_STREAMBLE_ELEMENT_ORDER;
     1108
     1109            RTZIPXARHASHDIGEST StoredDigest;
     1110            rc = RTVfsIoStrmReadAt(pThis->hVfsIos, pThis->offZero + offChecksum, &StoredDigest, cbChecksum,
     1111                                   true /*fBlocking*/, NULL /*pcbRead*/);
     1112            if (RT_FAILURE(rc))
     1113                return rc;
     1114            if (memcmp(&StoredDigest, pTocDigest, pThis->cbHashDigest))
     1115                return VERR_XAR_TOC_DIGEST_MISMATCH;
     1116        }
     1117    }
     1118    else if (pThis->uHashFunction != XAR_HASH_NONE)
     1119        return VERR_XAR_BAD_CHECKSUM_ELEMENT;
     1120
     1121    /*
     1122     * Check the signature, if we got one.
     1123     */
     1124    /** @todo signing. */
     1125
     1126    return VINF_SUCCESS;
     1127}
     1128
     1129
     1130/**
     1131 * Reads and validates the table of content.
     1132 *
     1133 * @returns IPRT status code.
     1134 * @param   hVfsIosIn   The input stream.
     1135 * @param   pXarHdr     The XAR header.
     1136 * @param   pDoc        The TOC XML document.
     1137 * @param   ppTocElem   Where to return the pointer to the TOC element on
     1138 *                      success.
     1139 * @param   pTocDigest  Where to return the TOC digest on success.
     1140 */
     1141static int rtZipXarReadAndValidateToc(RTVFSIOSTREAM hVfsIosIn, PCXARHEADER pXarHdr,
     1142                                      xml::Document *pDoc, xml::ElementNode const **ppTocElem, PRTZIPXARHASHDIGEST pTocDigest)
     1143{
     1144    /*
     1145     * Decompress it, calculating the hash while doing so.
     1146     */
     1147    char *pszOutput = (char *)RTMemTmpAlloc(pXarHdr->cbTocUncompressed + 1);
     1148    if (!pszOutput)
     1149        return VERR_NO_TMP_MEMORY;
     1150    int rc = VERR_NO_TMP_MEMORY;
     1151    void *pvInput = RTMemTmpAlloc(pXarHdr->cbTocCompressed);
     1152    if (pvInput)
     1153    {
     1154        rc = RTVfsIoStrmRead(hVfsIosIn, pvInput, pXarHdr->cbTocCompressed, true /*fBlocking*/,  NULL);
     1155        if (RT_SUCCESS(rc))
     1156        {
     1157            rtZipXarCalcHash(pXarHdr->uHashFunction, pvInput, pXarHdr->cbTocCompressed, pTocDigest);
     1158
     1159            size_t cbActual;
     1160            rc = RTZipBlockDecompress(RTZIPTYPE_ZLIB, 0 /*fFlags*/,
     1161                                      pvInput, pXarHdr->cbTocCompressed, NULL,
     1162                                      pszOutput, pXarHdr->cbTocUncompressed, &cbActual);
     1163            if (RT_SUCCESS(rc) && cbActual != pXarHdr->cbTocUncompressed)
     1164                rc = VERR_XAR_TOC_UNCOMP_SIZE_MISMATCH;
     1165        }
     1166        RTMemTmpFree(pvInput);
     1167    }
     1168    if (RT_SUCCESS(rc))
     1169    {
     1170        pszOutput[pXarHdr->cbTocUncompressed] = '\0';
     1171
     1172        /*
     1173         * Parse the TOC (XML document) and do some basic validations.
     1174         */
     1175        size_t cchToc = strlen(pszOutput);
     1176        if (   cchToc     == pXarHdr->cbTocUncompressed
     1177            || cchToc + 1 == pXarHdr->cbTocUncompressed)
     1178        {
     1179            rc = RTStrValidateEncoding(pszOutput);
     1180            if (RT_SUCCESS(rc))
     1181            {
     1182                xml::XmlMemParser Parser;
     1183                try
     1184                {
     1185                    Parser.read(pszOutput, cchToc, RTCString("xar-toc.xml"), *pDoc);
     1186                }
     1187                catch (xml::XmlError Err)
     1188                {
     1189                    rc = VERR_XAR_TOC_XML_PARSE_ERROR;
     1190                }
     1191                catch (...)
     1192                {
     1193                    rc = VERR_NO_MEMORY;
     1194                }
     1195                if (RT_SUCCESS(rc))
     1196                {
     1197                    xml::ElementNode const *pRootElem = pDoc->getRootElement();
     1198                    xml::ElementNode const *pTocElem  = NULL;
     1199                    if (pRootElem && pRootElem->nameEquals("xar"))
     1200                        pTocElem = pRootElem ? pRootElem->findChildElement(NULL, "toc") : NULL;
     1201                    if (pTocElem)
     1202                    {
     1203#ifndef USE_STD_LIST_FOR_CHILDREN
     1204                        Assert(pRootElem->getParent() == NULL);
     1205                        Assert(pTocElem->getParent() == pRootElem);
     1206                        if (   !pTocElem->getNextSibiling()
     1207                            && !pTocElem->getPrevSibiling())
     1208#endif
     1209                        {
     1210                            /*
     1211                             * Further parsing and validation is done after the
     1212                             * caller has created an file system stream instance.
     1213                             */
     1214                            *ppTocElem = pTocElem;
     1215
     1216                            RTMemTmpFree(pszOutput);
     1217                            return VINF_SUCCESS;
     1218                        }
     1219
     1220                        rc = VERR_XML_TOC_ELEMENT_HAS_SIBLINGS;
     1221                    }
     1222                    else
     1223                        rc = VERR_XML_TOC_ELEMENT_MISSING;
     1224                }
     1225            }
     1226            else
     1227                rc = VERR_XAR_TOC_UTF8_ENCODING;
     1228        }
     1229        else
     1230            rc = VERR_XAR_TOC_STRLEN_MISMATCH;
     1231    }
     1232
     1233    RTMemTmpFree(pszOutput);
     1234    return rc;
     1235}
     1236
     1237
     1238/**
     1239 * Reads and validates the XAR header.
     1240 *
     1241 * @returns IPRT status code.
     1242 * @param   hVfsIosIn   The input stream.
     1243 * @param   pXarHdr     Where to return the XAR header in host byte order.
     1244 */
     1245static int rtZipXarReadAndValidateHeader(RTVFSIOSTREAM hVfsIosIn, PXARHEADER pXarHdr)
     1246{
     1247    /*
     1248     * Read it and check the signature.
     1249     */
     1250    int rc = RTVfsIoStrmRead(hVfsIosIn, pXarHdr, sizeof(*pXarHdr), true /*fBlocking*/,  NULL);
     1251    if (RT_FAILURE(rc))
     1252        return rc;
     1253    if (pXarHdr->u32Magic != XAR_HEADER_MAGIC)
     1254        return VERR_XAR_WRONG_MAGIC;
     1255
     1256    /*
     1257     * Correct the byte order.
     1258     */
     1259    pXarHdr->cbHeader             = RT_BE2H_U16(pXarHdr->cbHeader);
     1260    pXarHdr->uVersion             = RT_BE2H_U16(pXarHdr->uVersion);
     1261    pXarHdr->cbTocCompressed      = RT_BE2H_U64(pXarHdr->cbTocCompressed);
     1262    pXarHdr->cbTocUncompressed    = RT_BE2H_U64(pXarHdr->cbTocUncompressed);
     1263    pXarHdr->uHashFunction        = RT_BE2H_U32(pXarHdr->uHashFunction);
     1264
     1265    /*
     1266     * Validate the header.
     1267     */
     1268    if (pXarHdr->uVersion > XAR_HEADER_VERSION)
     1269        return VERR_XAR_UNSUPPORTED_VERSION;
     1270    if (pXarHdr->cbHeader < sizeof(XARHEADER))
     1271        return VERR_XAR_BAD_HDR_SIZE;
     1272    if (pXarHdr->uHashFunction > XAR_HASH_MAX)
     1273        return VERR_XAR_UNSUPPORTED_HASH_FUNCTION;
     1274    if (pXarHdr->cbTocUncompressed < 16)
     1275        return VERR_XAR_TOC_TOO_SMALL;
     1276    if (pXarHdr->cbTocUncompressed > _4M)
     1277        return VERR_XAR_TOC_TOO_BIG;
     1278    if (pXarHdr->cbTocCompressed > _4M)
     1279        return VERR_XAR_TOC_TOO_BIG_COMPRESSED;
     1280
     1281    /*
     1282     * Skip over bytes we don't understand (could be padding).
     1283     */
     1284    if (pXarHdr->cbHeader > sizeof(XARHEADER))
     1285    {
     1286        rc = RTVfsIoStrmSkip(hVfsIosIn, pXarHdr->cbHeader - sizeof(XARHEADER));
     1287        if (RT_FAILURE(rc))
     1288            return rc;
     1289    }
     1290
     1291    return VINF_SUCCESS;
     1292}
     1293
     1294
     1295RTDECL(int) RTZipXarFsStreamFromIoStream(RTVFSIOSTREAM hVfsIosIn, uint32_t fFlags, PRTVFSFSSTREAM phVfsFss)
    15421296{
    15431297    /*
     
    15561310
    15571311    /*
    1558      * Retain the input stream and create a new filesystem stream handle.
    1559      */
    1560     PRTZIPTARFSSTREAM pThis;
    1561     RTVFSFSSTREAM     hVfsFss;
    1562     int rc = RTVfsNewFsStream(&rtZipTarFssOps, sizeof(*pThis), NIL_RTVFS, NIL_RTVFSLOCK, &hVfsFss, (void **)&pThis);
     1312     * Read and validate the header, then uncompress the TOC.
     1313     */
     1314    XARHEADER XarHdr;
     1315    int rc = rtZipXarReadAndValidateHeader(hVfsIosIn, &XarHdr);
    15631316    if (RT_SUCCESS(rc))
    15641317    {
    1565         pThis->hVfsIos              = hVfsIosIn;
    1566         pThis->hVfsCurObj           = NIL_RTVFSOBJ;
    1567         pThis->pCurIosData          = NULL;
    1568         pThis->offStart             = offStart;
    1569         pThis->offNextHdr           = offStart;
    1570         pThis->fEndOfStream         = false;
    1571         pThis->rcFatal              = VINF_SUCCESS;
    1572         pThis->TarReader.enmPrevType= RTZIPTARTYPE_INVALID;
    1573         pThis->TarReader.enmType    = RTZIPTARTYPE_INVALID;
    1574         pThis->TarReader.enmState   = RTZIPTARREADERSTATE_FIRST;
    1575 
    1576         /* Don't check if it's a TAR stream here, do that in the
    1577            rtZipTarFss_Next. */
    1578 
    1579         *phVfsFss = hVfsFss;
    1580         return VINF_SUCCESS;
     1318        xml::Document *pDoc = NULL;
     1319        try         { pDoc = new xml::Document(); }
     1320        catch (...) { }
     1321        if (pDoc)
     1322        {
     1323            RTZIPXARHASHDIGEST      TocDigest;
     1324            xml::ElementNode const *pTocElem = NULL;
     1325            rc = rtZipXarReadAndValidateToc(hVfsIosIn, &XarHdr, pDoc, &pTocElem, &TocDigest);
     1326            if (RT_SUCCESS(rc))
     1327            {
     1328                size_t offZero = RTVfsIoStrmTell(hVfsIosIn);
     1329                if (offZero > 0)
     1330                {
     1331                    /*
     1332                     * Create a file system stream before we continue the parsing.
     1333                     */
     1334                    PRTZIPXARFSSTREAM pThis;
     1335                    RTVFSFSSTREAM     hVfsFss;
     1336                    rc = RTVfsNewFsStream(&rtZipXarFssOps, sizeof(*pThis), NIL_RTVFS, NIL_RTVFSLOCK, &hVfsFss, (void **)&pThis);
     1337                    if (RT_SUCCESS(rc))
     1338                    {
     1339                        pThis->hVfsIos              = hVfsIosIn;
     1340                        pThis->hVfsFile             = RTVfsIoStrmToFile(hVfsIosIn);
     1341                        pThis->hVfsCurObj           = NIL_RTVFSOBJ;
     1342                        pThis->pCurIosData          = NULL;
     1343                        pThis->offStart             = offStart;
     1344                        pThis->offZero              = offZero;
     1345                        pThis->uHashFunction        = (uint8_t)XarHdr.uHashFunction;
     1346                        switch (pThis->uHashFunction)
     1347                        {
     1348                            case XAR_HASH_MD5:  pThis->cbHashDigest = sizeof(TocDigest.abMd5); break;
     1349                            case XAR_HASH_SHA1: pThis->cbHashDigest = sizeof(TocDigest.abSha1); break;
     1350                            default:            pThis->cbHashDigest = 0; break;
     1351                        }
     1352                        pThis->fEndOfStream         = false;
     1353                        pThis->rcFatal              = VINF_SUCCESS;
     1354                        pThis->XarReader.pDoc       = pDoc;
     1355                        pThis->XarReader.pToc       = pTocElem;
     1356                        pThis->XarReader.idCurFile  = 0; /* Assuming the ID numbering is from 1. */
     1357
     1358                        /*
     1359                         * Next validation step.
     1360                         */
     1361                        rc = rtZipXarValidateTocPart2(pThis, &XarHdr, &TocDigest);
     1362                        if (RT_SUCCESS(rc))
     1363                        {
     1364                            *phVfsFss = hVfsFss;
     1365                            return VINF_SUCCESS;
     1366                        }
     1367
     1368                        RTVfsFsStrmRelease(hVfsFss);
     1369                        return rc;
     1370                    }
     1371                }
     1372                else
     1373                    rc = (int)offZero;
     1374            }
     1375            delete pDoc;
     1376        }
     1377        else
     1378            rc = VERR_NO_MEMORY;
    15811379    }
    15821380
  • trunk/src/VBox/Runtime/common/zip/zip.cpp

    r47516 r48780  
    19171917
    19181918        case RTZIPTYPE_ZLIB:
     1919        {
     1920#ifdef RTZIP_USE_ZLIB
     1921            AssertReturn(cbSrc == (uInt)cbSrc, VERR_TOO_MUCH_DATA);
     1922            AssertReturn(cbDst == (uInt)cbDst, VERR_OUT_OF_RANGE);
     1923
     1924            z_stream ZStrm;
     1925            RT_ZERO(ZStrm);
     1926            ZStrm.next_in   = (Bytef *)pvSrc;
     1927            ZStrm.avail_in  = (uInt)cbSrc;
     1928            ZStrm.next_out  = (Bytef *)pvDst;
     1929            ZStrm.avail_out = (uInt)cbDst;
     1930
     1931            int rc = inflateInit(&ZStrm);
     1932            if (RT_UNLIKELY(rc != Z_OK))
     1933                return zipErrConvertFromZlib(rc, false /*fCompressing*/);
     1934            rc = inflate(&ZStrm, Z_FINISH);
     1935            if (rc != Z_STREAM_END)
     1936            {
     1937                inflateEnd(&ZStrm);
     1938                if ((rc == Z_BUF_ERROR && ZStrm.avail_in == 0) || rc == Z_NEED_DICT)
     1939                    return VERR_ZIP_CORRUPTED;
     1940                if (rc == Z_BUF_ERROR)
     1941                    return VERR_BUFFER_OVERFLOW;
     1942                AssertReturn(rc < Z_OK, VERR_GENERAL_FAILURE);
     1943                return zipErrConvertFromZlib(rc, false /*fCompressing*/);
     1944            }
     1945            rc = inflateEnd(&ZStrm);
     1946            if (rc != Z_OK)
     1947                return zipErrConvertFromZlib(rc, false /*fCompressing*/);
     1948
     1949            if (pcbSrcActual)
     1950                *pcbSrcActual = ZStrm.avail_in - cbSrc;
     1951            if (pcbDstActual)
     1952                *pcbDstActual = ZStrm.total_out;
     1953            break;
     1954#else
     1955            return VERR_NOT_SUPPORTED;
     1956#endif
     1957        }
     1958
    19191959        case RTZIPTYPE_BZLIB:
    19201960            return VERR_NOT_SUPPORTED;
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