1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-09 23:34:20 +00:00

Linux: WebBrowserComponent: Fix crash when accessing resources larger than 4k

This commit reverts 8e6aeab799.

The WebBrowserComponent subprocess calls tryNextRead() in an infinite
loop. Prior to the reverted change this allowed it to handle the
transfer of larger files, which would span multiple calls to the
function. The transfer state would be remembered in the receivingLength
and pos class members.

The simplification in 8e6aeab799 mainly
comes from moving these class members into function locals, but this
means, that the transfer state is lost whenever the break statements are
hit. This would cause bad access during the transfer of larger files.
This commit is contained in:
attila 2025-10-07 17:07:06 +02:00 committed by Attila Szarvas
parent 3592a73682
commit bc8e9e05af

View file

@ -464,24 +464,39 @@ public:
{
for (;;)
{
char lengthBytes[sizeof (size_t)]{};
const auto numLengthBytes = readIntoBuffer (lengthBytes);
auto len = (receivingLength ? sizeof (size_t) : bufferLength.len);
if (numLengthBytes != std::size (lengthBytes))
if (! receivingLength)
buffer.realloc (len);
auto* dst = (receivingLength ? bufferLength.data : buffer.getData());
auto actual = read (inChannel, &dst[pos], static_cast<size_t> (len - pos));
if (actual < 0)
{
if (errno == EINTR)
continue;
// This isn't an abort condition. The transfer of the same file can continue after
// the next call to tryNextRead.
break;
}
const auto numBytesExpected = readUnaligned<size_t> (lengthBytes);
buffer.reserve (numBytesExpected + 1);
buffer.resize (numBytesExpected);
pos += static_cast<size_t> (actual);
if (readIntoBuffer (buffer) != numBytesExpected)
break;
if (pos == len)
{
pos = 0;
buffer.push_back (0);
parseJSON (StringRef (buffer.data()));
if (! std::exchange (receivingLength, ! receivingLength))
{
parseJSON (String (buffer.getData(), bufferLength.len));
if (ret == ReturnAfterMessageReceived::yes)
return;
if (ret == ReturnAfterMessageReceived::yes)
return;
}
}
}
if (errno != EAGAIN && errno != EWOULDBLOCK && responder != nullptr)
@ -536,37 +551,15 @@ private:
}
}
/* Try to fill the target buffer by reading from the input channel.
Returns the number of bytes that were successfully read.
*/
size_t readIntoBuffer (Span<char> target) const
{
size_t pos = 0;
while (pos != target.size())
{
const auto bytesThisTime = read (inChannel, target.data() + pos, target.size() - pos);
if (bytesThisTime <= 0)
{
if (bytesThisTime != 0 && errno == EINTR)
continue;
break;
}
pos += static_cast<size_t> (bytesThisTime);
}
return pos;
}
static Identifier getCmdIdentifier() { static Identifier Id ("cmd"); return Id; }
static Identifier getParamIdentifier() { static Identifier Id ("params"); return Id; }
std::vector<char> buffer;
Responder* responder = nullptr;
int inChannel = 0;
size_t pos = 0;
bool receivingLength = true;
union { char data [sizeof (size_t)]; size_t len; } bufferLength;
HeapBlock<char> buffer;
};
#define juce_g_signal_connect(instance, detailed_signal, c_handler, data) \