Commit 14eb261d authored by John Chen's avatar John Chen Committed by Commit Bot

[ChromeDriver] Fix stack overflow due to huge data

Fix a stack overflow that can be caused by receiving a large amount of
data from Chrome. Also increase the maximum buffer size for
communication between app and ChromeDriver.

Bug: chromium:877105, chromedriver:2587, b/112588554
Change-Id: Ie98544237472da629c01b9422b2e01a4716e8b88
Reviewed-on: https://chromium-review.googlesource.com/1233177
Commit-Queue: John Chen <johnchen@chromium.org>
Reviewed-by: default avatarCaleb Rouleau <crouleau@chromium.org>
Cr-Commit-Position: refs/heads/master@{#595477}
parent 1574deae
...@@ -205,15 +205,20 @@ void WebSocket::ContinueWritingIfNecessary() { ...@@ -205,15 +205,20 @@ void WebSocket::ContinueWritingIfNecessary() {
} }
void WebSocket::Read() { void WebSocket::Read() {
int code = while (true) {
socket_->Read(read_buffer_.get(), int code = socket_->Read(
read_buffer_->size(), read_buffer_.get(), read_buffer_->size(),
base::Bind(&WebSocket::OnRead, base::Unretained(this))); base::Bind(&WebSocket::OnRead, base::Unretained(this), true));
if (code != net::ERR_IO_PENDING) if (code == net::ERR_IO_PENDING)
OnRead(code); break;
OnRead(false, code);
if (state_ == CLOSED)
break;
}
} }
void WebSocket::OnRead(int code) { void WebSocket::OnRead(bool read_again, int code) {
if (code <= 0) { if (code <= 0) {
VLOG(4) << "WebSocket::OnRead error " << net::ErrorToShortString(code); VLOG(4) << "WebSocket::OnRead error " << net::ErrorToShortString(code);
Close(code ? code : net::ERR_FAILED); Close(code ? code : net::ERR_FAILED);
...@@ -225,7 +230,13 @@ void WebSocket::OnRead(int code) { ...@@ -225,7 +230,13 @@ void WebSocket::OnRead(int code) {
else if (state_ == OPEN) else if (state_ == OPEN)
OnReadDuringOpen(read_buffer_->data(), code); OnReadDuringOpen(read_buffer_->data(), code);
if (state_ != CLOSED) // If we were called by the event loop due to arrival of data, call Read()
// again to read more data. If we were called by Read(), however, simply
// return to Read() and let it call socket_->Read() to read more data, and
// potentially call OnRead() again. This is necessary to avoid mutual
// recursion between Read and OnRead, which can cause stack overflow (e.g.,
// see https://crbug.com/877105).
if (read_again && state_ != CLOSED)
Read(); Read();
} }
......
...@@ -53,7 +53,7 @@ class WebSocket { ...@@ -53,7 +53,7 @@ class WebSocket {
void ContinueWritingIfNecessary(); void ContinueWritingIfNecessary();
void Read(); void Read();
void OnRead(int code); void OnRead(bool read_again, int code);
void OnReadDuringHandshake(const char* data, int len); void OnReadDuringHandshake(const char* data, int len);
void OnReadDuringOpen(const char* data, int len); void OnReadDuringOpen(const char* data, int len);
......
...@@ -50,7 +50,10 @@ ...@@ -50,7 +50,10 @@
namespace { namespace {
const int kBufferSize = 100 * 1024 * 1024; // 100 MB // Maximum message size between app and ChromeDriver. Data larger than 150 MB
// or so can cause crashes in Chrome (https://crbug.com/890854), so there is no
// need to support messages that are too large.
const int kBufferSize = 256 * 1024 * 1024; // 256 MB
typedef base::Callback< typedef base::Callback<
void(const net::HttpServerRequestInfo&, const HttpResponseSenderFunc&)> void(const net::HttpServerRequestInfo&, const HttpResponseSenderFunc&)>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment