[promises] Handle double scheduling of GRPC_OP_RECV_STATUS_ON_CLIENT (#34680)

pull/34723/head
Craig Tiller 1 year ago committed by GitHub
parent 6d669e9c78
commit b6dbfc9163
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      src/core/lib/surface/call.cc
  2. 27
      test/core/end2end/fuzzers/client_fuzzer_corpus/5760937752592384
  3. 1
      test/core/end2end/fuzzers/fuzzing_common.cc

@ -2836,6 +2836,7 @@ class ClientPromiseBasedCall final : public PromiseBasedCall {
Pipe<MessageHandle> client_to_server_messages_{arena()}; Pipe<MessageHandle> client_to_server_messages_{arena()};
Pipe<MessageHandle> server_to_client_messages_{arena()}; Pipe<MessageHandle> server_to_client_messages_{arena()};
bool is_trailers_only_ = false; bool is_trailers_only_ = false;
bool scheduled_receive_status_ = false;
// True once the promise for the call is started. // True once the promise for the call is started.
// This corresponds to sending initial metadata, or cancelling before doing // This corresponds to sending initial metadata, or cancelling before doing
// so. // so.
@ -2906,8 +2907,13 @@ grpc_call_error ClientPromiseBasedCall::ValidateBatch(const grpc_op* ops,
case GRPC_OP_RECV_INITIAL_METADATA: case GRPC_OP_RECV_INITIAL_METADATA:
case GRPC_OP_RECV_MESSAGE: case GRPC_OP_RECV_MESSAGE:
case GRPC_OP_SEND_CLOSE_FROM_CLIENT: case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
if (op.flags != 0) return GRPC_CALL_ERROR_INVALID_FLAGS;
break;
case GRPC_OP_RECV_STATUS_ON_CLIENT: case GRPC_OP_RECV_STATUS_ON_CLIENT:
if (op.flags != 0) return GRPC_CALL_ERROR_INVALID_FLAGS; if (op.flags != 0) return GRPC_CALL_ERROR_INVALID_FLAGS;
if (scheduled_receive_status_) {
return GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
}
break; break;
case GRPC_OP_RECV_CLOSE_ON_SERVER: case GRPC_OP_RECV_CLOSE_ON_SERVER:
case GRPC_OP_SEND_STATUS_FROM_SERVER: case GRPC_OP_SEND_STATUS_FROM_SERVER:
@ -2950,6 +2956,7 @@ void ClientPromiseBasedCall::CommitBatch(const grpc_op* ops, size_t nops,
spawner); spawner);
} break; } break;
case GRPC_OP_RECV_STATUS_ON_CLIENT: { case GRPC_OP_RECV_STATUS_ON_CLIENT: {
scheduled_receive_status_ = true;
StartRecvStatusOnClient(completion, op.data.recv_status_on_client, StartRecvStatusOnClient(completion, op.data.recv_status_on_client,
spawner); spawner);
} break; } break;

@ -0,0 +1,27 @@
api_actions {
create_call {
method {
value: "http"
}
timeout: 1862270974
}
}
api_actions {
queue_batch {
operations {
receive_status_on_client {
}
}
}
}
api_actions {
queue_batch {
operations {
receive_status_on_client {
}
}
}
}
config_vars {
experiments: 4702337453602635775
}

@ -655,6 +655,7 @@ bool BasicFuzzer::Continue() {
BasicFuzzer::Result BasicFuzzer::ExecuteAction( BasicFuzzer::Result BasicFuzzer::ExecuteAction(
const api_fuzzer::Action& action) { const api_fuzzer::Action& action) {
gpr_log(GPR_DEBUG, "EXECUTE_ACTION: %s", action.DebugString().c_str());
switch (action.type_case()) { switch (action.type_case()) {
case api_fuzzer::Action::TYPE_NOT_SET: case api_fuzzer::Action::TYPE_NOT_SET:
return BasicFuzzer::Result::kFailed; return BasicFuzzer::Result::kFailed;

Loading…
Cancel
Save