VirtualBox

Ignore:
Timestamp:
Oct 15, 2008 3:26:08 PM (16 years ago)
Author:
vboxsync
Message:

Additions/common: fixed a todo in the guest property enumeration code

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestProp.cpp

    r13282 r13290  
    4848    /** The buffer containing the raw enumeration data */
    4949    char *pchBuf;
    50     /** The size of the buffer */
    51     uint32_t cchBuf;
    52     /** Index into the buffer pointing to the next entry to enumerate */
    53     uint32_t iBuf;
     50    /** The end of the buffer */
     51    char *pchBufEnd;
     52    /** Pointer to the next entry to enumerate inside the buffer */
     53    char *pchNext;
    5454};
    5555
     
    581581    {
    582582        /* Transfer ownership of the buffer to the handle structure. */
    583         Handle->pchBuf = Buf.release();
    584         Handle->cchBuf = cchBuf;
     583        Handle->pchNext = Handle->pchBuf = Buf.release();
     584        Handle->pchBufEnd = Handle->pchBuf + cchBuf;
    585585    }
    586586    if (RT_SUCCESS(rc))
     
    622622                                        char const **ppszFlags)
    623623{
    624     uint32_t iBuf = pHandle->iBuf;
    625     char *pszName = pHandle->pchBuf + iBuf;
    626     /** @todo replace these with safe memchr's and return an error if needed. A
    627      *        PLEASE add a comment about the layout because this is rather
    628      *        unreadable. */
    629     iBuf += strlen(pszName) + 1;
    630     char *pszValue = pHandle->pchBuf + iBuf;
    631     iBuf += strlen(pszValue) + 1;
    632     char *pszTimestamp = pHandle->pchBuf + iBuf;
    633     iBuf += strlen(pszTimestamp) + 1;
     624    /* The VBGLR3GUESTPROPENUM structure contains a buffer containing the raw
     625     * properties data and a pointer into the buffer which tracks how far we
     626     * have parsed so far.  The buffer contains packed strings in groups of
     627     * four - name, value, timestamp (as a decimal string) and flags.  It is
     628     * terminated by four empty strings.  We can rely on this layout unless
     629     * the caller has been poking about in the structure internals, in which
     630     * case they must take responsibility for the results. */
     631
     632    /* Get the pointer into the buffer to the next entry. */
     633    char *pchNext = pHandle->pchNext;
     634    /* And the pointer to the end of the buffer. */
     635    char *pchLast = pHandle->pchBufEnd;
     636    /* The index will initially point to the next name entry. */
     637    char *pszName = pchNext;
     638    /* The value for this property starts after the terminator for the name. */
     639    char *pszValue = pchNext = (char *)memchr(pchNext, '\0', pchLast - pchNext) + 1;
     640    AssertPtr(pchNext);  /* 0x1 is also an invalid pointer :) */
     641    /* The timestamp after the value... */
     642    char *pszTimestamp = pchNext = (char *)memchr(pchNext, '\0', pchLast - pchNext) + 1;
     643    AssertPtr(pchNext);
     644    /* ...and the flags after the timestamp. */
     645    char *pszFlags = pchNext = (char *)memchr(pchNext, '\0', pchLast - pchNext) + 1;
     646    AssertPtr(pchNext);
    634647    uint64_t u64Timestamp = RTStrToUInt64(pszTimestamp);
    635     char *pszFlags = pHandle->pchBuf + iBuf;
    636     iBuf += strlen(pszFlags) + 1;
    637     /* Otherwise we just stay at the end of the list. */
    638     if ((iBuf != pHandle->iBuf + 4) && (iBuf < pHandle->cchBuf) /* sanity */)
    639         pHandle->iBuf = iBuf;
    640     *ppszName = *pszName != 0 ? pszName : NULL;
    641     *ppszValue = pszValue != 0 ? pszValue : NULL;
     648    /* Only move the index pointer in the structure if we found a non-empty entry. */
     649    if (*pszName != '\0')
     650    {
     651        pHandle->pchNext = pchNext = (char *)memchr(pchNext, '\0', pchLast - pchNext) + 1;
     652        AssertPtr(pchNext);
     653    }
     654    /* And make sure that the buffer terminator is correct. */
     655    Assert(   (*pszName != '\0')
     656           || (('\0' == *pszValue) && ('\0' == *pszTimestamp) && ('\0' == *pszFlags))
     657          );
     658    *ppszName = *pszName != '\0' ? pszName : NULL;
     659    *ppszValue = pszValue != '\0' ? pszValue : NULL;
    642660    *pu64Timestamp = u64Timestamp;
    643     *ppszFlags = pszFlags != 0 ? pszFlags : NULL;
     661    *ppszFlags = pszFlags != '\0' ? pszFlags : NULL;
    644662    return VINF_SUCCESS;
    645663}
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