physfs-cpp icon indicating copy to clipboard operation
physfs-cpp copied to clipboard

The put pointers are not being reset correctly on calls to overflow() and sync()

Open rh101 opened this issue 4 years ago • 0 comments

If data is larger than the buffer size, then what happens is that the first set of buffered data (2048 bytes) is written over and over again until the entire length of input data has been processed.

For instance, 500KB input data would result in an output file that is around a gigabytes in size.

These changes to class fbuf should fix the issue:

    int_type overflow(int_type c = traits_type::eof()) override
    {
        // Write buffer
        if (flush() < 0)
        {
            return traits_type::eof();
        }

        setp(buffer, buffer + bufferSize); // reset the put pointers

        if (c != traits_type::eof()) 
        {
            *pptr() = (char)c; // Add the overflow character to the put buffer
            pbump(1); // increment the put pointer by one
        }

        return c;
    }

    int sync() override
    {
        const auto result = flush();
        setp(buffer, buffer + bufferSize); // reset the put pointers

        return result;
    }

    int flush() const
    {
        const auto len = pptr() - pbase();
        if (len == 0)
        {
            return 0;  // nothing to do
        }

        if (PHYSFS_writeBytes(file, pbase(), len) < len)
        {
            return -1;
        }

        return 0;
    }

...
    ~fbuf() override
    {
        flush();
        delete[] buffer;
    }

rh101 avatar Apr 23 '21 14:04 rh101