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.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
michael@0 | 2 | * vim: set ts=8 sts=4 et sw=4 tw=99: |
michael@0 | 3 | * This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 4 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 5 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 6 | |
michael@0 | 7 | #ifndef jit_Compactbuffer_h |
michael@0 | 8 | #define jit_Compactbuffer_h |
michael@0 | 9 | |
michael@0 | 10 | #include "jsalloc.h" |
michael@0 | 11 | |
michael@0 | 12 | #include "jit/IonTypes.h" |
michael@0 | 13 | #include "js/Vector.h" |
michael@0 | 14 | |
michael@0 | 15 | namespace js { |
michael@0 | 16 | namespace jit { |
michael@0 | 17 | |
michael@0 | 18 | class CompactBufferWriter; |
michael@0 | 19 | |
michael@0 | 20 | // CompactBuffers are byte streams designed for compressable integers. It has |
michael@0 | 21 | // helper functions for writing bytes, fixed-size integers, and variable-sized |
michael@0 | 22 | // integers. Variable sized integers are encoded in 1-5 bytes, each byte |
michael@0 | 23 | // containing 7 bits of the integer and a bit which specifies whether the next |
michael@0 | 24 | // byte is also part of the integer. |
michael@0 | 25 | // |
michael@0 | 26 | // Fixed-width integers are also available, in case the actual value will not |
michael@0 | 27 | // be known until later. |
michael@0 | 28 | |
michael@0 | 29 | class CompactBufferReader |
michael@0 | 30 | { |
michael@0 | 31 | const uint8_t *buffer_; |
michael@0 | 32 | const uint8_t *end_; |
michael@0 | 33 | |
michael@0 | 34 | uint32_t readVariableLength() { |
michael@0 | 35 | uint32_t val = 0; |
michael@0 | 36 | uint32_t shift = 0; |
michael@0 | 37 | uint8_t byte; |
michael@0 | 38 | while (true) { |
michael@0 | 39 | JS_ASSERT(shift < 32); |
michael@0 | 40 | byte = readByte(); |
michael@0 | 41 | val |= (uint32_t(byte) >> 1) << shift; |
michael@0 | 42 | shift += 7; |
michael@0 | 43 | if (!(byte & 1)) |
michael@0 | 44 | return val; |
michael@0 | 45 | } |
michael@0 | 46 | MOZ_ASSUME_UNREACHABLE("unreachable"); |
michael@0 | 47 | } |
michael@0 | 48 | |
michael@0 | 49 | public: |
michael@0 | 50 | CompactBufferReader(const uint8_t *start, const uint8_t *end) |
michael@0 | 51 | : buffer_(start), |
michael@0 | 52 | end_(end) |
michael@0 | 53 | { } |
michael@0 | 54 | inline CompactBufferReader(const CompactBufferWriter &writer); |
michael@0 | 55 | uint8_t readByte() { |
michael@0 | 56 | JS_ASSERT(buffer_ < end_); |
michael@0 | 57 | return *buffer_++; |
michael@0 | 58 | } |
michael@0 | 59 | uint32_t readFixedUint32_t() { |
michael@0 | 60 | uint32_t b0 = readByte(); |
michael@0 | 61 | uint32_t b1 = readByte(); |
michael@0 | 62 | uint32_t b2 = readByte(); |
michael@0 | 63 | uint32_t b3 = readByte(); |
michael@0 | 64 | return b0 | (b1 << 8) | (b2 << 16) | (b3 << 24); |
michael@0 | 65 | } |
michael@0 | 66 | uint16_t readFixedUint16_t() { |
michael@0 | 67 | uint32_t b0 = readByte(); |
michael@0 | 68 | uint32_t b1 = readByte(); |
michael@0 | 69 | return b0 | (b1 << 8); |
michael@0 | 70 | } |
michael@0 | 71 | uint32_t readUnsigned() { |
michael@0 | 72 | return readVariableLength(); |
michael@0 | 73 | } |
michael@0 | 74 | int32_t readSigned() { |
michael@0 | 75 | uint8_t b = readByte(); |
michael@0 | 76 | bool isNegative = !!(b & (1 << 0)); |
michael@0 | 77 | bool more = !!(b & (1 << 1)); |
michael@0 | 78 | int32_t result = b >> 2; |
michael@0 | 79 | if (more) |
michael@0 | 80 | result |= readUnsigned() << 6; |
michael@0 | 81 | if (isNegative) |
michael@0 | 82 | return -result; |
michael@0 | 83 | return result; |
michael@0 | 84 | } |
michael@0 | 85 | |
michael@0 | 86 | bool more() const { |
michael@0 | 87 | JS_ASSERT(buffer_ <= end_); |
michael@0 | 88 | return buffer_ < end_; |
michael@0 | 89 | } |
michael@0 | 90 | |
michael@0 | 91 | void seek(const uint8_t *start, uint32_t offset) { |
michael@0 | 92 | buffer_ = start + offset; |
michael@0 | 93 | MOZ_ASSERT(start < end_); |
michael@0 | 94 | MOZ_ASSERT(buffer_ < end_); |
michael@0 | 95 | } |
michael@0 | 96 | }; |
michael@0 | 97 | |
michael@0 | 98 | class CompactBufferWriter |
michael@0 | 99 | { |
michael@0 | 100 | js::Vector<uint8_t, 32, SystemAllocPolicy> buffer_; |
michael@0 | 101 | bool enoughMemory_; |
michael@0 | 102 | |
michael@0 | 103 | public: |
michael@0 | 104 | CompactBufferWriter() |
michael@0 | 105 | : enoughMemory_(true) |
michael@0 | 106 | { } |
michael@0 | 107 | |
michael@0 | 108 | // Note: writeByte() takes uint32 to catch implicit casts with a runtime |
michael@0 | 109 | // assert. |
michael@0 | 110 | void writeByte(uint32_t byte) { |
michael@0 | 111 | JS_ASSERT(byte <= 0xFF); |
michael@0 | 112 | enoughMemory_ &= buffer_.append(byte); |
michael@0 | 113 | } |
michael@0 | 114 | void writeUnsigned(uint32_t value) { |
michael@0 | 115 | do { |
michael@0 | 116 | uint8_t byte = ((value & 0x7F) << 1) | (value > 0x7F); |
michael@0 | 117 | writeByte(byte); |
michael@0 | 118 | value >>= 7; |
michael@0 | 119 | } while (value); |
michael@0 | 120 | } |
michael@0 | 121 | void writeSigned(int32_t v) { |
michael@0 | 122 | bool isNegative = v < 0; |
michael@0 | 123 | uint32_t value = isNegative ? -v : v; |
michael@0 | 124 | uint8_t byte = ((value & 0x3F) << 2) | ((value > 0x3F) << 1) | uint32_t(isNegative); |
michael@0 | 125 | writeByte(byte); |
michael@0 | 126 | |
michael@0 | 127 | // Write out the rest of the bytes, if needed. |
michael@0 | 128 | value >>= 6; |
michael@0 | 129 | if (value == 0) |
michael@0 | 130 | return; |
michael@0 | 131 | writeUnsigned(value); |
michael@0 | 132 | } |
michael@0 | 133 | void writeFixedUint32_t(uint32_t value) { |
michael@0 | 134 | writeByte(value & 0xFF); |
michael@0 | 135 | writeByte((value >> 8) & 0xFF); |
michael@0 | 136 | writeByte((value >> 16) & 0xFF); |
michael@0 | 137 | writeByte((value >> 24) & 0xFF); |
michael@0 | 138 | } |
michael@0 | 139 | void writeFixedUint16_t(uint16_t value) { |
michael@0 | 140 | writeByte(value & 0xFF); |
michael@0 | 141 | writeByte(value >> 8); |
michael@0 | 142 | } |
michael@0 | 143 | size_t length() const { |
michael@0 | 144 | return buffer_.length(); |
michael@0 | 145 | } |
michael@0 | 146 | uint8_t *buffer() { |
michael@0 | 147 | return &buffer_[0]; |
michael@0 | 148 | } |
michael@0 | 149 | const uint8_t *buffer() const { |
michael@0 | 150 | return &buffer_[0]; |
michael@0 | 151 | } |
michael@0 | 152 | bool oom() const { |
michael@0 | 153 | return !enoughMemory_; |
michael@0 | 154 | } |
michael@0 | 155 | }; |
michael@0 | 156 | |
michael@0 | 157 | CompactBufferReader::CompactBufferReader(const CompactBufferWriter &writer) |
michael@0 | 158 | : buffer_(writer.buffer()), |
michael@0 | 159 | end_(writer.buffer() + writer.length()) |
michael@0 | 160 | { |
michael@0 | 161 | } |
michael@0 | 162 | |
michael@0 | 163 | } // namespace jit |
michael@0 | 164 | } // namespace js |
michael@0 | 165 | |
michael@0 | 166 | #endif /* jit_Compactbuffer_h */ |