1/*
2 * Copyright (C) 2014 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#include "config.h"
27#include "SessionState.h"
28
29#include "WebCoreArgumentCoders.h"
30#include <WebCore/BackForwardItemIdentifier.h>
31
32namespace WebKit {
33using namespace WebCore;
34
35bool isValidEnum(WebCore::ShouldOpenExternalURLsPolicy policy)
36{
37 switch (policy) {
38 case WebCore::ShouldOpenExternalURLsPolicy::ShouldAllow:
39 case WebCore::ShouldOpenExternalURLsPolicy::ShouldAllowExternalSchemes:
40 case WebCore::ShouldOpenExternalURLsPolicy::ShouldNotAllow:
41 return true;
42 }
43 return false;
44}
45
46void HTTPBody::Element::encode(IPC::Encoder& encoder) const
47{
48 encoder.encodeEnum(type);
49 encoder << data;
50 encoder << filePath;
51 encoder << fileStart;
52 encoder << fileLength;
53 encoder << expectedFileModificationTime;
54 encoder << blobURLString;
55}
56
57static bool isValidEnum(HTTPBody::Element::Type type)
58{
59 switch (type) {
60 case HTTPBody::Element::Type::Data:
61 case HTTPBody::Element::Type::File:
62 case HTTPBody::Element::Type::Blob:
63 return true;
64 }
65
66 return false;
67}
68
69auto HTTPBody::Element::decode(IPC::Decoder& decoder) -> Optional<Element>
70{
71 Element result;
72 if (!decoder.decodeEnum(result.type) || !isValidEnum(result.type))
73 return WTF::nullopt;
74 if (!decoder.decode(result.data))
75 return WTF::nullopt;
76 if (!decoder.decode(result.filePath))
77 return WTF::nullopt;
78 if (!decoder.decode(result.fileStart))
79 return WTF::nullopt;
80 if (!decoder.decode(result.fileLength))
81 return WTF::nullopt;
82 if (!decoder.decode(result.expectedFileModificationTime))
83 return WTF::nullopt;
84 if (!decoder.decode(result.blobURLString))
85 return WTF::nullopt;
86
87 return result;
88}
89
90void HTTPBody::encode(IPC::Encoder& encoder) const
91{
92 encoder << contentType;
93 encoder << elements;
94}
95
96bool HTTPBody::decode(IPC::Decoder& decoder, HTTPBody& result)
97{
98 if (!decoder.decode(result.contentType))
99 return false;
100 if (!decoder.decode(result.elements))
101 return false;
102
103 return true;
104}
105
106void FrameState::encode(IPC::Encoder& encoder) const
107{
108 encoder << urlString;
109 encoder << originalURLString;
110 encoder << referrer;
111 encoder << target;
112
113 encoder << documentState;
114 encoder << stateObjectData;
115
116 encoder << documentSequenceNumber;
117 encoder << itemSequenceNumber;
118
119 encoder << scrollPosition;
120 encoder << shouldRestoreScrollPosition;
121 encoder << pageScaleFactor;
122
123 encoder << httpBody;
124
125#if PLATFORM(IOS_FAMILY)
126 encoder << exposedContentRect;
127 encoder << unobscuredContentRect;
128 encoder << minimumLayoutSizeInScrollViewCoordinates;
129 encoder << contentSize;
130 encoder << scaleIsInitial;
131 encoder << obscuredInsets;
132#endif
133
134 encoder << children;
135}
136
137Optional<FrameState> FrameState::decode(IPC::Decoder& decoder)
138{
139 FrameState result;
140 if (!decoder.decode(result.urlString))
141 return WTF::nullopt;
142 if (!decoder.decode(result.originalURLString))
143 return WTF::nullopt;
144 if (!decoder.decode(result.referrer))
145 return WTF::nullopt;
146 if (!decoder.decode(result.target))
147 return WTF::nullopt;
148
149 if (!decoder.decode(result.documentState))
150 return WTF::nullopt;
151 if (!decoder.decode(result.stateObjectData))
152 return WTF::nullopt;
153
154 if (!decoder.decode(result.documentSequenceNumber))
155 return WTF::nullopt;
156 if (!decoder.decode(result.itemSequenceNumber))
157 return WTF::nullopt;
158
159 if (!decoder.decode(result.scrollPosition))
160 return WTF::nullopt;
161 if (!decoder.decode(result.shouldRestoreScrollPosition))
162 return WTF::nullopt;
163 if (!decoder.decode(result.pageScaleFactor))
164 return WTF::nullopt;
165
166 if (!decoder.decode(result.httpBody))
167 return WTF::nullopt;
168
169#if PLATFORM(IOS_FAMILY)
170 if (!decoder.decode(result.exposedContentRect))
171 return WTF::nullopt;
172 if (!decoder.decode(result.unobscuredContentRect))
173 return WTF::nullopt;
174 if (!decoder.decode(result.minimumLayoutSizeInScrollViewCoordinates))
175 return WTF::nullopt;
176 if (!decoder.decode(result.contentSize))
177 return WTF::nullopt;
178 if (!decoder.decode(result.scaleIsInitial))
179 return WTF::nullopt;
180 if (!decoder.decode(result.obscuredInsets))
181 return WTF::nullopt;
182#endif
183
184 if (!decoder.decode(result.children))
185 return WTF::nullopt;
186
187 return result;
188}
189
190void PageState::encode(IPC::Encoder& encoder) const
191{
192 encoder << title << mainFrameState << !!sessionStateObject;
193
194 if (sessionStateObject)
195 encoder << sessionStateObject->toWireBytes();
196
197 encoder.encodeEnum(shouldOpenExternalURLsPolicy);
198}
199
200bool PageState::decode(IPC::Decoder& decoder, PageState& result)
201{
202 if (!decoder.decode(result.title))
203 return false;
204 Optional<FrameState> mainFrameState;
205 decoder >> mainFrameState;
206 if (!mainFrameState)
207 return false;
208 result.mainFrameState = WTFMove(*mainFrameState);
209
210 bool hasSessionState;
211 if (!decoder.decode(hasSessionState))
212 return false;
213
214 if (hasSessionState) {
215 Vector<uint8_t> wireBytes;
216 if (!decoder.decode(wireBytes))
217 return false;
218
219 result.sessionStateObject = SerializedScriptValue::createFromWireBytes(WTFMove(wireBytes));
220 }
221
222 if (!decoder.decodeEnum(result.shouldOpenExternalURLsPolicy) || !isValidEnum(result.shouldOpenExternalURLsPolicy))
223 return false;
224
225 return true;
226}
227
228void BackForwardListItemState::encode(IPC::Encoder& encoder) const
229{
230 encoder << identifier;
231 encoder << pageState;
232}
233
234Optional<BackForwardListItemState> BackForwardListItemState::decode(IPC::Decoder& decoder)
235{
236 BackForwardListItemState result;
237
238 auto identifier = BackForwardItemIdentifier::decode(decoder);
239 if (!identifier)
240 return WTF::nullopt;
241 result.identifier = *identifier;
242
243 if (!decoder.decode(result.pageState))
244 return WTF::nullopt;
245
246 return result;
247}
248
249void BackForwardListState::encode(IPC::Encoder& encoder) const
250{
251 encoder << items;
252 encoder << currentIndex;
253}
254
255Optional<BackForwardListState> BackForwardListState::decode(IPC::Decoder& decoder)
256{
257 Optional<Vector<BackForwardListItemState>> items;
258 decoder >> items;
259 if (!items)
260 return WTF::nullopt;
261
262 Optional<uint32_t> currentIndex;
263 if (!decoder.decode(currentIndex))
264 return WTF::nullopt;
265
266 return {{ WTFMove(*items), WTFMove(currentIndex) }};
267}
268
269} // namespace WebKit
270