Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
1 // Copyright (c) 2007, Google Inc.
2 // 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 are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 // * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 //
30 // MachIPC.mm
31 // Wrapper for mach IPC calls
33 #import <stdio.h>
34 #import "MachIPC.h"
35 #include "common/mac/bootstrap_compat.h"
37 namespace google_breakpad {
38 //==============================================================================
39 MachSendMessage::MachSendMessage(int32_t message_id) : MachMessage() {
40 head.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0);
42 // head.msgh_remote_port = ...; // filled out in MachPortSender::SendMessage()
43 head.msgh_local_port = MACH_PORT_NULL;
44 head.msgh_reserved = 0;
45 head.msgh_id = 0;
47 SetDescriptorCount(0); // start out with no descriptors
49 SetMessageID(message_id);
50 SetData(NULL, 0); // client may add data later
51 }
53 //==============================================================================
54 // returns true if successful
55 bool MachMessage::SetData(void *data,
56 int32_t data_length) {
57 // first check to make sure we have enough space
58 size_t size = CalculateSize();
59 size_t new_size = size + data_length;
61 if (new_size > sizeof(MachMessage)) {
62 return false; // not enough space
63 }
65 GetDataPacket()->data_length = EndianU32_NtoL(data_length);
66 if (data) memcpy(GetDataPacket()->data, data, data_length);
68 CalculateSize();
70 return true;
71 }
73 //==============================================================================
74 // calculates and returns the total size of the message
75 // Currently, the entire message MUST fit inside of the MachMessage
76 // messsage size <= sizeof(MachMessage)
77 mach_msg_size_t MachMessage::CalculateSize() {
78 size_t size = sizeof(mach_msg_header_t) + sizeof(mach_msg_body_t);
80 // add space for MessageDataPacket
81 int32_t alignedDataLength = (GetDataLength() + 3) & ~0x3;
82 size += 2*sizeof(int32_t) + alignedDataLength;
84 // add space for descriptors
85 size += GetDescriptorCount() * sizeof(MachMsgPortDescriptor);
87 head.msgh_size = static_cast<mach_msg_size_t>(size);
89 return head.msgh_size;
90 }
92 //==============================================================================
93 MachMessage::MessageDataPacket *MachMessage::GetDataPacket() {
94 size_t desc_size = sizeof(MachMsgPortDescriptor)*GetDescriptorCount();
95 MessageDataPacket *packet =
96 reinterpret_cast<MessageDataPacket*>(padding + desc_size);
98 return packet;
99 }
101 //==============================================================================
102 void MachMessage::SetDescriptor(int n,
103 const MachMsgPortDescriptor &desc) {
104 MachMsgPortDescriptor *desc_array =
105 reinterpret_cast<MachMsgPortDescriptor*>(padding);
106 desc_array[n] = desc;
107 }
109 //==============================================================================
110 // returns true if successful otherwise there was not enough space
111 bool MachMessage::AddDescriptor(const MachMsgPortDescriptor &desc) {
112 // first check to make sure we have enough space
113 int size = CalculateSize();
114 size_t new_size = size + sizeof(MachMsgPortDescriptor);
116 if (new_size > sizeof(MachMessage)) {
117 return false; // not enough space
118 }
120 // unfortunately, we need to move the data to allow space for the
121 // new descriptor
122 u_int8_t *p = reinterpret_cast<u_int8_t*>(GetDataPacket());
123 bcopy(p, p+sizeof(MachMsgPortDescriptor), GetDataLength()+2*sizeof(int32_t));
125 SetDescriptor(GetDescriptorCount(), desc);
126 SetDescriptorCount(GetDescriptorCount() + 1);
128 CalculateSize();
130 return true;
131 }
133 //==============================================================================
134 void MachMessage::SetDescriptorCount(int n) {
135 body.msgh_descriptor_count = n;
137 if (n > 0) {
138 head.msgh_bits |= MACH_MSGH_BITS_COMPLEX;
139 } else {
140 head.msgh_bits &= ~MACH_MSGH_BITS_COMPLEX;
141 }
142 }
144 //==============================================================================
145 MachMsgPortDescriptor *MachMessage::GetDescriptor(int n) {
146 if (n < GetDescriptorCount()) {
147 MachMsgPortDescriptor *desc =
148 reinterpret_cast<MachMsgPortDescriptor*>(padding);
149 return desc + n;
150 }
152 return nil;
153 }
155 //==============================================================================
156 mach_port_t MachMessage::GetTranslatedPort(int n) {
157 if (n < GetDescriptorCount()) {
158 return GetDescriptor(n)->GetMachPort();
159 }
160 return MACH_PORT_NULL;
161 }
163 #pragma mark -
165 //==============================================================================
166 // create a new mach port for receiving messages and register a name for it
167 ReceivePort::ReceivePort(const char *receive_port_name) {
168 mach_port_t current_task = mach_task_self();
170 init_result_ = mach_port_allocate(current_task,
171 MACH_PORT_RIGHT_RECEIVE,
172 &port_);
174 if (init_result_ != KERN_SUCCESS)
175 return;
177 init_result_ = mach_port_insert_right(current_task,
178 port_,
179 port_,
180 MACH_MSG_TYPE_MAKE_SEND);
182 if (init_result_ != KERN_SUCCESS)
183 return;
185 mach_port_t task_bootstrap_port = 0;
186 init_result_ = task_get_bootstrap_port(current_task, &task_bootstrap_port);
188 if (init_result_ != KERN_SUCCESS)
189 return;
191 init_result_ = breakpad::BootstrapRegister(
192 bootstrap_port,
193 const_cast<char*>(receive_port_name),
194 port_);
195 }
197 //==============================================================================
198 // create a new mach port for receiving messages
199 ReceivePort::ReceivePort() {
200 mach_port_t current_task = mach_task_self();
202 init_result_ = mach_port_allocate(current_task,
203 MACH_PORT_RIGHT_RECEIVE,
204 &port_);
206 if (init_result_ != KERN_SUCCESS)
207 return;
209 init_result_ = mach_port_insert_right(current_task,
210 port_,
211 port_,
212 MACH_MSG_TYPE_MAKE_SEND);
213 }
215 //==============================================================================
216 // Given an already existing mach port, use it. We take ownership of the
217 // port and deallocate it in our destructor.
218 ReceivePort::ReceivePort(mach_port_t receive_port)
219 : port_(receive_port),
220 init_result_(KERN_SUCCESS) {
221 }
223 //==============================================================================
224 ReceivePort::~ReceivePort() {
225 if (init_result_ == KERN_SUCCESS)
226 mach_port_deallocate(mach_task_self(), port_);
227 }
229 //==============================================================================
230 kern_return_t ReceivePort::WaitForMessage(MachReceiveMessage *out_message,
231 mach_msg_timeout_t timeout) {
232 if (!out_message) {
233 return KERN_INVALID_ARGUMENT;
234 }
236 // return any error condition encountered in constructor
237 if (init_result_ != KERN_SUCCESS)
238 return init_result_;
240 out_message->head.msgh_bits = 0;
241 out_message->head.msgh_local_port = port_;
242 out_message->head.msgh_remote_port = MACH_PORT_NULL;
243 out_message->head.msgh_reserved = 0;
244 out_message->head.msgh_id = 0;
246 mach_msg_option_t options = MACH_RCV_MSG;
247 if (timeout != MACH_MSG_TIMEOUT_NONE)
248 options |= MACH_RCV_TIMEOUT;
249 kern_return_t result = mach_msg(&out_message->head,
250 options,
251 0,
252 sizeof(MachMessage),
253 port_,
254 timeout, // timeout in ms
255 MACH_PORT_NULL);
257 return result;
258 }
260 #pragma mark -
262 //==============================================================================
263 // get a port with send rights corresponding to a named registered service
264 MachPortSender::MachPortSender(const char *receive_port_name) {
265 mach_port_t task_bootstrap_port = 0;
266 init_result_ = task_get_bootstrap_port(mach_task_self(),
267 &task_bootstrap_port);
269 if (init_result_ != KERN_SUCCESS)
270 return;
272 init_result_ = bootstrap_look_up(task_bootstrap_port,
273 const_cast<char*>(receive_port_name),
274 &send_port_);
275 }
277 //==============================================================================
278 MachPortSender::MachPortSender(mach_port_t send_port)
279 : send_port_(send_port),
280 init_result_(KERN_SUCCESS) {
281 }
283 //==============================================================================
284 kern_return_t MachPortSender::SendMessage(MachSendMessage &message,
285 mach_msg_timeout_t timeout) {
286 if (message.head.msgh_size == 0) {
287 return KERN_INVALID_VALUE; // just for safety -- never should occur
288 };
290 if (init_result_ != KERN_SUCCESS)
291 return init_result_;
293 message.head.msgh_remote_port = send_port_;
295 kern_return_t result = mach_msg(&message.head,
296 MACH_SEND_MSG | MACH_SEND_TIMEOUT,
297 message.head.msgh_size,
298 0,
299 MACH_PORT_NULL,
300 timeout, // timeout in ms
301 MACH_PORT_NULL);
303 return result;
304 }
306 } // namespace google_breakpad