VirtualBox

Changeset 86492 in vbox


Ignore:
Timestamp:
Oct 8, 2020 10:27:13 AM (4 years ago)
Author:
vboxsync
Message:

IPRT/xml: Fixed tiny leak in File::File(). bugref:9841

File:
1 edited

Legend:

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

    r85121 r86492  
    166166struct File::Data
    167167{
    168     Data()
    169         : handle(NIL_RTFILE), opened(false)
     168    Data(RTFILE a_hHandle, const char *a_pszFilename, bool a_fFlushOnClose)
     169        : strFileName(a_pszFilename)
     170        , handle(a_hHandle)
     171        , opened(a_hHandle != NIL_RTFILE)
     172        , flushOnClose(a_fFlushOnClose)
    170173    { }
     174
     175    ~Data()
     176    {
     177        if (flushOnClose)
     178        {
     179            RTFileFlush(handle);
     180            if (!strFileName.isEmpty())
     181                RTDirFlushParent(strFileName.c_str());
     182        }
     183
     184        if (opened)
     185        {
     186            RTFileClose(handle);
     187            handle = NIL_RTFILE;
     188            opened = false;
     189        }
     190    }
    171191
    172192    RTCString strFileName;
     
    177197
    178198File::File(Mode aMode, const char *aFileName, bool aFlushIt /* = false */)
    179     : m(new Data())
    180 {
    181     m->strFileName = aFileName;
    182     m->flushOnClose = aFlushIt;
    183 
     199    : m(NULL)
     200{
     201    /* Try open the file first, as the destructor will not be invoked if we throw anything from here. For details see:
     202       https://stackoverflow.com/questions/9971782/destructor-not-invoked-when-an-exception-is-thrown-in-the-constructor */
    184203    uint32_t flags = 0;
    185204    const char *pcszMode = "???";
     
    204223            break;
    205224    }
    206 
    207     int vrc = RTFileOpen(&m->handle, aFileName, flags);
     225    RTFILE hFile = NIL_RTFILE;
     226    int vrc = RTFileOpen(&hFile, aFileName, flags);
    208227    if (RT_FAILURE(vrc))
    209228        throw EIPRTFailure(vrc, "Runtime error opening '%s' for %s", aFileName, pcszMode);
    210229
    211     m->opened = true;
    212     m->flushOnClose = aFlushIt && (flags & RTFILE_O_ACCESS_MASK) != RTFILE_O_READ;
     230    /* Now we can create the data and stuff: */
     231    try
     232    {
     233        m = new Data(hFile, aFileName, aFlushIt && (flags & RTFILE_O_ACCESS_MASK) != RTFILE_O_READ);
     234    }
     235    catch (std::bad_alloc &)
     236    {
     237        RTFileClose(hFile);
     238        throw;
     239    }
    213240}
    214241
    215242File::File(RTFILE aHandle, const char *aFileName /* = NULL */, bool aFlushIt /* = false */)
    216     : m(new Data())
     243    : m(NULL)
    217244{
    218245    if (aHandle == NIL_RTFILE)
    219246        throw EInvalidArg(RT_SRC_POS);
    220247
    221     m->handle = aHandle;
    222 
    223     if (aFileName)
    224         m->strFileName = aFileName;
    225 
    226     m->flushOnClose = aFlushIt;
     248    m = new Data(aHandle, aFileName, aFlushIt);
    227249
    228250    setPos(0);
     
    231253File::~File()
    232254{
    233     if (m->flushOnClose)
    234     {
    235         RTFileFlush(m->handle);
    236         if (!m->strFileName.isEmpty())
    237             RTDirFlushParent(m->strFileName.c_str());
    238     }
    239 
    240     if (m->opened)
    241         RTFileClose(m->handle);
    242     delete m;
     255    if (m)
     256    {
     257        delete m;
     258        m = NULL;
     259    }
    243260}
    244261
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