1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ppapi/proxy/ppapi_param_traits.h"
7 #include <string.h> // For memcpy
9 #include "ppapi/c/pp_resource.h"
10 #include "ppapi/proxy/ppapi_messages.h"
11 #include "ppapi/proxy/serialized_var.h"
12 #include "ppapi/proxy/serialized_flash_menu.h"
13 #include "ppapi/shared_impl/host_resource.h"
14 #include "ppapi/shared_impl/private/ppb_x509_certificate_private_shared.h"
20 // Deserializes a vector from IPC. This special version must be used instead
21 // of the default IPC version when the vector contains a SerializedVar, either
22 // directly or indirectly (i.e. a vector of objects that have a SerializedVar
25 // The default vector deserializer does resize and then we deserialize into
26 // those allocated slots. However, the implementation of vector (at least in
27 // GCC's implementation), creates a new empty object using the default
28 // constructor, and then sets the rest of the items to that empty one using the
31 // Since we allocate the inner class when you call the default constructor and
32 // transfer the inner class when you do operator=, the entire vector will end
33 // up referring to the same inner class. Deserializing into this will just end
34 // up overwriting the same item over and over, since all the SerializedVars
35 // will refer to the same thing.
37 // The solution is to make a new object for each deserialized item, and then
38 // add it to the vector one at a time.
40 bool ReadVectorWithoutCopy(const Message
* m
,
42 std::vector
<T
>* output
) {
43 // This part is just a copy of the the default ParamTraits vector Read().
45 // ReadLength() checks for < 0 itself.
46 if (!m
->ReadLength(iter
, &size
))
48 // Resizing beforehand is not safe, see BUG 1006367 for details.
49 if (INT_MAX
/ sizeof(T
) <= static_cast<size_t>(size
))
52 output
->reserve(size
);
53 for (int i
= 0; i
< size
; i
++) {
55 if (!ReadParam(m
, iter
, &cur
))
57 output
->push_back(cur
);
62 // This serializes the vector of items to the IPC message in exactly the same
63 // way as the "regular" IPC vector serializer does. But having the code here
64 // saves us from having to copy this code into all ParamTraits that use the
65 // ReadVectorWithoutCopy function for deserializing.
67 void WriteVectorWithoutCopy(Message
* m
, const std::vector
<T
>& p
) {
68 WriteParam(m
, static_cast<int>(p
.size()));
69 for (size_t i
= 0; i
< p
.size(); i
++)
75 // PP_Bool ---------------------------------------------------------------------
78 void ParamTraits
<PP_Bool
>::Write(Message
* m
, const param_type
& p
) {
79 ParamTraits
<bool>::Write(m
, PP_ToBool(p
));
83 bool ParamTraits
<PP_Bool
>::Read(const Message
* m
,
86 // We specifically want to be strict here about what types of input we accept,
87 // which ParamTraits<bool> does for us. We don't want to deserialize "2" into
88 // a PP_Bool, for example.
90 if (!ParamTraits
<bool>::Read(m
, iter
, &result
))
92 *r
= PP_FromBool(result
);
97 void ParamTraits
<PP_Bool
>::Log(const param_type
& p
, std::string
* l
) {
100 // PP_NetAddress_Private -------------------------------------------------------
103 void ParamTraits
<PP_NetAddress_Private
>::Write(Message
* m
,
104 const param_type
& p
) {
105 WriteParam(m
, p
.size
);
106 m
->WriteBytes(p
.data
, static_cast<int>(p
.size
));
110 bool ParamTraits
<PP_NetAddress_Private
>::Read(const Message
* m
,
111 PickleIterator
* iter
,
114 if (!ReadParam(m
, iter
, &size
))
116 if (size
> sizeof(p
->data
))
121 if (!m
->ReadBytes(iter
, &data
, size
))
123 memcpy(p
->data
, data
, size
);
128 void ParamTraits
<PP_NetAddress_Private
>::Log(const param_type
& p
,
130 l
->append("<PP_NetAddress_Private (");
132 l
->append(" bytes)>");
135 // HostResource ----------------------------------------------------------------
138 void ParamTraits
<ppapi::HostResource
>::Write(Message
* m
,
139 const param_type
& p
) {
140 ParamTraits
<PP_Instance
>::Write(m
, p
.instance());
141 ParamTraits
<PP_Resource
>::Write(m
, p
.host_resource());
145 bool ParamTraits
<ppapi::HostResource
>::Read(const Message
* m
,
146 PickleIterator
* iter
,
148 PP_Instance instance
;
149 PP_Resource resource
;
150 if (!ParamTraits
<PP_Instance
>::Read(m
, iter
, &instance
) ||
151 !ParamTraits
<PP_Resource
>::Read(m
, iter
, &resource
))
153 r
->SetHostResource(instance
, resource
);
158 void ParamTraits
<ppapi::HostResource
>::Log(const param_type
& p
,
162 // SerializedVar ---------------------------------------------------------------
165 void ParamTraits
<ppapi::proxy::SerializedVar
>::Write(Message
* m
,
166 const param_type
& p
) {
171 bool ParamTraits
<ppapi::proxy::SerializedVar
>::Read(const Message
* m
,
172 PickleIterator
* iter
,
174 return r
->ReadFromMessage(m
, iter
);
178 void ParamTraits
<ppapi::proxy::SerializedVar
>::Log(const param_type
& p
,
182 // std::vector<SerializedVar> --------------------------------------------------
184 void ParamTraits
< std::vector
<ppapi::proxy::SerializedVar
> >::Write(
186 const param_type
& p
) {
187 WriteVectorWithoutCopy(m
, p
);
191 bool ParamTraits
< std::vector
<ppapi::proxy::SerializedVar
> >::Read(
193 PickleIterator
* iter
,
195 return ReadVectorWithoutCopy(m
, iter
, r
);
199 void ParamTraits
< std::vector
<ppapi::proxy::SerializedVar
> >::Log(
204 // ppapi::PpapiPermissions -----------------------------------------------------
206 void ParamTraits
<ppapi::PpapiPermissions
>::Write(Message
* m
,
207 const param_type
& p
) {
208 ParamTraits
<uint32_t>::Write(m
, p
.GetBits());
212 bool ParamTraits
<ppapi::PpapiPermissions
>::Read(const Message
* m
,
213 PickleIterator
* iter
,
216 if (!ParamTraits
<uint32_t>::Read(m
, iter
, &bits
))
218 *r
= ppapi::PpapiPermissions(bits
);
223 void ParamTraits
<ppapi::PpapiPermissions
>::Log(const param_type
& p
,
227 // SerializedHandle ------------------------------------------------------------
230 void ParamTraits
<ppapi::proxy::SerializedHandle
>::Write(Message
* m
,
231 const param_type
& p
) {
232 ppapi::proxy::SerializedHandle::WriteHeader(p
.header(), m
);
234 case ppapi::proxy::SerializedHandle::SHARED_MEMORY
:
235 ParamTraits
<base::SharedMemoryHandle
>::Write(m
, p
.shmem());
237 case ppapi::proxy::SerializedHandle::SOCKET
:
238 case ppapi::proxy::SerializedHandle::CHANNEL_HANDLE
:
239 case ppapi::proxy::SerializedHandle::FILE:
240 ParamTraits
<IPC::PlatformFileForTransit
>::Write(m
, p
.descriptor());
242 case ppapi::proxy::SerializedHandle::INVALID
:
244 // No default so the compiler will warn on new types.
249 bool ParamTraits
<ppapi::proxy::SerializedHandle
>::Read(const Message
* m
,
250 PickleIterator
* iter
,
252 ppapi::proxy::SerializedHandle::Header header
;
253 if (!ppapi::proxy::SerializedHandle::ReadHeader(iter
, &header
))
255 switch (header
.type
) {
256 case ppapi::proxy::SerializedHandle::SHARED_MEMORY
: {
257 base::SharedMemoryHandle handle
;
258 if (ParamTraits
<base::SharedMemoryHandle
>::Read(m
, iter
, &handle
)) {
259 r
->set_shmem(handle
, header
.size
);
264 case ppapi::proxy::SerializedHandle::SOCKET
: {
265 IPC::PlatformFileForTransit socket
;
266 if (ParamTraits
<IPC::PlatformFileForTransit
>::Read(m
, iter
, &socket
)) {
267 r
->set_socket(socket
);
272 case ppapi::proxy::SerializedHandle::CHANNEL_HANDLE
: {
273 IPC::PlatformFileForTransit desc
;
274 if (ParamTraits
<IPC::PlatformFileForTransit
>::Read(m
, iter
, &desc
)) {
275 r
->set_channel_handle(desc
);
280 case ppapi::proxy::SerializedHandle::FILE: {
281 IPC::PlatformFileForTransit desc
;
282 if (ParamTraits
<IPC::PlatformFileForTransit
>::Read(m
, iter
, &desc
)) {
283 r
->set_file_handle(desc
, header
.open_flag
);
288 case ppapi::proxy::SerializedHandle::INVALID
:
290 // No default so the compiler will warn us if a new type is added.
296 void ParamTraits
<ppapi::proxy::SerializedHandle
>::Log(const param_type
& p
,
300 // PPBURLLoader_UpdateProgress_Params ------------------------------------------
303 void ParamTraits
<ppapi::proxy::PPBURLLoader_UpdateProgress_Params
>::Write(
305 const param_type
& p
) {
306 ParamTraits
<PP_Instance
>::Write(m
, p
.instance
);
307 ParamTraits
<ppapi::HostResource
>::Write(m
, p
.resource
);
308 ParamTraits
<int64_t>::Write(m
, p
.bytes_sent
);
309 ParamTraits
<int64_t>::Write(m
, p
.total_bytes_to_be_sent
);
310 ParamTraits
<int64_t>::Write(m
, p
.bytes_received
);
311 ParamTraits
<int64_t>::Write(m
, p
.total_bytes_to_be_received
);
315 bool ParamTraits
<ppapi::proxy::PPBURLLoader_UpdateProgress_Params
>::Read(
317 PickleIterator
* iter
,
320 ParamTraits
<PP_Instance
>::Read(m
, iter
, &r
->instance
) &&
321 ParamTraits
<ppapi::HostResource
>::Read(m
, iter
, &r
->resource
) &&
322 ParamTraits
<int64_t>::Read(m
, iter
, &r
->bytes_sent
) &&
323 ParamTraits
<int64_t>::Read(m
, iter
, &r
->total_bytes_to_be_sent
) &&
324 ParamTraits
<int64_t>::Read(m
, iter
, &r
->bytes_received
) &&
325 ParamTraits
<int64_t>::Read(m
, iter
, &r
->total_bytes_to_be_received
);
329 void ParamTraits
<ppapi::proxy::PPBURLLoader_UpdateProgress_Params
>::Log(
334 #if !defined(OS_NACL) && !defined(NACL_WIN64)
335 // PPBFlash_DrawGlyphs_Params --------------------------------------------------
337 void ParamTraits
<ppapi::proxy::PPBFlash_DrawGlyphs_Params
>::Write(
339 const param_type
& p
) {
340 ParamTraits
<PP_Instance
>::Write(m
, p
.instance
);
341 ParamTraits
<ppapi::HostResource
>::Write(m
, p
.image_data
);
342 ParamTraits
<ppapi::proxy::SerializedFontDescription
>::Write(m
, p
.font_desc
);
343 ParamTraits
<uint32_t>::Write(m
, p
.color
);
344 ParamTraits
<PP_Point
>::Write(m
, p
.position
);
345 ParamTraits
<PP_Rect
>::Write(m
, p
.clip
);
346 ParamTraits
<float>::Write(m
, p
.transformation
[0][0]);
347 ParamTraits
<float>::Write(m
, p
.transformation
[0][1]);
348 ParamTraits
<float>::Write(m
, p
.transformation
[0][2]);
349 ParamTraits
<float>::Write(m
, p
.transformation
[1][0]);
350 ParamTraits
<float>::Write(m
, p
.transformation
[1][1]);
351 ParamTraits
<float>::Write(m
, p
.transformation
[1][2]);
352 ParamTraits
<float>::Write(m
, p
.transformation
[2][0]);
353 ParamTraits
<float>::Write(m
, p
.transformation
[2][1]);
354 ParamTraits
<float>::Write(m
, p
.transformation
[2][2]);
355 ParamTraits
<PP_Bool
>::Write(m
, p
.allow_subpixel_aa
);
356 ParamTraits
<std::vector
<uint16_t> >::Write(m
, p
.glyph_indices
);
357 ParamTraits
<std::vector
<PP_Point
> >::Write(m
, p
.glyph_advances
);
361 bool ParamTraits
<ppapi::proxy::PPBFlash_DrawGlyphs_Params
>::Read(
363 PickleIterator
* iter
,
366 ParamTraits
<PP_Instance
>::Read(m
, iter
, &r
->instance
) &&
367 ParamTraits
<ppapi::HostResource
>::Read(m
, iter
, &r
->image_data
) &&
368 ParamTraits
<ppapi::proxy::SerializedFontDescription
>::Read(m
, iter
,
370 ParamTraits
<uint32_t>::Read(m
, iter
, &r
->color
) &&
371 ParamTraits
<PP_Point
>::Read(m
, iter
, &r
->position
) &&
372 ParamTraits
<PP_Rect
>::Read(m
, iter
, &r
->clip
) &&
373 ParamTraits
<float>::Read(m
, iter
, &r
->transformation
[0][0]) &&
374 ParamTraits
<float>::Read(m
, iter
, &r
->transformation
[0][1]) &&
375 ParamTraits
<float>::Read(m
, iter
, &r
->transformation
[0][2]) &&
376 ParamTraits
<float>::Read(m
, iter
, &r
->transformation
[1][0]) &&
377 ParamTraits
<float>::Read(m
, iter
, &r
->transformation
[1][1]) &&
378 ParamTraits
<float>::Read(m
, iter
, &r
->transformation
[1][2]) &&
379 ParamTraits
<float>::Read(m
, iter
, &r
->transformation
[2][0]) &&
380 ParamTraits
<float>::Read(m
, iter
, &r
->transformation
[2][1]) &&
381 ParamTraits
<float>::Read(m
, iter
, &r
->transformation
[2][2]) &&
382 ParamTraits
<PP_Bool
>::Read(m
, iter
, &r
->allow_subpixel_aa
) &&
383 ParamTraits
<std::vector
<uint16_t> >::Read(m
, iter
, &r
->glyph_indices
) &&
384 ParamTraits
<std::vector
<PP_Point
> >::Read(m
, iter
, &r
->glyph_advances
) &&
385 r
->glyph_indices
.size() == r
->glyph_advances
.size();
389 void ParamTraits
<ppapi::proxy::PPBFlash_DrawGlyphs_Params
>::Log(
394 // SerializedDirEntry ----------------------------------------------------------
397 void ParamTraits
<ppapi::proxy::SerializedDirEntry
>::Write(Message
* m
,
398 const param_type
& p
) {
399 ParamTraits
<std::string
>::Write(m
, p
.name
);
400 ParamTraits
<bool>::Write(m
, p
.is_dir
);
404 bool ParamTraits
<ppapi::proxy::SerializedDirEntry
>::Read(const Message
* m
,
405 PickleIterator
* iter
,
407 return ParamTraits
<std::string
>::Read(m
, iter
, &r
->name
) &&
408 ParamTraits
<bool>::Read(m
, iter
, &r
->is_dir
);
412 void ParamTraits
<ppapi::proxy::SerializedDirEntry
>::Log(const param_type
& p
,
416 // ppapi::proxy::SerializedFontDescription -------------------------------------
419 void ParamTraits
<ppapi::proxy::SerializedFontDescription
>::Write(
421 const param_type
& p
) {
422 ParamTraits
<std::string
>::Write(m
, p
.face
);
423 ParamTraits
<int32_t>::Write(m
, p
.family
);
424 ParamTraits
<uint32_t>::Write(m
, p
.size
);
425 ParamTraits
<int32_t>::Write(m
, p
.weight
);
426 ParamTraits
<PP_Bool
>::Write(m
, p
.italic
);
427 ParamTraits
<PP_Bool
>::Write(m
, p
.small_caps
);
428 ParamTraits
<int32_t>::Write(m
, p
.letter_spacing
);
429 ParamTraits
<int32_t>::Write(m
, p
.word_spacing
);
433 bool ParamTraits
<ppapi::proxy::SerializedFontDescription
>::Read(
435 PickleIterator
* iter
,
438 ParamTraits
<std::string
>::Read(m
, iter
, &r
->face
) &&
439 ParamTraits
<int32_t>::Read(m
, iter
, &r
->family
) &&
440 ParamTraits
<uint32_t>::Read(m
, iter
, &r
->size
) &&
441 ParamTraits
<int32_t>::Read(m
, iter
, &r
->weight
) &&
442 ParamTraits
<PP_Bool
>::Read(m
, iter
, &r
->italic
) &&
443 ParamTraits
<PP_Bool
>::Read(m
, iter
, &r
->small_caps
) &&
444 ParamTraits
<int32_t>::Read(m
, iter
, &r
->letter_spacing
) &&
445 ParamTraits
<int32_t>::Read(m
, iter
, &r
->word_spacing
);
449 void ParamTraits
<ppapi::proxy::SerializedFontDescription
>::Log(
453 #endif // !defined(OS_NACL) && !defined(NACL_WIN64)
455 // ppapi::proxy::SerializedTrueTypeFontDesc ------------------------------------
458 void ParamTraits
<ppapi::proxy::SerializedTrueTypeFontDesc
>::Write(
460 const param_type
& p
) {
461 ParamTraits
<std::string
>::Write(m
, p
.family
);
462 ParamTraits
<PP_TrueTypeFontFamily_Dev
>::Write(m
, p
.generic_family
);
463 ParamTraits
<PP_TrueTypeFontStyle_Dev
>::Write(m
, p
.style
);
464 ParamTraits
<PP_TrueTypeFontWeight_Dev
>::Write(m
, p
.weight
);
465 ParamTraits
<PP_TrueTypeFontWidth_Dev
>::Write(m
, p
.width
);
466 ParamTraits
<PP_TrueTypeFontCharset_Dev
>::Write(m
, p
.charset
);
470 bool ParamTraits
<ppapi::proxy::SerializedTrueTypeFontDesc
>::Read(
472 PickleIterator
* iter
,
475 ParamTraits
<std::string
>::Read(m
, iter
, &r
->family
) &&
476 ParamTraits
<PP_TrueTypeFontFamily_Dev
>::Read(m
, iter
,
477 &r
->generic_family
) &&
478 ParamTraits
<PP_TrueTypeFontStyle_Dev
>::Read(m
, iter
, &r
->style
) &&
479 ParamTraits
<PP_TrueTypeFontWeight_Dev
>::Read(m
, iter
, &r
->weight
) &&
480 ParamTraits
<PP_TrueTypeFontWidth_Dev
>::Read(m
, iter
, &r
->width
) &&
481 ParamTraits
<PP_TrueTypeFontCharset_Dev
>::Read(m
, iter
, &r
->charset
);
485 void ParamTraits
<ppapi::proxy::SerializedTrueTypeFontDesc
>::Log(
490 #if !defined(OS_NACL) && !defined(NACL_WIN64)
491 // ppapi::PepperFilePath -------------------------------------------------------
494 void ParamTraits
<ppapi::PepperFilePath
>::Write(Message
* m
,
495 const param_type
& p
) {
496 WriteParam(m
, static_cast<unsigned>(p
.domain()));
497 WriteParam(m
, p
.path());
501 bool ParamTraits
<ppapi::PepperFilePath
>::Read(const Message
* m
,
502 PickleIterator
* iter
,
506 if (!ReadParam(m
, iter
, &domain
) || !ReadParam(m
, iter
, &path
))
508 if (domain
> ppapi::PepperFilePath::DOMAIN_MAX_VALID
)
511 *p
= ppapi::PepperFilePath(
512 static_cast<ppapi::PepperFilePath::Domain
>(domain
), path
);
517 void ParamTraits
<ppapi::PepperFilePath
>::Log(const param_type
& p
,
520 LogParam(static_cast<unsigned>(p
.domain()), l
);
522 LogParam(p
.path(), l
);
526 // SerializedFlashMenu ---------------------------------------------------------
529 void ParamTraits
<ppapi::proxy::SerializedFlashMenu
>::Write(
531 const param_type
& p
) {
536 bool ParamTraits
<ppapi::proxy::SerializedFlashMenu
>::Read(const Message
* m
,
537 PickleIterator
* iter
,
539 return r
->ReadFromMessage(m
, iter
);
543 void ParamTraits
<ppapi::proxy::SerializedFlashMenu
>::Log(const param_type
& p
,
546 #endif // !defined(OS_NACL) && !defined(NACL_WIN64)
548 // PPB_X509Certificate_Fields --------------------------------------------------
551 void ParamTraits
<ppapi::PPB_X509Certificate_Fields
>::Write(
553 const param_type
& p
) {
554 ParamTraits
<base::ListValue
>::Write(m
, p
.values_
);
558 bool ParamTraits
<ppapi::PPB_X509Certificate_Fields
>::Read(const Message
* m
,
559 PickleIterator
* iter
,
561 return ParamTraits
<base::ListValue
>::Read(m
, iter
, &(r
->values_
));
565 void ParamTraits
<ppapi::PPB_X509Certificate_Fields
>::Log(const param_type
& p
,
569 // ppapi::SocketOptionData -----------------------------------------------------
572 void ParamTraits
<ppapi::SocketOptionData
>::Write(Message
* m
,
573 const param_type
& p
) {
574 ppapi::SocketOptionData::Type type
= p
.GetType();
575 ParamTraits
<int32_t>::Write(m
, static_cast<int32_t>(type
));
577 case ppapi::SocketOptionData::TYPE_INVALID
: {
580 case ppapi::SocketOptionData::TYPE_BOOL
: {
581 bool out_value
= false;
582 bool result
= p
.GetBool(&out_value
);
583 // Suppress unused variable warnings.
584 static_cast<void>(result
);
587 ParamTraits
<bool>::Write(m
, out_value
);
590 case ppapi::SocketOptionData::TYPE_INT32
: {
591 int32_t out_value
= 0;
592 bool result
= p
.GetInt32(&out_value
);
593 // Suppress unused variable warnings.
594 static_cast<void>(result
);
597 ParamTraits
<int32_t>::Write(m
, out_value
);
600 // No default so the compiler will warn on new types.
605 bool ParamTraits
<ppapi::SocketOptionData
>::Read(const Message
* m
,
606 PickleIterator
* iter
,
608 *r
= ppapi::SocketOptionData();
610 if (!ParamTraits
<int32_t>::Read(m
, iter
, &type
))
612 if (type
!= ppapi::SocketOptionData::TYPE_INVALID
&&
613 type
!= ppapi::SocketOptionData::TYPE_BOOL
&&
614 type
!= ppapi::SocketOptionData::TYPE_INT32
) {
617 switch (static_cast<ppapi::SocketOptionData::Type
>(type
)) {
618 case ppapi::SocketOptionData::TYPE_INVALID
: {
621 case ppapi::SocketOptionData::TYPE_BOOL
: {
623 if (!ParamTraits
<bool>::Read(m
, iter
, &value
))
628 case ppapi::SocketOptionData::TYPE_INT32
: {
630 if (!ParamTraits
<int32_t>::Read(m
, iter
, &value
))
635 // No default so the compiler will warn on new types.
641 void ParamTraits
<ppapi::SocketOptionData
>::Log(const param_type
& p
,