1/*
2 * Copyright (C) 2010-2017 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#include "Decoder.h"
29#include "Encoder.h"
30#include <utility>
31#include <wtf/Forward.h>
32#include <wtf/MonotonicTime.h>
33#include <wtf/SHA1.h>
34#include <wtf/WallTime.h>
35
36namespace IPC {
37
38// An argument coder works on POD types
39template<typename T> struct SimpleArgumentCoder {
40 static void encode(Encoder& encoder, const T& t)
41 {
42 encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(&t), sizeof(T), alignof(T));
43 }
44
45 static bool decode(Decoder& decoder, T& t)
46 {
47 return decoder.decodeFixedLengthData(reinterpret_cast<uint8_t*>(&t), sizeof(T), alignof(T));
48 }
49};
50
51template<typename T> struct ArgumentCoder<OptionSet<T>> {
52 static void encode(Encoder& encoder, const OptionSet<T>& optionSet)
53 {
54 encoder << (static_cast<uint64_t>(optionSet.toRaw()));
55 }
56
57 static bool decode(Decoder& decoder, OptionSet<T>& optionSet)
58 {
59 uint64_t value;
60 if (!decoder.decode(value))
61 return false;
62
63 optionSet = OptionSet<T>::fromRaw(value);
64 return true;
65 }
66
67 static Optional<OptionSet<T>> decode(Decoder& decoder)
68 {
69 Optional<uint64_t> value;
70 decoder >> value;
71 if (!value)
72 return WTF::nullopt;
73 return OptionSet<T>::fromRaw(*value);
74 }
75};
76
77template<typename T> struct ArgumentCoder<Optional<T>> {
78 static void encode(Encoder& encoder, const Optional<T>& optional)
79 {
80 if (!optional) {
81 encoder << false;
82 return;
83 }
84
85 encoder << true;
86 encoder << optional.value();
87 }
88
89 static bool decode(Decoder& decoder, Optional<T>& optional)
90 {
91 bool isEngaged;
92 if (!decoder.decode(isEngaged))
93 return false;
94
95 if (!isEngaged) {
96 optional = WTF::nullopt;
97 return true;
98 }
99
100 T value;
101 if (!decoder.decode(value))
102 return false;
103
104 optional = WTFMove(value);
105 return true;
106 }
107
108 static Optional<Optional<T>> decode(Decoder& decoder)
109 {
110 Optional<bool> isEngaged;
111 decoder >> isEngaged;
112 if (!isEngaged)
113 return WTF::nullopt;
114 if (*isEngaged) {
115 Optional<T> value;
116 decoder >> value;
117 if (!value)
118 return WTF::nullopt;
119 return Optional<Optional<T>>(WTFMove(*value));
120 }
121 return Optional<Optional<T>>(Optional<T>(WTF::nullopt));
122 }
123};
124
125template<typename T, typename U> struct ArgumentCoder<std::pair<T, U>> {
126 static void encode(Encoder& encoder, const std::pair<T, U>& pair)
127 {
128 encoder << pair.first << pair.second;
129 }
130
131 static bool decode(Decoder& decoder, std::pair<T, U>& pair)
132 {
133 T first;
134 if (!decoder.decode(first))
135 return false;
136
137 U second;
138 if (!decoder.decode(second))
139 return false;
140
141 pair.first = first;
142 pair.second = second;
143 return true;
144 }
145
146 static Optional<std::pair<T, U>> decode(Decoder& decoder)
147 {
148 Optional<T> first;
149 decoder >> first;
150 if (!first)
151 return WTF::nullopt;
152
153 Optional<U> second;
154 decoder >> second;
155 if (!second)
156 return WTF::nullopt;
157
158 return {{ WTFMove(*first), WTFMove(*second) }};
159 }
160};
161
162template<size_t index, typename... Elements>
163struct TupleEncoder {
164 static void encode(Encoder& encoder, const std::tuple<Elements...>& tuple)
165 {
166 encoder << std::get<sizeof...(Elements) - index>(tuple);
167 TupleEncoder<index - 1, Elements...>::encode(encoder, tuple);
168 }
169};
170
171template<typename... Elements>
172struct TupleEncoder<0, Elements...> {
173 static void encode(Encoder&, const std::tuple<Elements...>&)
174 {
175 }
176};
177
178template <typename T, typename... Elements, size_t... Indices>
179auto tupleFromTupleAndObject(T&& object, std::tuple<Elements...>&& tuple, std::index_sequence<Indices...>)
180{
181 return std::make_tuple(WTFMove(object), WTFMove(std::get<Indices>(tuple))...);
182}
183
184template <typename T, typename... Elements>
185auto tupleFromTupleAndObject(T&& object, std::tuple<Elements...>&& tuple)
186{
187 return tupleFromTupleAndObject(WTFMove(object), WTFMove(tuple), std::index_sequence_for<Elements...>());
188}
189
190template<typename Type, typename... Types>
191struct TupleDecoderImpl {
192 static Optional<std::tuple<Type, Types...>> decode(Decoder& decoder)
193 {
194 Optional<Type> optional;
195 decoder >> optional;
196 if (!optional)
197 return WTF::nullopt;
198
199 Optional<std::tuple<Types...>> subTuple = TupleDecoderImpl<Types...>::decode(decoder);
200 if (!subTuple)
201 return WTF::nullopt;
202
203 return tupleFromTupleAndObject(WTFMove(*optional), WTFMove(*subTuple));
204 }
205};
206
207template<typename Type>
208struct TupleDecoderImpl<Type> {
209 static Optional<std::tuple<Type>> decode(Decoder& decoder)
210 {
211 Optional<Type> optional;
212 decoder >> optional;
213 if (!optional)
214 return WTF::nullopt;
215 return std::make_tuple(WTFMove(*optional));
216 }
217};
218
219template<size_t size, typename... Elements>
220struct TupleDecoder {
221 static Optional<std::tuple<Elements...>> decode(Decoder& decoder)
222 {
223 return TupleDecoderImpl<Elements...>::decode(decoder);
224 }
225};
226
227template<>
228struct TupleDecoder<0> {
229 static Optional<std::tuple<>> decode(Decoder& decoder)
230 {
231 return std::make_tuple();
232 }
233};
234
235template<typename... Elements> struct ArgumentCoder<std::tuple<Elements...>> {
236 static void encode(Encoder& encoder, const std::tuple<Elements...>& tuple)
237 {
238 TupleEncoder<sizeof...(Elements), Elements...>::encode(encoder, tuple);
239 }
240
241 static Optional<std::tuple<Elements...>> decode(Decoder& decoder)
242 {
243 return TupleDecoder<sizeof...(Elements), Elements...>::decode(decoder);
244 }
245};
246
247template<typename KeyType, typename ValueType> struct ArgumentCoder<WTF::KeyValuePair<KeyType, ValueType>> {
248 static void encode(Encoder& encoder, const WTF::KeyValuePair<KeyType, ValueType>& pair)
249 {
250 encoder << pair.key << pair.value;
251 }
252
253 static bool decode(Decoder& decoder, WTF::KeyValuePair<KeyType, ValueType>& pair)
254 {
255 KeyType key;
256 if (!decoder.decode(key))
257 return false;
258
259 ValueType value;
260 if (!decoder.decode(value))
261 return false;
262
263 pair.key = key;
264 pair.value = value;
265 return true;
266 }
267};
268
269template<bool fixedSizeElements, typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity> struct VectorArgumentCoder;
270
271template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity> struct VectorArgumentCoder<false, T, inlineCapacity, OverflowHandler, minCapacity> {
272 static void encode(Encoder& encoder, const Vector<T, inlineCapacity, OverflowHandler, minCapacity>& vector)
273 {
274 encoder << static_cast<uint64_t>(vector.size());
275 for (size_t i = 0; i < vector.size(); ++i)
276 encoder << vector[i];
277 }
278
279 static bool decode(Decoder& decoder, Vector<T, inlineCapacity, OverflowHandler, minCapacity>& vector)
280 {
281 Optional<Vector<T, inlineCapacity, OverflowHandler, minCapacity>> optional;
282 decoder >> optional;
283 if (!optional)
284 return false;
285 vector = WTFMove(*optional);
286 return true;
287 }
288
289 static Optional<Vector<T, inlineCapacity, OverflowHandler, minCapacity>> decode(Decoder& decoder)
290 {
291 uint64_t size;
292 if (!decoder.decode(size))
293 return WTF::nullopt;
294
295 Vector<T, inlineCapacity, OverflowHandler, minCapacity> vector;
296 for (size_t i = 0; i < size; ++i) {
297 Optional<T> element;
298 decoder >> element;
299 if (!element)
300 return WTF::nullopt;
301 vector.append(WTFMove(*element));
302 }
303 vector.shrinkToFit();
304 return vector;
305 }
306};
307
308template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity> struct VectorArgumentCoder<true, T, inlineCapacity, OverflowHandler, minCapacity> {
309 static void encode(Encoder& encoder, const Vector<T, inlineCapacity, OverflowHandler, minCapacity>& vector)
310 {
311 encoder << static_cast<uint64_t>(vector.size());
312 encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(vector.data()), vector.size() * sizeof(T), alignof(T));
313 }
314
315 static bool decode(Decoder& decoder, Vector<T, inlineCapacity, OverflowHandler, minCapacity>& vector)
316 {
317 uint64_t size;
318 if (!decoder.decode(size))
319 return false;
320
321 // Since we know the total size of the elements, we can allocate the vector in
322 // one fell swoop. Before allocating we must however make sure that the decoder buffer
323 // is big enough.
324 if (!decoder.bufferIsLargeEnoughToContain<T>(size)) {
325 decoder.markInvalid();
326 return false;
327 }
328
329 Vector<T, inlineCapacity, OverflowHandler, minCapacity> temp;
330 temp.grow(size);
331
332 decoder.decodeFixedLengthData(reinterpret_cast<uint8_t*>(temp.data()), size * sizeof(T), alignof(T));
333
334 vector.swap(temp);
335 return true;
336 }
337
338 static Optional<Vector<T, inlineCapacity, OverflowHandler, minCapacity>> decode(Decoder& decoder)
339 {
340 uint64_t size;
341 if (!decoder.decode(size))
342 return WTF::nullopt;
343
344 // Since we know the total size of the elements, we can allocate the vector in
345 // one fell swoop. Before allocating we must however make sure that the decoder buffer
346 // is big enough.
347 if (!decoder.bufferIsLargeEnoughToContain<T>(size)) {
348 decoder.markInvalid();
349 return WTF::nullopt;
350 }
351
352 Vector<T, inlineCapacity, OverflowHandler, minCapacity> vector;
353 vector.grow(size);
354
355 decoder.decodeFixedLengthData(reinterpret_cast<uint8_t*>(vector.data()), size * sizeof(T), alignof(T));
356
357 return vector;
358 }
359};
360
361template<typename T, size_t inlineCapacity, typename OverflowHandler, size_t minCapacity> struct ArgumentCoder<Vector<T, inlineCapacity, OverflowHandler, minCapacity>> : VectorArgumentCoder<std::is_arithmetic<T>::value, T, inlineCapacity, OverflowHandler, minCapacity> { };
362
363template<typename KeyArg, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg> struct ArgumentCoder<HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>> {
364 typedef HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> HashMapType;
365
366 static void encode(Encoder& encoder, const HashMapType& hashMap)
367 {
368 encoder << static_cast<uint64_t>(hashMap.size());
369 for (typename HashMapType::const_iterator it = hashMap.begin(), end = hashMap.end(); it != end; ++it)
370 encoder << *it;
371 }
372
373 static bool decode(Decoder& decoder, HashMapType& hashMap)
374 {
375 uint64_t hashMapSize;
376 if (!decoder.decode(hashMapSize))
377 return false;
378
379 HashMapType tempHashMap;
380 for (uint64_t i = 0; i < hashMapSize; ++i) {
381 KeyArg key;
382 MappedArg value;
383 if (!decoder.decode(key))
384 return false;
385 if (!decoder.decode(value))
386 return false;
387
388 if (!tempHashMap.add(key, value).isNewEntry) {
389 // The hash map already has the specified key, bail.
390 decoder.markInvalid();
391 return false;
392 }
393 }
394
395 hashMap.swap(tempHashMap);
396 return true;
397 }
398
399 static Optional<HashMapType> decode(Decoder& decoder)
400 {
401 uint64_t hashMapSize;
402 if (!decoder.decode(hashMapSize))
403 return WTF::nullopt;
404
405 HashMapType hashMap;
406 for (uint64_t i = 0; i < hashMapSize; ++i) {
407 Optional<KeyArg> key;
408 decoder >> key;
409 if (!key)
410 return WTF::nullopt;
411
412 Optional<MappedArg> value;
413 decoder >> value;
414 if (!value)
415 return WTF::nullopt;
416
417 if (!hashMap.add(WTFMove(key.value()), WTFMove(value.value())).isNewEntry) {
418 // The hash map already has the specified key, bail.
419 decoder.markInvalid();
420 return WTF::nullopt;
421 }
422 }
423
424 return hashMap;
425 }
426};
427
428template<typename KeyArg, typename HashArg, typename KeyTraitsArg> struct ArgumentCoder<HashSet<KeyArg, HashArg, KeyTraitsArg>> {
429 typedef HashSet<KeyArg, HashArg, KeyTraitsArg> HashSetType;
430
431 static void encode(Encoder& encoder, const HashSetType& hashSet)
432 {
433 encoder << static_cast<uint64_t>(hashSet.size());
434 for (typename HashSetType::const_iterator it = hashSet.begin(), end = hashSet.end(); it != end; ++it)
435 encoder << *it;
436 }
437
438 static bool decode(Decoder& decoder, HashSetType& hashSet)
439 {
440 Optional<HashSetType> tempHashSet;
441 decoder >> tempHashSet;
442 if (!tempHashSet)
443 return false;
444
445 hashSet.swap(tempHashSet.value());
446 return true;
447 }
448
449 static Optional<HashSetType> decode(Decoder& decoder)
450 {
451 uint64_t hashSetSize;
452 if (!decoder.decode(hashSetSize))
453 return WTF::nullopt;
454
455 HashSetType hashSet;
456 for (uint64_t i = 0; i < hashSetSize; ++i) {
457 Optional<KeyArg> key;
458 decoder >> key;
459 if (!key)
460 return WTF::nullopt;
461
462 if (!hashSet.add(WTFMove(key.value())).isNewEntry) {
463 // The hash set already has the specified key, bail.
464 decoder.markInvalid();
465 return WTF::nullopt;
466 }
467 }
468
469 return hashSet;
470 }
471};
472
473template<typename KeyArg, typename HashArg, typename KeyTraitsArg> struct ArgumentCoder<HashCountedSet<KeyArg, HashArg, KeyTraitsArg>> {
474 typedef HashCountedSet<KeyArg, HashArg, KeyTraitsArg> HashCountedSetType;
475
476 static void encode(Encoder& encoder, const HashCountedSetType& hashCountedSet)
477 {
478 encoder << static_cast<uint64_t>(hashCountedSet.size());
479
480 for (auto entry : hashCountedSet) {
481 encoder << entry.key;
482 encoder << entry.value;
483 }
484 }
485
486 static bool decode(Decoder& decoder, HashCountedSetType& hashCountedSet)
487 {
488 uint64_t hashCountedSetSize;
489 if (!decoder.decode(hashCountedSetSize))
490 return false;
491
492 HashCountedSetType tempHashCountedSet;
493 for (uint64_t i = 0; i < hashCountedSetSize; ++i) {
494 KeyArg key;
495 if (!decoder.decode(key))
496 return false;
497
498 unsigned count;
499 if (!decoder.decode(count))
500 return false;
501
502 if (!tempHashCountedSet.add(key, count).isNewEntry) {
503 // The hash counted set already has the specified key, bail.
504 decoder.markInvalid();
505 return false;
506 }
507 }
508
509 hashCountedSet.swap(tempHashCountedSet);
510 return true;
511 }
512};
513
514template<typename ValueType, typename ErrorType> struct ArgumentCoder<Expected<ValueType, ErrorType>> {
515 static void encode(Encoder& encoder, const Expected<ValueType, ErrorType>& expected)
516 {
517 if (!expected.has_value()) {
518 encoder << false;
519 encoder << expected.error();
520 return;
521 }
522 encoder << true;
523 encoder << expected.value();
524 }
525
526 static Optional<Expected<ValueType, ErrorType>> decode(Decoder& decoder)
527 {
528 Optional<bool> hasValue;
529 decoder >> hasValue;
530 if (!hasValue)
531 return WTF::nullopt;
532
533 if (*hasValue) {
534 Optional<ValueType> value;
535 decoder >> value;
536 if (!value)
537 return WTF::nullopt;
538
539 Expected<ValueType, ErrorType> expected(WTFMove(*value));
540 return expected;
541 }
542 Optional<ErrorType> error;
543 decoder >> error;
544 if (!error)
545 return WTF::nullopt;
546 return { makeUnexpected(WTFMove(*error)) };
547 }
548};
549
550template<size_t index, typename... Types>
551struct VariantCoder {
552 static void encode(Encoder& encoder, const WTF::Variant<Types...>& variant, unsigned i)
553 {
554 if (i == index) {
555 encoder << WTF::get<index>(variant);
556 return;
557 }
558 VariantCoder<index - 1, Types...>::encode(encoder, variant, i);
559 }
560
561 static Optional<WTF::Variant<Types...>> decode(Decoder& decoder, unsigned i)
562 {
563 if (i == index) {
564 Optional<typename WTF::variant_alternative<index, WTF::Variant<Types...>>::type> optional;
565 decoder >> optional;
566 if (!optional)
567 return WTF::nullopt;
568 return { WTFMove(*optional) };
569 }
570 return VariantCoder<index - 1, Types...>::decode(decoder, i);
571 }
572};
573
574template<typename... Types>
575struct VariantCoder<0, Types...> {
576 static void encode(Encoder& encoder, const WTF::Variant<Types...>& variant, unsigned i)
577 {
578 ASSERT_UNUSED(i, !i);
579 encoder << WTF::get<0>(variant);
580 }
581
582 static Optional<WTF::Variant<Types...>> decode(Decoder& decoder, unsigned i)
583 {
584 ASSERT_UNUSED(i, !i);
585 Optional<typename WTF::variant_alternative<0, WTF::Variant<Types...>>::type> optional;
586 decoder >> optional;
587 if (!optional)
588 return WTF::nullopt;
589 return { WTFMove(*optional) };
590 }
591};
592
593template<typename... Types> struct ArgumentCoder<WTF::Variant<Types...>> {
594 static void encode(Encoder& encoder, const WTF::Variant<Types...>& variant)
595 {
596 unsigned i = variant.index();
597 encoder << i;
598 VariantCoder<sizeof...(Types) - 1, Types...>::encode(encoder, variant, i);
599 }
600
601 static Optional<WTF::Variant<Types...>> decode(Decoder& decoder)
602 {
603 Optional<unsigned> i;
604 decoder >> i;
605 if (!i)
606 return WTF::nullopt;
607 return VariantCoder<sizeof...(Types) - 1, Types...>::decode(decoder, *i);
608 }
609};
610
611template<> struct ArgumentCoder<WallTime> {
612 static void encode(Encoder&, const WallTime&);
613 static bool decode(Decoder&, WallTime&);
614 static Optional<WallTime> decode(Decoder&);
615};
616
617template<> struct ArgumentCoder<AtomicString> {
618 static void encode(Encoder&, const AtomicString&);
619 static bool decode(Decoder&, AtomicString&);
620};
621
622template<> struct ArgumentCoder<CString> {
623 static void encode(Encoder&, const CString&);
624 static bool decode(Decoder&, CString&);
625};
626
627template<> struct ArgumentCoder<String> {
628 static void encode(Encoder&, const String&);
629 static bool decode(Decoder&, String&);
630 static Optional<String> decode(Decoder&);
631};
632
633template<> struct ArgumentCoder<SHA1::Digest> {
634 static void encode(Encoder&, const SHA1::Digest&);
635 static bool decode(Decoder&, SHA1::Digest&);
636};
637
638} // namespace IPC
639