Commit 70a1658a authored by Adam Rice's avatar Adam Rice Committed by Commit Bot

Make IsClosed() and IsErrored() take an ExceptionState& argument

Modify IsClosed() and IsErrored() in blink::ReadableStreamOperations to
take an ExceptionState& parameters. Modify the wrappers in
BodyStreamBuffer to also take ExceptionState&, and make the callers
handle exceptions from them correctly.

Bug: 853189
Change-Id: I64a806571bd2c080de3ee2b5966cad6142ba0e15
Reviewed-on: https://chromium-review.googlesource.com/1116634
Commit-Queue: Adam Rice <ricea@chromium.org>
Reviewed-by: default avatarTsuyoshi Horo <horo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#571038}
parent 239033b6
...@@ -177,7 +177,11 @@ scoped_refptr<BlobDataHandle> BodyStreamBuffer::DrainAsBlobDataHandle( ...@@ -177,7 +177,11 @@ scoped_refptr<BlobDataHandle> BodyStreamBuffer::DrainAsBlobDataHandle(
ExceptionState& exception_state) { ExceptionState& exception_state) {
DCHECK(!IsStreamLockedForDCheck()); DCHECK(!IsStreamLockedForDCheck());
DCHECK(!IsStreamDisturbedForDCheck()); DCHECK(!IsStreamDisturbedForDCheck());
if (IsStreamClosed() || IsStreamErrored()) const base::Optional<bool> is_closed = IsStreamClosed(exception_state);
if (exception_state.HadException() || is_closed.value())
return nullptr;
const base::Optional<bool> is_errored = IsStreamErrored(exception_state);
if (exception_state.HadException() || is_errored.value())
return nullptr; return nullptr;
if (made_from_readable_stream_) if (made_from_readable_stream_)
...@@ -198,7 +202,11 @@ scoped_refptr<EncodedFormData> BodyStreamBuffer::DrainAsFormData( ...@@ -198,7 +202,11 @@ scoped_refptr<EncodedFormData> BodyStreamBuffer::DrainAsFormData(
ExceptionState& exception_state) { ExceptionState& exception_state) {
DCHECK(!IsStreamLockedForDCheck()); DCHECK(!IsStreamLockedForDCheck());
DCHECK(!IsStreamDisturbedForDCheck()); DCHECK(!IsStreamDisturbedForDCheck());
if (IsStreamClosed() || IsStreamErrored()) const base::Optional<bool> is_closed = IsStreamClosed(exception_state);
if (exception_state.HadException() || is_closed.value())
return nullptr;
const base::Optional<bool> is_errored = IsStreamErrored(exception_state);
if (exception_state.HadException() || is_errored.value())
return nullptr; return nullptr;
if (made_from_readable_stream_) if (made_from_readable_stream_)
...@@ -349,14 +357,16 @@ base::Optional<bool> BodyStreamBuffer::IsStreamReadable( ...@@ -349,14 +357,16 @@ base::Optional<bool> BodyStreamBuffer::IsStreamReadable(
exception_state); exception_state);
} }
bool BodyStreamBuffer::IsStreamClosed() { base::Optional<bool> BodyStreamBuffer::IsStreamClosed(
return BooleanStreamOperationOrFallback(ReadableStreamOperations::IsClosed, ExceptionState& exception_state) {
true); return BooleanStreamOperation(ReadableStreamOperations::IsClosed,
exception_state);
} }
bool BodyStreamBuffer::IsStreamErrored() { base::Optional<bool> BodyStreamBuffer::IsStreamErrored(
return BooleanStreamOperationOrFallback(ReadableStreamOperations::IsErrored, ExceptionState& exception_state) {
true); return BooleanStreamOperation(ReadableStreamOperations::IsErrored,
exception_state);
} }
base::Optional<bool> BodyStreamBuffer::IsStreamLocked( base::Optional<bool> BodyStreamBuffer::IsStreamLocked(
...@@ -490,20 +500,6 @@ void BodyStreamBuffer::StopLoading() { ...@@ -490,20 +500,6 @@ void BodyStreamBuffer::StopLoading() {
loader_ = nullptr; loader_ = nullptr;
} }
bool BodyStreamBuffer::BooleanStreamOperationOrFallback(
base::Optional<bool> (*predicate)(ScriptState*, ScriptValue),
bool fallback_value) {
if (stream_broken_)
return fallback_value;
ScriptState::Scope scope(script_state_.get());
const base::Optional<bool> result = predicate(script_state_.get(), Stream());
if (!result.has_value()) {
stream_broken_ = true;
return fallback_value;
}
return result.value();
}
base::Optional<bool> BodyStreamBuffer::BooleanStreamOperation( base::Optional<bool> BodyStreamBuffer::BooleanStreamOperation(
base::Optional<bool> (*predicate)(ScriptState*, base::Optional<bool> (*predicate)(ScriptState*,
ScriptValue, ScriptValue,
...@@ -556,21 +552,26 @@ BytesConsumer* BodyStreamBuffer::ReleaseHandle( ...@@ -556,21 +552,26 @@ BytesConsumer* BodyStreamBuffer::ReleaseHandle(
} }
return new ReadableStreamBytesConsumer(script_state_.get(), reader); return new ReadableStreamBytesConsumer(script_state_.get(), reader);
} }
// We need to call these before calling closeAndLockAndDisturb. // We need to call these before calling CloseAndLockAndDisturb.
const bool is_closed = IsStreamClosed(); const base::Optional<bool> is_closed = IsStreamClosed(exception_state);
const bool is_errored = IsStreamErrored(); if (exception_state.HadException())
return nullptr;
const base::Optional<bool> is_errored = IsStreamErrored(exception_state);
if (exception_state.HadException())
return nullptr;
BytesConsumer* consumer = consumer_.Release(); BytesConsumer* consumer = consumer_.Release();
CloseAndLockAndDisturb(exception_state); CloseAndLockAndDisturb(exception_state);
if (exception_state.HadException()) if (exception_state.HadException())
return nullptr; return nullptr;
if (is_closed) { if (is_closed.value()) {
// Note that the stream cannot be "draining", because it doesn't have // Note that the stream cannot be "draining", because it doesn't have
// the internal buffer. // the internal buffer.
return BytesConsumer::CreateClosed(); return BytesConsumer::CreateClosed();
} }
if (is_errored) if (is_errored.value())
return BytesConsumer::CreateErrored(BytesConsumer::Error("error")); return BytesConsumer::CreateErrored(BytesConsumer::Error("error"));
DCHECK(consumer); DCHECK(consumer);
......
...@@ -63,8 +63,8 @@ class CORE_EXPORT BodyStreamBuffer final : public UnderlyingSourceBase, ...@@ -63,8 +63,8 @@ class CORE_EXPORT BodyStreamBuffer final : public UnderlyingSourceBase,
String DebugName() const override { return "BodyStreamBuffer"; } String DebugName() const override { return "BodyStreamBuffer"; }
base::Optional<bool> IsStreamReadable(ExceptionState&); base::Optional<bool> IsStreamReadable(ExceptionState&);
bool IsStreamClosed(); base::Optional<bool> IsStreamClosed(ExceptionState&);
bool IsStreamErrored(); base::Optional<bool> IsStreamErrored(ExceptionState&);
base::Optional<bool> IsStreamLocked(ExceptionState&); base::Optional<bool> IsStreamLocked(ExceptionState&);
bool IsStreamLockedForDCheck(); bool IsStreamLockedForDCheck();
base::Optional<bool> IsStreamDisturbed(ExceptionState&); base::Optional<bool> IsStreamDisturbed(ExceptionState&);
...@@ -93,19 +93,10 @@ class CORE_EXPORT BodyStreamBuffer final : public UnderlyingSourceBase, ...@@ -93,19 +93,10 @@ class CORE_EXPORT BodyStreamBuffer final : public UnderlyingSourceBase,
void EndLoading(); void EndLoading();
void StopLoading(); void StopLoading();
// Implementation of IsStream*() methods that don't take an ExceptionState& // Implementation of IsStream*() methods. Delegates to |predicate|, one of the
// parameter. Delegates to |predicate|, one of the methods defined in // methods defined in ReadableStreamOperations. Sets |stream_broken_| and
// ReadableStreamOperations. Sets |stream_broken_| if |predicate| returns // throws if |predicate| throws. Throws an exception if called when
// empty. Returns |fallback_value| if |stream_broken_| is or becomes true. // |stream_broken_| is already true.
bool BooleanStreamOperationOrFallback(
base::Optional<bool> (*predicate)(ScriptState*, ScriptValue),
bool fallback_value);
// Implementation of IsStream*() methods that take an ExceptionState&
// parameter. Delegates to |predicate|, one of the methods defined in
// ReadableStreamOperations. Sets |stream_broken_| and throws if |predicate|
// throws. Throws an exception if called when |stream_broken_| is already
// true.
base::Optional<bool> BooleanStreamOperation( base::Optional<bool> BooleanStreamOperation(
base::Optional<bool> (*predicate)(ScriptState*, base::Optional<bool> (*predicate)(ScriptState*,
ScriptValue, ScriptValue,
......
...@@ -443,7 +443,7 @@ TEST_F(BodyStreamBufferTest, LoadClosedHandle) { ...@@ -443,7 +443,7 @@ TEST_F(BodyStreamBufferTest, LoadClosedHandle) {
BodyStreamBuffer* buffer = new BodyStreamBuffer( BodyStreamBuffer* buffer = new BodyStreamBuffer(
scope.GetScriptState(), BytesConsumer::CreateClosed(), nullptr); scope.GetScriptState(), BytesConsumer::CreateClosed(), nullptr);
EXPECT_TRUE(buffer->IsStreamClosed()); EXPECT_TRUE(buffer->IsStreamClosed(ASSERT_NO_EXCEPTION).value_or(false));
EXPECT_FALSE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(true)); EXPECT_FALSE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(true));
EXPECT_FALSE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(true)); EXPECT_FALSE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(true));
...@@ -473,7 +473,7 @@ TEST_F(BodyStreamBufferTest, LoadErroredHandle) { ...@@ -473,7 +473,7 @@ TEST_F(BodyStreamBufferTest, LoadErroredHandle) {
scope.GetScriptState(), scope.GetScriptState(),
BytesConsumer::CreateErrored(BytesConsumer::Error()), nullptr); BytesConsumer::CreateErrored(BytesConsumer::Error()), nullptr);
EXPECT_TRUE(buffer->IsStreamErrored()); EXPECT_TRUE(buffer->IsStreamErrored(ASSERT_NO_EXCEPTION).value_or(false));
EXPECT_FALSE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(true)); EXPECT_FALSE(buffer->IsStreamLocked(ASSERT_NO_EXCEPTION).value_or(true));
EXPECT_FALSE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(true)); EXPECT_FALSE(buffer->IsStreamDisturbed(ASSERT_NO_EXCEPTION).value_or(true));
......
...@@ -193,16 +193,20 @@ base::Optional<bool> ReadableStreamOperations::IsReadable( ...@@ -193,16 +193,20 @@ base::Optional<bool> ReadableStreamOperations::IsReadable(
base::Optional<bool> ReadableStreamOperations::IsClosed( base::Optional<bool> ReadableStreamOperations::IsClosed(
ScriptState* script_state, ScriptState* script_state,
ScriptValue stream) { ScriptValue stream,
ExceptionState& exception_state) {
DCHECK(IsReadableStreamForDCheck(script_state, stream)); DCHECK(IsReadableStreamForDCheck(script_state, stream));
return BooleanOperation(script_state, stream, "IsReadableStreamClosed"); return BooleanOperationWithRethrow(script_state, stream,
"IsReadableStreamClosed", exception_state);
} }
base::Optional<bool> ReadableStreamOperations::IsErrored( base::Optional<bool> ReadableStreamOperations::IsErrored(
ScriptState* script_state, ScriptState* script_state,
ScriptValue stream) { ScriptValue stream,
ExceptionState& exception_state) {
DCHECK(IsReadableStreamForDCheck(script_state, stream)); DCHECK(IsReadableStreamForDCheck(script_state, stream));
return BooleanOperation(script_state, stream, "IsReadableStreamErrored"); return BooleanOperationWithRethrow(
script_state, stream, "IsReadableStreamErrored", exception_state);
} }
base::Optional<bool> ReadableStreamOperations::IsReadableStreamDefaultReader( base::Optional<bool> ReadableStreamOperations::IsReadableStreamDefaultReader(
......
...@@ -99,11 +99,15 @@ class CORE_EXPORT ReadableStreamOperations { ...@@ -99,11 +99,15 @@ class CORE_EXPORT ReadableStreamOperations {
// IsReadableStreamClosed. // IsReadableStreamClosed.
// This function assumes |IsReadableStream(stream)|. // This function assumes |IsReadableStream(stream)|.
static base::Optional<bool> IsClosed(ScriptState*, ScriptValue stream); static base::Optional<bool> IsClosed(ScriptState*,
ScriptValue stream,
ExceptionState& exception_state);
// IsReadableStreamErrored. // IsReadableStreamErrored.
// This function assumes |IsReadableStream(stream)|. // This function assumes |IsReadableStream(stream)|.
static base::Optional<bool> IsErrored(ScriptState*, ScriptValue stream); static base::Optional<bool> IsErrored(ScriptState*,
ScriptValue stream,
ExceptionState& exception_state);
// IsReadableStreamDefaultReader. // IsReadableStreamDefaultReader.
static base::Optional<bool> IsReadableStreamDefaultReader(ScriptState*, static base::Optional<bool> IsReadableStreamDefaultReader(ScriptState*,
......
...@@ -394,14 +394,15 @@ TEST(ReadableStreamOperationsTest, IsClosed) { ...@@ -394,14 +394,15 @@ TEST(ReadableStreamOperationsTest, IsClosed) {
ASSERT_FALSE(closed.IsEmpty()); ASSERT_FALSE(closed.IsEmpty());
ASSERT_FALSE(errored.IsEmpty()); ASSERT_FALSE(errored.IsEmpty());
EXPECT_FALSE( EXPECT_FALSE(ReadableStreamOperations::IsClosed(scope.GetScriptState(),
ReadableStreamOperations::IsClosed(scope.GetScriptState(), readable) readable, ASSERT_NO_EXCEPTION)
.value_or(true)); .value_or(true));
EXPECT_TRUE(ReadableStreamOperations::IsClosed(scope.GetScriptState(), closed) EXPECT_TRUE(ReadableStreamOperations::IsClosed(scope.GetScriptState(), closed,
ASSERT_NO_EXCEPTION)
.value_or(false)); .value_or(false));
EXPECT_FALSE( EXPECT_FALSE(ReadableStreamOperations::IsClosed(scope.GetScriptState(),
ReadableStreamOperations::IsClosed(scope.GetScriptState(), errored) errored, ASSERT_NO_EXCEPTION)
.value_or(true)); .value_or(true));
} }
TEST(ReadableStreamOperationsTest, IsErrored) { TEST(ReadableStreamOperationsTest, IsErrored) {
...@@ -416,15 +417,15 @@ TEST(ReadableStreamOperationsTest, IsErrored) { ...@@ -416,15 +417,15 @@ TEST(ReadableStreamOperationsTest, IsErrored) {
ASSERT_FALSE(closed.IsEmpty()); ASSERT_FALSE(closed.IsEmpty());
ASSERT_FALSE(errored.IsEmpty()); ASSERT_FALSE(errored.IsEmpty());
EXPECT_FALSE( EXPECT_FALSE(ReadableStreamOperations::IsErrored(
ReadableStreamOperations::IsErrored(scope.GetScriptState(), readable) scope.GetScriptState(), readable, ASSERT_NO_EXCEPTION)
.value_or(true)); .value_or(true));
EXPECT_FALSE( EXPECT_FALSE(ReadableStreamOperations::IsErrored(scope.GetScriptState(),
ReadableStreamOperations::IsErrored(scope.GetScriptState(), closed) closed, ASSERT_NO_EXCEPTION)
.value_or(true)); .value_or(true));
EXPECT_TRUE( EXPECT_TRUE(ReadableStreamOperations::IsErrored(scope.GetScriptState(),
ReadableStreamOperations::IsErrored(scope.GetScriptState(), errored) errored, ASSERT_NO_EXCEPTION)
.value_or(false)); .value_or(false));
} }
TEST(ReadableStreamOperationsTest, Tee) { TEST(ReadableStreamOperationsTest, Tee) {
......
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