diff --git a/sandboxed_api/BUILD.bazel b/sandboxed_api/BUILD.bazel index e02db84..187d5e4 100644 --- a/sandboxed_api/BUILD.bazel +++ b/sandboxed_api/BUILD.bazel @@ -127,6 +127,7 @@ cc_library( cc_library( name = "vars", srcs = [ + "proto_helper.cc", "rpcchannel.cc", "var_abstract.cc", "var_int.cc", diff --git a/sandboxed_api/CMakeLists.txt b/sandboxed_api/CMakeLists.txt index 7aab157..09624af 100644 --- a/sandboxed_api/CMakeLists.txt +++ b/sandboxed_api/CMakeLists.txt @@ -129,6 +129,7 @@ target_link_libraries(sapi_var_type PRIVATE # sandboxed_api:vars add_library(sapi_vars ${SAPI_LIB_TYPE} + proto_helper.cc proto_helper.h rpcchannel.cc rpcchannel.h diff --git a/sandboxed_api/proto_helper.cc b/sandboxed_api/proto_helper.cc new file mode 100644 index 0000000..a83bdc4 --- /dev/null +++ b/sandboxed_api/proto_helper.cc @@ -0,0 +1,55 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "sandboxed_api/proto_helper.h" + +#include "absl/status/status.h" + +namespace sapi { + +namespace internal { + +absl::Status DeserializeProto(const char* data, size_t len, + google::protobuf::Message& output) { + ProtoArg envelope; + if (!envelope.ParseFromArray(data, len)) { + return absl::InternalError("Unable to parse proto from array"); + } + + auto pb_data = envelope.protobuf_data(); + if (!output.ParseFromArray(pb_data.data(), pb_data.size())) { + return absl::InternalError("Unable to parse proto from envelope data"); + } + return absl::OkStatus(); +} + +} // namespace internal + +absl::StatusOr> SerializeProto( + const google::protobuf::Message& proto) { + // Wrap protobuf in a envelope so that we know the name of the protobuf + // structure when deserializing in the sandboxee. + ProtoArg proto_arg; + proto_arg.set_protobuf_data(proto.SerializeAsString()); + proto_arg.set_full_name(proto.GetDescriptor()->full_name()); + + std::vector serialized_proto(proto_arg.ByteSizeLong()); + if (!proto_arg.SerializeToArray(serialized_proto.data(), + serialized_proto.size())) { + return absl::InternalError("Unable to serialize proto to array"); + } + return serialized_proto; +} + +} // namespace sapi diff --git a/sandboxed_api/proto_helper.h b/sandboxed_api/proto_helper.h index 63c4294..0c22fab 100644 --- a/sandboxed_api/proto_helper.h +++ b/sandboxed_api/proto_helper.h @@ -24,41 +24,27 @@ #include "absl/status/status.h" #include "absl/status/statusor.h" #include "sandboxed_api/proto_arg.pb.h" +#include "sandboxed_api/util/status_macros.h" namespace sapi { -template -absl::StatusOr> SerializeProto(const T& proto) { - static_assert(std::is_base_of::value, - "Template argument must be a proto message"); - // Wrap protobuf in a envelope so that we know the name of the protobuf - // structure when deserializing in the sandboxee. - ProtoArg proto_arg; - proto_arg.set_protobuf_data(proto.SerializeAsString()); - proto_arg.set_full_name(proto.GetDescriptor()->full_name()); +namespace internal { - std::vector serialized_proto(proto_arg.ByteSizeLong()); - if (!proto_arg.SerializeToArray(serialized_proto.data(), - serialized_proto.size())) { - return absl::InternalError("Unable to serialize proto to array"); - } - return serialized_proto; -} +absl::Status DeserializeProto(const char* data, size_t len, + google::protobuf::Message& output); + +} // namespace internal + +absl::StatusOr> SerializeProto( + const google::protobuf::Message& proto); template absl::StatusOr DeserializeProto(const char* data, size_t len) { static_assert(std::is_base_of::value, "Template argument must be a proto message"); - ProtoArg envelope; - if (!envelope.ParseFromArray(data, len)) { - return absl::InternalError("Unable to parse proto from array"); - } - - auto pb_data = envelope.protobuf_data(); T result; - if (!result.ParseFromArray(pb_data.data(), pb_data.size())) { - return absl::InternalError("Unable to parse proto from envelope data"); - } + SAPI_RETURN_IF_ERROR( + internal::DeserializeProto(data, len, /*output=*/result)); return result; }