diff options
10 files changed, 71 insertions, 30 deletions
diff --git a/mojo/public/cpp/bindings/lib/array_serialization.h b/mojo/public/cpp/bindings/lib/array_serialization.h index b6168033..8759f6d 100644 --- a/mojo/public/cpp/bindings/lib/array_serialization.h +++ b/mojo/public/cpp/bindings/lib/array_serialization.h @@ -30,7 +30,7 @@ inline void SerializeArray_( const internal::ArrayValidateParams* validate_params); template <typename E, typename F> -inline void Deserialize_(internal::Array_Data<F>* data, +inline bool Deserialize_(internal::Array_Data<F>* data, Array<E>* output, internal::SerializationContext* context); @@ -62,13 +62,14 @@ struct ArraySerializer<E, F, false> { if (input.size()) memcpy(output->storage(), &input.storage()[0], input.size() * sizeof(E)); } - static void DeserializeElements(Array_Data<F>* input, + static bool DeserializeElements(Array_Data<F>* input, Array<E>* output, SerializationContext* context) { std::vector<E> result(input->size()); if (input->size()) memcpy(&result[0], input->storage(), input->size() * sizeof(E)); output->Swap(&result); + return true; } }; @@ -92,7 +93,7 @@ struct ArraySerializer<bool, bool, false> { for (size_t i = 0; i < input.size(); ++i) output->at(i) = input[i]; } - static void DeserializeElements(Array_Data<bool>* input, + static bool DeserializeElements(Array_Data<bool>* input, Array<bool>* output, SerializationContext* context) { Array<bool> result(input->size()); @@ -100,6 +101,7 @@ struct ArraySerializer<bool, bool, false> { for (size_t i = 0; i < input->size(); ++i) result.at(i) = input->at(i); output->Swap(&result); + return true; } }; @@ -127,13 +129,14 @@ struct ArraySerializer<ScopedHandleBase<H>, H, false> { i)); } } - static void DeserializeElements(Array_Data<H>* input, + static bool DeserializeElements(Array_Data<H>* input, Array<ScopedHandleBase<H>>* output, SerializationContext* context) { Array<ScopedHandleBase<H>> result(input->size()); for (size_t i = 0; i < input->size(); ++i) result.at(i) = MakeScopedHandle(FetchAndReset(&input->at(i))); output->Swap(&result); + return true; } }; @@ -171,14 +174,20 @@ struct ArraySerializer< input.size(), i)); } } - static void DeserializeElements(Array_Data<S_Data*>* input, + static bool DeserializeElements(Array_Data<S_Data*>* input, Array<S>* output, SerializationContext* context) { + bool success = true; Array<S> result(input->size()); for (size_t i = 0; i < input->size(); ++i) { - Deserialize_(input->at(i), &result[i], context); + // Note that we rely on complete deserialization taking place in order to + // transfer ownership of all encoded handles. Therefore we don't + // short-circuit on failure here. + if (!Deserialize_(input->at(i), &result[i], context)) + success = false; } output->Swap(&result); + return success; } private: @@ -244,14 +253,20 @@ struct ArraySerializer<U, U_Data, true> { } } - static void DeserializeElements(Array_Data<U_Data>* input, + static bool DeserializeElements(Array_Data<U_Data>* input, Array<U>* output, SerializationContext* context) { + bool success = true; Array<U> result(input->size()); for (size_t i = 0; i < input->size(); ++i) { - Deserialize_(&input->at(i), &result[i], context); + // Note that we rely on complete deserialization taking place in order to + // transfer ownership of all encoded handles. Therefore we don't + // short-circuit on failure here. + if (!Deserialize_(&input->at(i), &result[i], context)) + success = false; } output->Swap(&result); + return success; } }; @@ -288,13 +303,17 @@ struct ArraySerializer<String, String_Data*> { input.size(), i)); } } - static void DeserializeElements(Array_Data<String_Data*>* input, + static bool DeserializeElements(Array_Data<String_Data*>* input, Array<String>* output, SerializationContext* context) { Array<String> result(input->size()); - for (size_t i = 0; i < input->size(); ++i) - Deserialize_(input->at(i), &result[i], context); + for (size_t i = 0; i < input->size(); ++i) { + // It's OK to short-circuit here since string data cannot contain handles. + if (!Deserialize_(input->at(i), &result[i], context)) + return false; + } output->Swap(&result); + return true; } }; @@ -336,15 +355,18 @@ inline void SerializeArray_( } template <typename E, typename F> -inline void Deserialize_(internal::Array_Data<F>* input, +inline bool Deserialize_(internal::Array_Data<F>* input, Array<E>* output, internal::SerializationContext* context) { if (input) { - internal::ArraySerializer<E, F>::DeserializeElements(input, output, - context); + if (!internal::ArraySerializer<E, F>::DeserializeElements(input, output, + context)) { + return false; + } } else { output->reset(); } + return true; } } // namespace mojo diff --git a/mojo/public/cpp/bindings/lib/map_serialization.h b/mojo/public/cpp/bindings/lib/map_serialization.h index 6874fbe..b326872 100644 --- a/mojo/public/cpp/bindings/lib/map_serialization.h +++ b/mojo/public/cpp/bindings/lib/map_serialization.h @@ -162,20 +162,27 @@ template <typename MapKey, typename MapValue, typename DataKey, typename DataValue> -inline void Deserialize_(internal::Map_Data<DataKey, DataValue>* input, +inline bool Deserialize_(internal::Map_Data<DataKey, DataValue>* input, Map<MapKey, MapValue>* output, internal::SerializationContext* context) { + bool success = true; if (input) { Array<MapKey> keys; Array<MapValue> values; - Deserialize_(input->keys.ptr, &keys, context); - Deserialize_(input->values.ptr, &values, context); + // Note that we rely on complete deserialization taking place in order to + // transfer ownership of all encoded handles. Therefore we don't + // short-circuit on failure here. + if (!Deserialize_(input->keys.ptr, &keys, context)) + success = false; + if (!Deserialize_(input->values.ptr, &values, context)) + success = false; *output = Map<MapKey, MapValue>(keys.Pass(), values.Pass()); } else { output->reset(); } + return success; } } // namespace mojo diff --git a/mojo/public/cpp/bindings/lib/string_serialization.cc b/mojo/public/cpp/bindings/lib/string_serialization.cc index be1508d..936493e 100644 --- a/mojo/public/cpp/bindings/lib/string_serialization.cc +++ b/mojo/public/cpp/bindings/lib/string_serialization.cc @@ -28,7 +28,7 @@ void Serialize_(const String& input, } } -void Deserialize_(internal::String_Data* input, +bool Deserialize_(internal::String_Data* input, String* output, internal::SerializationContext* context) { if (input) { @@ -37,6 +37,7 @@ void Deserialize_(internal::String_Data* input, } else { output->reset(); } + return true; } } // namespace mojo diff --git a/mojo/public/cpp/bindings/lib/string_serialization.h b/mojo/public/cpp/bindings/lib/string_serialization.h index 9bee8ff..f6e7c1c 100644 --- a/mojo/public/cpp/bindings/lib/string_serialization.h +++ b/mojo/public/cpp/bindings/lib/string_serialization.h @@ -14,7 +14,7 @@ size_t GetSerializedSize_(const String& input); void Serialize_(const String& input, internal::Buffer* buffer, internal::String_Data** output); -void Deserialize_(internal::String_Data* input, +bool Deserialize_(internal::String_Data* input, String* output, internal::SerializationContext* context); diff --git a/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl index 9889f8b..a445313 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl @@ -7,10 +7,13 @@ {%- set namespace_as_string = "%s"|format(namespace|replace(".","::")) %} {%- macro alloc_params(struct, serialization_context) %} + bool success = true; {%- for param in struct.packed.packed_fields_in_ordinal_order %} {{param.field.kind|cpp_result_type}} p_{{param.field.name}}{}; {%- endfor %} - {{struct_macros.deserialize(struct, "params", "p_%s", serialization_context)}} + {{struct_macros.deserialize(struct, "params", "p_%s", serialization_context, "success")}} + if (!success) + return false; {%- endmacro %} {%- macro pass_params(parameters) %} @@ -224,11 +227,11 @@ bool {{class_name}}Stub::AcceptWithResponder( message->mutable_payload()); params->DecodePointersAndHandles(message->mutable_handles()); + {{alloc_params(method.param_struct, "&serialization_context_")|indent(4)}} {{class_name}}::{{method.name}}Callback::Runnable* runnable = new {{class_name}}_{{method.name}}_ProxyToResponder( message->request_id(), responder); {{class_name}}::{{method.name}}Callback callback(runnable); - {{alloc_params(method.param_struct, "&serialization_context_")|indent(4)}} // A null |sink_| means no implementation was bound. assert(sink_); TRACE_EVENT0("mojom", "{{class_name}}::{{method.name}}"); diff --git a/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl index f28948a..0898949 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/struct_macros.tmpl @@ -113,7 +113,8 @@ - method parameters/response parameters: the output is a list of arguments. #} |context| is the name of the serialization context. -{%- macro deserialize(struct, input, output_field_pattern, context) -%} + |success| is the name of a bool variable to track success of the operation. +{%- macro deserialize(struct, input, output_field_pattern, context, success) -%} do { // NOTE: The memory backing |{{input}}| may has be smaller than // |sizeof(*{{input}})| if the message comes from an older version. @@ -133,9 +134,11 @@ {%- endif %} {%- if kind|is_object_kind %} {%- if kind|is_union_kind %} - Deserialize_(&{{input}}->{{name}}, &{{output_field}}, {{context}}); + if (!Deserialize_(&{{input}}->{{name}}, &{{output_field}}, {{context}})) + {{success}} = false; {%- else %} - Deserialize_({{input}}->{{name}}.ptr, &{{output_field}}, {{context}}); + if (!Deserialize_({{input}}->{{name}}.ptr, &{{output_field}}, {{context}})) + {{success}} = false; {%- endif %} {%- elif kind|is_interface_kind %} mojo::internal::InterfaceDataToPointer(&{{input}}->{{name}}, &{{output_field}}); diff --git a/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_declaration.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_declaration.tmpl index 1f02481..5ded622 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_declaration.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_declaration.tmpl @@ -1,6 +1,6 @@ size_t GetSerializedSize_(const {{struct.name}}Ptr& input); void Serialize_({{struct.name}}Ptr input, mojo::internal::Buffer* buffer, internal::{{struct.name}}_Data** output); -void Deserialize_(internal::{{struct.name}}_Data* input, +bool Deserialize_(internal::{{struct.name}}_Data* input, {{struct.name}}Ptr* output, mojo::internal::SerializationContext* context); diff --git a/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_definition.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_definition.tmpl index 24cc767..5c14ea0 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_definition.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_definition.tmpl @@ -16,14 +16,16 @@ void Serialize_({{struct.name}}Ptr input, mojo::internal::Buffer* buf, } } -void Deserialize_(internal::{{struct.name}}_Data* input, +bool Deserialize_(internal::{{struct.name}}_Data* input, {{struct.name}}Ptr* output, mojo::internal::SerializationContext* context) { + bool success = true; if (input) { {{struct.name}}Ptr result({{struct.name}}::New()); - {{struct_macros.deserialize(struct, "input", "result->%s", "context")|indent(2)}} + {{struct_macros.deserialize(struct, "input", "result->%s", "context", "success")|indent(2)}} *output = result.Pass(); } else { output->reset(); } + return success; } diff --git a/mojo/public/tools/bindings/generators/cpp_templates/union_serialization_declaration.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/union_serialization_declaration.tmpl index 6773486..3604763 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/union_serialization_declaration.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/union_serialization_declaration.tmpl @@ -1,6 +1,6 @@ size_t GetSerializedSize_(const {{union.name}}Ptr& input, bool inlined); void SerializeUnion_({{union.name}}Ptr input, mojo::internal::Buffer* buffer, internal::{{union.name}}_Data** output, bool inlined); -void Deserialize_(internal::{{union.name}}_Data* input, +bool Deserialize_(internal::{{union.name}}_Data* input, {{union.name}}Ptr* output, mojo::internal::SerializationContext* context); diff --git a/mojo/public/tools/bindings/generators/cpp_templates/union_serialization_definition.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/union_serialization_definition.tmpl index 3471932..73f6c95 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/union_serialization_definition.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/union_serialization_definition.tmpl @@ -93,9 +93,10 @@ void SerializeUnion_({{union.name}}Ptr input, mojo::internal::Buffer* buf, *output = result; } -void Deserialize_(internal::{{union.name}}_Data* input, +bool Deserialize_(internal::{{union.name}}_Data* input, {{union.name}}Ptr* output, mojo::internal::SerializationContext* context) { + bool success = true; if (input && !input->is_null()) { {{union.name}}Ptr result({{union.name}}::New()); mojo::internal::UnionAccessor<{{union.name}}> result_acc(result.get()); @@ -104,7 +105,8 @@ void Deserialize_(internal::{{union.name}}_Data* input, case {{union.name}}::Tag::{{field.name|upper}}: { {% if field.kind|is_object_kind %} result_acc.SwitchActive({{union.name}}::Tag::{{field.name|upper}}); - Deserialize_(input->data.f_{{field.name}}.ptr, result_acc.data()->{{field.name}}, context); + if (!Deserialize_(input->data.f_{{field.name}}.ptr, result_acc.data()->{{field.name}}, context)) + success = false; {% elif field.kind|is_any_handle_kind %} {{field.kind|cpp_wrapper_type}}* {{field.name}} = reinterpret_cast<{{field.kind|cpp_wrapper_type}}*>(&input->data.f_{{field.name}}); @@ -132,4 +134,5 @@ void Deserialize_(internal::{{union.name}}_Data* input, } else { output->reset(); } + return success; } |