VirtualBox

Changeset 23499 in vbox for trunk/src/VBox/Runtime/common


Ignore:
Timestamp:
Oct 2, 2009 7:58:09 AM (15 years ago)
Author:
vboxsync
Message:

iprt/manifest.cpp: code review: addressed some issue in error paths; must check RTStrmClose status when writing since it may flush buffered data and hit some error; corrected alloc/free type mix; don't use RTStrStr to search for single chars, use strchr for that. Adjusted the style.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/checksum/manifest.cpp

    r21749 r23499  
    3030
    3131
    32 #include "iprt/manifest.h"
    33 
     32/*******************************************************************************
     33*   Header Files                                                               *
     34*******************************************************************************/
     35#include "internal/iprt.h"
     36#include <iprt/manifest.h>
     37
     38#include <iprt/err.h>
     39#include <iprt/file.h>
     40#include <iprt/mem.h>
     41#include <iprt/path.h>
    3442#include <iprt/sha1.h>
    3543#include <iprt/stream.h>
    3644#include <iprt/string.h>
    37 #include <iprt/path.h>
    38 #include <iprt/file.h>
    39 #include <iprt/mem.h>
    40 #include <iprt/err.h>
    41 
    42 #include <stdlib.h>
     45
    4346
    4447/*******************************************************************************
    4548*   Structures and Typedefs                                                    *
    4649*******************************************************************************/
    47 typedef struct RTFILELISTINT
     50/**
     51 * Internal per file structure used by RTManifestVerify
     52 */
     53typedef struct RTMANIFESTFILEENTRY
    4854{
    4955    char *pszManifestFile;
    5056    char *pszManifestDigest;
    5157    PRTMANIFESTTEST pTestPattern;
    52 } RTFILELISTINT;
    53 typedef RTFILELISTINT* PRTFILELISTINT;
    54 
    55 /*******************************************************************************
    56 *   Public RTManifest interface                                                *
    57 *******************************************************************************/
     58} RTMANIFESTFILEENTRY;
     59typedef RTMANIFESTFILEENTRY* PRTMANIFESTFILEENTRY;
     60
     61
    5862
    5963RTR3DECL(int) RTManifestVerify(const char *pszManifestFile, PRTMANIFESTTEST paTests, size_t cTests, size_t *piFailed)
    6064{
    6165    /* Validate input */
    62     if (!pszManifestFile || !paTests)
    63     {
    64         AssertMsgFailed(("Must supply pszManifestFile and paTests!\n"));
    65         return VERR_INVALID_PARAMETER;
    66     }
     66    AssertPtrReturn(pszManifestFile, VERR_INVALID_POINTER);
     67    AssertPtrReturn(paTests, VERR_INVALID_POINTER);
     68    AssertReturn(cTests > 0, VERR_INVALID_PARAMETER);
    6769
    6870    /* Open the manifest file */
     
    7274        return rc;
    7375
    74     PRTFILELISTINT pFileList = (PRTFILELISTINT)RTMemAllocZ(sizeof(RTFILELISTINT)*cTests);
    75     if (!pFileList)
     76    PRTMANIFESTFILEENTRY paFiles = (PRTMANIFESTFILEENTRY)RTMemTmpAllocZ(sizeof(RTMANIFESTFILEENTRY) * cTests);
     77    if (!paFiles)
     78    {
     79        RTStrmClose(pStream);
    7680        return VERR_NO_MEMORY;
     81    }
     82
    7783    /* Fill our compare list */
    78     for (size_t i=0; i < cTests; ++i)
    79         pFileList[i].pTestPattern = &paTests[i];
     84    for (size_t i = 0; i < cTests; ++i)
     85        paFiles[i].pTestPattern = &paTests[i];
    8086
    8187    /* Parse the manifest file line by line */
    82     char pszLine[1024];
    83     do
    84     {
    85         rc = RTStrmGetLine(pStream, pszLine, 1024);
     88    char szLine[1024];
     89    for (;;)
     90    {
     91        rc = RTStrmGetLine(pStream, szLine, sizeof(szLine));
    8692        if (RT_FAILURE(rc))
    8793            break;
    88         size_t cbCount = strlen(pszLine);
     94        size_t cch = strlen(szLine);
     95
    8996        /* Skip empty lines */
    90         if (cbCount == 0)
     97        if (cch == 0)
    9198            continue;
     99
     100        /** @todo r=bird:
     101         *  -# The SHA1 test should probably include a blank space check.
     102         *  -# If there is a specific order to the elements in the string, it would be
     103         *     good if the delimiter searching checked for it.
     104         *  -# Deal with filenames containing delimiter characters.
     105         */
     106
    92107        /* Check for the digest algorithm */
    93         if (cbCount < 4 ||
    94             !(pszLine[0] == 'S' &&
    95               pszLine[1] == 'H' &&
    96               pszLine[2] == 'A' &&
    97               pszLine[3] == '1'))
     108        if (   cch < 4
     109            || !(  szLine[0] == 'S'
     110                && szLine[1] == 'H'
     111                && szLine[2] == 'A'
     112                && szLine[3] == '1'))
    98113        {
    99114            /* Digest unsupported */
     
    101116            break;
    102117        }
     118
    103119        /* Try to find the filename */
    104         char *pszNameStart = RTStrStr(pszLine, "(");
     120        char *pszNameStart = strchr(szLine, '(');
    105121        if (!pszNameStart)
    106122        {
     
    108124            break;
    109125        }
    110         char *pszNameEnd = RTStrStr(pszLine, ")");
     126        char *pszNameEnd = strchr(szLine, ')');
    111127        if (!pszNameEnd)
    112128        {
     
    114130            break;
    115131        }
     132
    116133        /* Copy the filename part */
    117         size_t len = pszNameEnd-pszNameStart - 1;
    118         char* pszName = (char*)RTMemAlloc(len+1);
     134        size_t cchName = pszNameEnd - pszNameStart - 1;
     135        char *pszName = (char *)RTMemTmpAlloc(cchName + 1);
    119136        if (!pszName)
    120137        {
     
    122139            break;
    123140        }
    124         memcpy(pszName, pszNameStart + 1, len);
    125         pszName[len] = '\0';
     141        memcpy(pszName, pszNameStart + 1, cchName);
     142        pszName[cchName] = '\0';
     143
    126144        /* Try to find the digest sum */
    127         char *pszDigestStart = RTStrStr(pszLine, "=") + 1;
     145        char *pszDigestStart = strchr(szLine, '=');
    128146        if (!pszDigestStart)
    129147        {
     148            RTMemTmpFree(pszName);
    130149            rc = VERR_MANIFEST_WRONG_FILE_FORMAT;
    131150            break;
    132151        }
    133         char *pszDigest = pszDigestStart;
     152        char *pszDigest = ++pszDigestStart;
     153
    134154        /* Check our file list against the extracted data */
    135155        bool fFound = false;
    136         for (size_t i=0; i < cTests; ++i)
    137         {
    138             if (!RTStrCmp(RTPathFilename(pFileList[i].pTestPattern->pszTestFile), RTStrStrip(pszName)))
     156        for (size_t i = 0; i < cTests; ++i)
     157        {
     158            if (!RTStrCmp(RTPathFilename(paFiles[i].pTestPattern->pszTestFile), RTStrStrip(pszName)))
    139159            {
    140160                /* Add the data of the manifest file to the file list */
     161                paFiles[i].pszManifestFile = RTStrDup(RTStrStrip(pszName));
     162                paFiles[i].pszManifestDigest = RTStrDup(RTStrStrip(pszDigest));
    141163                fFound = true;
    142                 pFileList[i].pszManifestFile = RTStrDup(RTStrStrip(pszName));
    143                 pFileList[i].pszManifestDigest = RTStrDup(RTStrStrip(pszDigest));
    144164                break;
    145165            }
    146166        }
    147         RTStrFree(pszName);
     167        RTMemTmpFree(pszName);
    148168        if (!fFound)
    149169        {
     
    153173        }
    154174    }
    155     while (1);
    156175    RTStrmClose(pStream);
    157176
    158     if (rc == VINF_SUCCESS ||
    159         rc == VERR_EOF)
     177    if (   rc == VINF_SUCCESS
     178        || rc == VERR_EOF)
    160179    {
    161180        rc = VINF_SUCCESS;
    162         for (size_t i=0; i < cTests; ++i)
     181        for (size_t i = 0; i < cTests; ++i)
    163182        {
    164183            /* If there is an entry in the file list, which hasn't an
    165184             * equivalent in the manifest file, its an error. */
    166             if (!pFileList[i].pszManifestFile ||
    167                 !pFileList[i].pszManifestDigest)
     185            if (   !paFiles[i].pszManifestFile
     186                || !paFiles[i].pszManifestDigest)
    168187            {
    169188                rc = VERR_MANIFEST_FILE_MISMATCH;
    170189                break;
    171190            }
     191
    172192            /* Do the manifest SHA1 digest match against the actual digest? */
    173             if (RTStrICmp(pFileList[i].pszManifestDigest, pFileList[i].pTestPattern->pszTestDigest))
     193            if (RTStrICmp(paFiles[i].pszManifestDigest, paFiles[i].pTestPattern->pszTestDigest))
    174194            {
    175195                if (piFailed)
     
    182202
    183203    /* Cleanup */
    184     for (size_t i=0; i < cTests; ++i)
    185     {
    186         if (pFileList[i].pszManifestFile)
    187             RTStrFree (pFileList[i].pszManifestFile);
    188         if (pFileList[i].pszManifestDigest)
    189             RTStrFree (pFileList[i].pszManifestDigest);
    190     }
    191     RTMemFree(pFileList);
     204    for (size_t i = 0; i < cTests; ++i)
     205    {
     206        if (paFiles[i].pszManifestFile)
     207            RTStrFree(paFiles[i].pszManifestFile);
     208        if (paFiles[i].pszManifestDigest)
     209            RTStrFree(paFiles[i].pszManifestDigest);
     210    }
     211    RTMemTmpFree(paFiles);
    192212
    193213    return rc;
    194214}
    195215
     216
    196217RTR3DECL(int) RTManifestVerifyFiles(const char *pszManifestFile, const char * const *papszFiles, size_t cFiles, size_t *piFailed)
    197218{
    198219    /* Validate input */
    199     if (!pszManifestFile || !papszFiles)
    200     {
    201         AssertMsgFailed(("Must supply pszManifestFile and papszFiles!\n"));
    202         return VERR_INVALID_PARAMETER;
    203     }
     220    AssertPtrReturn(pszManifestFile, VERR_INVALID_POINTER);
     221    AssertPtrReturn(papszFiles, VERR_INVALID_POINTER);
    204222
    205223    /* Create our compare list */
    206     PRTMANIFESTTEST pFileList = (PRTMANIFESTTEST)RTMemAllocZ(sizeof(RTMANIFESTTEST)*cFiles);
    207     if (!pFileList)
     224    PRTMANIFESTTEST paFiles = (PRTMANIFESTTEST)RTMemTmpAllocZ(sizeof(RTMANIFESTTEST) * cFiles);
     225    if (!paFiles)
    208226        return VERR_NO_MEMORY;
    209227
     228    /* Fill our compare list */
    210229    int rc = VINF_SUCCESS;
    211     /* Fill our compare list */
    212     for (size_t i=0; i < cFiles; ++i)
     230    for (size_t i = 0; i < cFiles; ++i)
    213231    {
    214232        char *pszDigest;
     
    216234        if (RT_FAILURE(rc))
    217235            break;
    218         pFileList[i].pszTestFile = (char*)papszFiles[i];
    219         pFileList[i].pszTestDigest = pszDigest;
    220     }
    221     /* Do the verify */
     236        paFiles[i].pszTestFile = (char*)papszFiles[i];
     237        paFiles[i].pszTestDigest = pszDigest;
     238    }
     239
     240    /* Do the verification */
    222241    if (RT_SUCCESS(rc))
    223         rc = RTManifestVerify(pszManifestFile, pFileList, cFiles, piFailed);
     242        rc = RTManifestVerify(pszManifestFile, paFiles, cFiles, piFailed);
    224243
    225244    /* Cleanup */
    226     for (size_t i=0; i < cFiles; ++i)
    227     {
    228         if (pFileList[i].pszTestDigest)
    229             RTStrFree(pFileList[i].pszTestDigest);
    230     }
    231     RTMemFree(pFileList);
     245    for (size_t i = 0; i < cFiles; ++i)
     246    {
     247        if (paFiles[i].pszTestDigest)
     248            RTStrFree(paFiles[i].pszTestDigest);
     249    }
     250    RTMemTmpFree(paFiles);
    232251
    233252    return rc;
    234253}
    235254
     255
    236256RTR3DECL(int) RTManifestWriteFiles(const char *pszManifestFile, const char * const *papszFiles, size_t cFiles)
    237257{
    238258    /* Validate input */
    239     if (!pszManifestFile || !papszFiles)
    240     {
    241         AssertMsgFailed(("Must supply pszManifestFile and papszFiles!\n"));
    242         return VERR_INVALID_PARAMETER;
    243     }
     259    AssertPtrReturn(pszManifestFile, VERR_INVALID_POINTER);
     260    AssertPtrReturn(papszFiles, VERR_INVALID_POINTER);
    244261
    245262    /* Open a file to stream in */
     
    249266        return rc;
    250267
    251     for (size_t i=0; i < cFiles; ++i)
     268    for (size_t i = 0; i < cFiles; ++i)
    252269    {
    253270        /* Calculate the SHA1 digest of every file */
     
    256273        if (RT_FAILURE(rc))
    257274            break;
     275
    258276        /* Add the entry to the manifest file */
    259         int cbRet = RTStrmPrintf(pStream, "SHA1 (%s)= %s\n", RTPathFilename(papszFiles[i]), pszDigest);
     277        int cch = RTStrmPrintf(pStream, "SHA1 (%s)= %s\n", RTPathFilename(papszFiles[i]), pszDigest);
    260278        RTStrFree(pszDigest);
    261         if (RT_UNLIKELY(cbRet < 0))
     279        if (RT_UNLIKELY(cch < 0))
    262280        {
    263281            rc = VERR_INTERNAL_ERROR;
     
    265283        }
    266284    }
    267     RTStrmClose(pStream);
     285    int rc2 = RTStrmClose(pStream);
     286    if (RT_FAILURE(rc2) && RT_SUCCESS(rc))
     287        rc2 = rc;
     288
    268289    /* Delete the manifest file on failure */
    269290    if (RT_FAILURE(rc))
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