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 reverts8e6aeab799. 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 in8e6aeab799mainly 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:
parent
3592a73682
commit
bc8e9e05af
1 changed files with 31 additions and 38 deletions
|
|
@ -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) \
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue