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