VirtualBox

Changeset 96710 in vbox


Ignore:
Timestamp:
Sep 12, 2022 7:47:16 PM (2 years ago)
Author:
vboxsync
Message:

IPRT/stream: Check that rtStrmGetFile doesn't return NIL_RTFILE before passing it along to RTFileRead or RTFileWrite, as these will assert when NIL and all the standard streams can have NIL handles (especially in GUI apps). bugref:10261

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/stream.cpp

    r96511 r96710  
    12181218    Assert(cbToFlush <= pStream->offBufEnd - pStream->offBufFirst);
    12191219
    1220     /** @todo do nonblocking & incomplete writes?   */
    1221     size_t offBufFirst = pStream->offBufFirst;
    1222     int rc = RTFileWrite(rtStrmGetFile(pStream), &pStream->pchBuf[offBufFirst], cbToFlush, NULL);
    1223     if (RT_SUCCESS(rc))
    1224     {
    1225         offBufFirst += cbToFlush;
    1226         if (offBufFirst >= pStream->offBufEnd)
    1227             pStream->offBufEnd = 0;
    1228         else
    1229         {
    1230             /* Shift up the remaining content so the next write can take full
    1231                advantage of the buffer size. */
    1232             size_t cbLeft = pStream->offBufEnd - offBufFirst;
    1233             memmove(pStream->pchBuf, &pStream->pchBuf[offBufFirst], cbLeft);
    1234             pStream->offBufEnd = cbLeft;
    1235         }
    1236         pStream->offBufFirst = 0;
    1237         return VINF_SUCCESS;
    1238     }
    1239     return rc;
     1220    RTFILE const hFile = rtStrmGetFile(pStream);
     1221    if (hFile != NIL_RTFILE)
     1222    {
     1223        /** @todo do nonblocking & incomplete writes?   */
     1224        size_t offBufFirst = pStream->offBufFirst;
     1225        int rc = RTFileWrite(hFile, &pStream->pchBuf[offBufFirst], cbToFlush, NULL);
     1226        if (RT_SUCCESS(rc))
     1227        {
     1228            offBufFirst += cbToFlush;
     1229            if (offBufFirst >= pStream->offBufEnd)
     1230                pStream->offBufEnd = 0;
     1231            else
     1232            {
     1233                /* Shift up the remaining content so the next write can take full
     1234                   advantage of the buffer size. */
     1235                size_t cbLeft = pStream->offBufEnd - offBufFirst;
     1236                memmove(pStream->pchBuf, &pStream->pchBuf[offBufFirst], cbLeft);
     1237                pStream->offBufEnd = cbLeft;
     1238            }
     1239            pStream->offBufFirst = 0;
     1240            return VINF_SUCCESS;
     1241        }
     1242        return rc;
     1243    }
     1244    return VERR_INVALID_HANDLE;
    12401245}
    12411246
     
    14531458     * Read data till the buffer is full.
    14541459     */
    1455     size_t cbRead = 0;
    1456     int rc = RTFileRead(rtStrmGetFile(pStream), &pStream->pchBuf[cbInBuffer], pStream->cbBufAlloc - cbInBuffer, &cbRead);
    1457     if (RT_SUCCESS(rc))
    1458     {
    1459         cbInBuffer        += cbRead;
    1460         pStream->offBufEnd = cbInBuffer;
    1461 
    1462         if (cbInBuffer != 0)
    1463         {
     1460    int          rc     = VERR_INVALID_HANDLE;
     1461    RTFILE const hFile  = rtStrmGetFile(pStream);
     1462    if (hFile != NIL_RTFILE)
     1463    {
     1464        size_t   cbRead = 0;
     1465        rc = RTFileRead(hFile, &pStream->pchBuf[cbInBuffer], pStream->cbBufAlloc - cbInBuffer, &cbRead);
     1466        if (RT_SUCCESS(rc))
     1467        {
     1468            cbInBuffer        += cbRead;
     1469            pStream->offBufEnd = cbInBuffer;
     1470
     1471            if (cbInBuffer != 0)
     1472            {
    14641473# ifdef RTSTREAM_WITH_TEXT_MODE
    14651474            if (pStream->fBinary)
    14661475# endif
    14671476                return VINF_SUCCESS;
    1468         }
    1469         else
    1470         {
    1471             /** @todo this shouldn't be sticky, should it? */
    1472             ASMAtomicWriteS32(&pStream->i32Error, VERR_EOF);
    1473             return VERR_EOF;
    1474         }
     1477            }
     1478            else
     1479            {
     1480                /** @todo this shouldn't be sticky, should it? */
     1481                ASMAtomicWriteS32(&pStream->i32Error, VERR_EOF);
     1482                return VERR_EOF;
     1483            }
    14751484
    14761485# ifdef RTSTREAM_WITH_TEXT_MODE
    1477         /*
    1478          * Do CRLF -> LF conversion in the buffer.
    1479          */
    1480         ASMBitClearRange(pStream->pbmBuf, offCrLfConvStart, RT_ALIGN_Z(cbInBuffer, 64));
    1481         char  *pchCur = &pStream->pchBuf[offCrLfConvStart];
    1482         size_t cbLeft = cbInBuffer - offCrLfConvStart;
    1483         while (cbLeft > 0)
    1484         {
    1485             Assert(&pchCur[cbLeft] == &pStream->pchBuf[pStream->offBufEnd]);
    1486             char *pchCr = (char *)memchr(pchCur, '\r', cbLeft);
    1487             if (pchCr)
     1486            /*
     1487             * Do CRLF -> LF conversion in the buffer.
     1488             */
     1489            ASMBitClearRange(pStream->pbmBuf, offCrLfConvStart, RT_ALIGN_Z(cbInBuffer, 64));
     1490            char  *pchCur = &pStream->pchBuf[offCrLfConvStart];
     1491            size_t cbLeft = cbInBuffer - offCrLfConvStart;
     1492            while (cbLeft > 0)
    14881493            {
    1489                 size_t offCur = (size_t)(pchCr - pchCur);
    1490                 if (offCur + 1 < cbLeft)
     1494                Assert(&pchCur[cbLeft] == &pStream->pchBuf[pStream->offBufEnd]);
     1495                char *pchCr = (char *)memchr(pchCur, '\r', cbLeft);
     1496                if (pchCr)
    14911497                {
    1492                     if (pchCr[1] == '\n')
     1498                    size_t offCur = (size_t)(pchCr - pchCur);
     1499                    if (offCur + 1 < cbLeft)
    14931500                    {
    1494                         /* Found one '\r\n' sequence. Look for more before shifting the buffer content. */
    1495                         cbLeft -= offCur;
    1496                         pchCur  = pchCr;
    1497 
    1498                         do
     1501                        if (pchCr[1] == '\n')
    14991502                        {
    1500                             ASMBitSet(pStream->pbmBuf, (int32_t)(pchCur - pStream->pchBuf));
    1501                             *pchCur++  = '\n'; /* dst */
    1502                             cbLeft    -= 2;
    1503                             pchCr     += 2;    /* src */
    1504                         } while  (cbLeft >= 2 && pchCr[0] == '\r' && pchCr[1] == '\n');
    1505 
    1506                         memmove(&pchCur, pchCr, cbLeft);
     1503                            /* Found one '\r\n' sequence. Look for more before shifting the buffer content. */
     1504                            cbLeft -= offCur;
     1505                            pchCur  = pchCr;
     1506
     1507                            do
     1508                            {
     1509                                ASMBitSet(pStream->pbmBuf, (int32_t)(pchCur - pStream->pchBuf));
     1510                                *pchCur++  = '\n'; /* dst */
     1511                                cbLeft    -= 2;
     1512                                pchCr     += 2;    /* src */
     1513                            } while  (cbLeft >= 2 && pchCr[0] == '\r' && pchCr[1] == '\n');
     1514
     1515                            memmove(&pchCur, pchCr, cbLeft);
     1516                        }
     1517                        else
     1518                        {
     1519                            cbLeft -= offCur + 1;
     1520                            pchCur  = pchCr  + 1;
     1521                        }
    15071522                    }
    15081523                    else
    15091524                    {
    1510                         cbLeft -= offCur + 1;
    1511                         pchCur  = pchCr  + 1;
     1525                        Assert(pchCr == &pStream->pchBuf[pStream->offBufEnd - 1]);
     1526                        pStream->fPendingCr = true;
     1527                        pStream->offBufEnd  = --cbInBuffer;
     1528                        break;
    15121529                    }
    15131530                }
    15141531                else
    1515                 {
    1516                     Assert(pchCr == &pStream->pchBuf[pStream->offBufEnd - 1]);
    1517                     pStream->fPendingCr = true;
    1518                     pStream->offBufEnd  = --cbInBuffer;
    15191532                    break;
    1520                 }
    15211533            }
    1522             else
    1523                 break;
    1524         }
    1525 
    1526         return VINF_SUCCESS;
    1527 # endif
     1534
     1535            return VINF_SUCCESS;
     1536# endif
     1537        }
    15281538    }
    15291539
     
    17621772    if (RT_SUCCESS(rc))
    17631773    {
    1764         rc = RTFileSeek(rtStrmGetFile(pStream), 0, RTFILE_SEEK_CURRENT, &off);
    1765         if (RT_SUCCESS(rc))
    1766         {
    1767             switch (pStream->enmBufDir)
     1774        RTFILE const hFile = rtStrmGetFile(pStream);
     1775        if (hFile != NIL_RTFILE)
     1776        {
     1777            rc = RTFileSeek(hFile, 0, RTFILE_SEEK_CURRENT, &off);
     1778            if (RT_SUCCESS(rc))
    17681779            {
    1769                 case RTSTREAMBUFDIR_READ:
    1770                     /* Subtract unconsumed chars and removed '\r' characters. */
    1771                     off -= pStream->offBufEnd - pStream->offBufFirst;
    1772                     if (!pStream->fBinary)
    1773                         for (size_t offBuf = pStream->offBufFirst; offBuf < pStream->offBufEnd; offBuf++)
    1774                             off -= ASMBitTest(pStream->pbmBuf, (int32_t)offBuf);
    1775                     break;
    1776                 case RTSTREAMBUFDIR_WRITE:
    1777                     /* Add unwrittend chars in the buffer. */
    1778                     off += pStream->offBufEnd - pStream->offBufFirst;
    1779                     break;
    1780                 default:
    1781                     AssertFailed();
    1782                 case RTSTREAMBUFDIR_NONE:
    1783                     break;
     1780                switch (pStream->enmBufDir)
     1781                {
     1782                    case RTSTREAMBUFDIR_READ:
     1783                        /* Subtract unconsumed chars and removed '\r' characters. */
     1784                        off -= pStream->offBufEnd - pStream->offBufFirst;
     1785                        if (!pStream->fBinary)
     1786                            for (size_t offBuf = pStream->offBufFirst; offBuf < pStream->offBufEnd; offBuf++)
     1787                                off -= ASMBitTest(pStream->pbmBuf, (int32_t)offBuf);
     1788                        break;
     1789                    case RTSTREAMBUFDIR_WRITE:
     1790                        /* Add unwrittend chars in the buffer. */
     1791                        off += pStream->offBufEnd - pStream->offBufFirst;
     1792                        break;
     1793                    default:
     1794                        AssertFailed();
     1795                    case RTSTREAMBUFDIR_NONE:
     1796                        break;
     1797                }
    17841798            }
    17851799        }
     1800        else
     1801            rc = VERR_INVALID_HANDLE;
    17861802    }
    17871803    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