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++ -*- |
michael@0 | 2 | |
michael@0 | 3 | // Copyright (c) 2010, Google Inc. |
michael@0 | 4 | // All rights reserved. |
michael@0 | 5 | // |
michael@0 | 6 | // Redistribution and use in source and binary forms, with or without |
michael@0 | 7 | // modification, are permitted provided that the following conditions are |
michael@0 | 8 | // met: |
michael@0 | 9 | // |
michael@0 | 10 | // * Redistributions of source code must retain the above copyright |
michael@0 | 11 | // notice, this list of conditions and the following disclaimer. |
michael@0 | 12 | // * Redistributions in binary form must reproduce the above |
michael@0 | 13 | // copyright notice, this list of conditions and the following disclaimer |
michael@0 | 14 | // in the documentation and/or other materials provided with the |
michael@0 | 15 | // distribution. |
michael@0 | 16 | // * Neither the name of Google Inc. nor the names of its |
michael@0 | 17 | // contributors may be used to endorse or promote products derived from |
michael@0 | 18 | // this software without specific prior written permission. |
michael@0 | 19 | // |
michael@0 | 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
michael@0 | 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
michael@0 | 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
michael@0 | 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
michael@0 | 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
michael@0 | 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
michael@0 | 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
michael@0 | 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
michael@0 | 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
michael@0 | 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
michael@0 | 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
michael@0 | 31 | |
michael@0 | 32 | // Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com> |
michael@0 | 33 | |
michael@0 | 34 | // Mock classes for writing stackwalker tests, shared amongst architectures. |
michael@0 | 35 | |
michael@0 | 36 | #ifndef PROCESSOR_STACKWALKER_UNITTEST_UTILS_H_ |
michael@0 | 37 | #define PROCESSOR_STACKWALKER_UNITTEST_UTILS_H_ |
michael@0 | 38 | |
michael@0 | 39 | #include <stdlib.h> |
michael@0 | 40 | #include <string> |
michael@0 | 41 | #include <vector> |
michael@0 | 42 | |
michael@0 | 43 | #include "common/using_std_string.h" |
michael@0 | 44 | #include "google_breakpad/common/breakpad_types.h" |
michael@0 | 45 | #include "google_breakpad/processor/code_module.h" |
michael@0 | 46 | #include "google_breakpad/processor/code_modules.h" |
michael@0 | 47 | #include "google_breakpad/processor/memory_region.h" |
michael@0 | 48 | #include "google_breakpad/processor/symbol_supplier.h" |
michael@0 | 49 | #include "google_breakpad/processor/system_info.h" |
michael@0 | 50 | |
michael@0 | 51 | class MockMemoryRegion: public google_breakpad::MemoryRegion { |
michael@0 | 52 | public: |
michael@0 | 53 | MockMemoryRegion(): base_address_(0) { } |
michael@0 | 54 | |
michael@0 | 55 | // Set this region's address and contents. If we have placed an |
michael@0 | 56 | // instance of this class in a test fixture class, individual tests |
michael@0 | 57 | // can use this to provide the region's contents. |
michael@0 | 58 | void Init(uint64_t base_address, const string &contents) { |
michael@0 | 59 | base_address_ = base_address; |
michael@0 | 60 | contents_ = contents; |
michael@0 | 61 | } |
michael@0 | 62 | |
michael@0 | 63 | uint64_t GetBase() const { return base_address_; } |
michael@0 | 64 | uint32_t GetSize() const { return contents_.size(); } |
michael@0 | 65 | |
michael@0 | 66 | bool GetMemoryAtAddress(uint64_t address, uint8_t *value) const { |
michael@0 | 67 | return GetMemoryLittleEndian(address, value); |
michael@0 | 68 | } |
michael@0 | 69 | bool GetMemoryAtAddress(uint64_t address, uint16_t *value) const { |
michael@0 | 70 | return GetMemoryLittleEndian(address, value); |
michael@0 | 71 | } |
michael@0 | 72 | bool GetMemoryAtAddress(uint64_t address, uint32_t *value) const { |
michael@0 | 73 | return GetMemoryLittleEndian(address, value); |
michael@0 | 74 | } |
michael@0 | 75 | bool GetMemoryAtAddress(uint64_t address, uint64_t *value) const { |
michael@0 | 76 | return GetMemoryLittleEndian(address, value); |
michael@0 | 77 | } |
michael@0 | 78 | |
michael@0 | 79 | private: |
michael@0 | 80 | // Fetch a little-endian value from ADDRESS in contents_ whose size |
michael@0 | 81 | // is BYTES, and store it in *VALUE. Return true on success. |
michael@0 | 82 | template<typename ValueType> |
michael@0 | 83 | bool GetMemoryLittleEndian(uint64_t address, ValueType *value) const { |
michael@0 | 84 | if (address < base_address_ || |
michael@0 | 85 | address - base_address_ + sizeof(ValueType) > contents_.size()) |
michael@0 | 86 | return false; |
michael@0 | 87 | ValueType v = 0; |
michael@0 | 88 | int start = address - base_address_; |
michael@0 | 89 | // The loop condition is odd, but it's correct for size_t. |
michael@0 | 90 | for (size_t i = sizeof(ValueType) - 1; i < sizeof(ValueType); i--) |
michael@0 | 91 | v = (v << 8) | static_cast<unsigned char>(contents_[start + i]); |
michael@0 | 92 | *value = v; |
michael@0 | 93 | return true; |
michael@0 | 94 | } |
michael@0 | 95 | |
michael@0 | 96 | uint64_t base_address_; |
michael@0 | 97 | string contents_; |
michael@0 | 98 | }; |
michael@0 | 99 | |
michael@0 | 100 | class MockCodeModule: public google_breakpad::CodeModule { |
michael@0 | 101 | public: |
michael@0 | 102 | MockCodeModule(uint64_t base_address, uint64_t size, |
michael@0 | 103 | const string &code_file, const string &version) |
michael@0 | 104 | : base_address_(base_address), size_(size), code_file_(code_file) { } |
michael@0 | 105 | |
michael@0 | 106 | uint64_t base_address() const { return base_address_; } |
michael@0 | 107 | uint64_t size() const { return size_; } |
michael@0 | 108 | string code_file() const { return code_file_; } |
michael@0 | 109 | string code_identifier() const { return code_file_; } |
michael@0 | 110 | string debug_file() const { return code_file_; } |
michael@0 | 111 | string debug_identifier() const { return code_file_; } |
michael@0 | 112 | string version() const { return version_; } |
michael@0 | 113 | const google_breakpad::CodeModule *Copy() const { |
michael@0 | 114 | abort(); // Tests won't use this. |
michael@0 | 115 | } |
michael@0 | 116 | |
michael@0 | 117 | private: |
michael@0 | 118 | uint64_t base_address_; |
michael@0 | 119 | uint64_t size_; |
michael@0 | 120 | string code_file_; |
michael@0 | 121 | string version_; |
michael@0 | 122 | }; |
michael@0 | 123 | |
michael@0 | 124 | class MockCodeModules: public google_breakpad::CodeModules { |
michael@0 | 125 | public: |
michael@0 | 126 | typedef google_breakpad::CodeModule CodeModule; |
michael@0 | 127 | typedef google_breakpad::CodeModules CodeModules; |
michael@0 | 128 | |
michael@0 | 129 | void Add(const MockCodeModule *module) { |
michael@0 | 130 | modules_.push_back(module); |
michael@0 | 131 | } |
michael@0 | 132 | |
michael@0 | 133 | unsigned int module_count() const { return modules_.size(); } |
michael@0 | 134 | |
michael@0 | 135 | const CodeModule *GetModuleForAddress(uint64_t address) const { |
michael@0 | 136 | for (ModuleVector::const_iterator i = modules_.begin(); |
michael@0 | 137 | i != modules_.end(); i++) { |
michael@0 | 138 | const MockCodeModule *module = *i; |
michael@0 | 139 | if (module->base_address() <= address && |
michael@0 | 140 | address - module->base_address() < module->size()) |
michael@0 | 141 | return module; |
michael@0 | 142 | } |
michael@0 | 143 | return NULL; |
michael@0 | 144 | }; |
michael@0 | 145 | |
michael@0 | 146 | const CodeModule *GetMainModule() const { return modules_[0]; } |
michael@0 | 147 | |
michael@0 | 148 | const CodeModule *GetModuleAtSequence(unsigned int sequence) const { |
michael@0 | 149 | return modules_.at(sequence); |
michael@0 | 150 | } |
michael@0 | 151 | |
michael@0 | 152 | const CodeModule *GetModuleAtIndex(unsigned int index) const { |
michael@0 | 153 | return modules_.at(index); |
michael@0 | 154 | } |
michael@0 | 155 | |
michael@0 | 156 | const CodeModules *Copy() const { abort(); } // Tests won't use this. |
michael@0 | 157 | |
michael@0 | 158 | private: |
michael@0 | 159 | typedef std::vector<const MockCodeModule *> ModuleVector; |
michael@0 | 160 | ModuleVector modules_; |
michael@0 | 161 | }; |
michael@0 | 162 | |
michael@0 | 163 | class MockSymbolSupplier: public google_breakpad::SymbolSupplier { |
michael@0 | 164 | public: |
michael@0 | 165 | typedef google_breakpad::CodeModule CodeModule; |
michael@0 | 166 | typedef google_breakpad::SystemInfo SystemInfo; |
michael@0 | 167 | MOCK_METHOD3(GetSymbolFile, SymbolResult(const CodeModule *module, |
michael@0 | 168 | const SystemInfo *system_info, |
michael@0 | 169 | string *symbol_file)); |
michael@0 | 170 | MOCK_METHOD4(GetSymbolFile, SymbolResult(const CodeModule *module, |
michael@0 | 171 | const SystemInfo *system_info, |
michael@0 | 172 | string *symbol_file, |
michael@0 | 173 | string *symbol_data)); |
michael@0 | 174 | MOCK_METHOD4(GetCStringSymbolData, SymbolResult(const CodeModule *module, |
michael@0 | 175 | const SystemInfo *system_info, |
michael@0 | 176 | string *symbol_file, |
michael@0 | 177 | char **symbol_data)); |
michael@0 | 178 | MOCK_METHOD1(FreeSymbolData, void(const CodeModule *module)); |
michael@0 | 179 | |
michael@0 | 180 | // Copies the passed string contents into a newly allocated buffer. |
michael@0 | 181 | // The newly allocated buffer will be freed during destruction. |
michael@0 | 182 | char* CopySymbolDataAndOwnTheCopy(const std::string &info) { |
michael@0 | 183 | unsigned int buffer_size = info.size() + 1; |
michael@0 | 184 | char *symbol_data = new char [buffer_size]; |
michael@0 | 185 | strcpy(symbol_data, info.c_str()); |
michael@0 | 186 | symbol_data_to_free_.push_back(symbol_data); |
michael@0 | 187 | return symbol_data; |
michael@0 | 188 | } |
michael@0 | 189 | |
michael@0 | 190 | virtual ~MockSymbolSupplier() { |
michael@0 | 191 | for (SymbolDataVector::const_iterator i = symbol_data_to_free_.begin(); |
michael@0 | 192 | i != symbol_data_to_free_.end(); i++) { |
michael@0 | 193 | char* symbol_data = *i; |
michael@0 | 194 | delete [] symbol_data; |
michael@0 | 195 | } |
michael@0 | 196 | } |
michael@0 | 197 | |
michael@0 | 198 | private: |
michael@0 | 199 | // List of symbol data to be freed upon destruction |
michael@0 | 200 | typedef std::vector<char*> SymbolDataVector; |
michael@0 | 201 | SymbolDataVector symbol_data_to_free_; |
michael@0 | 202 | }; |
michael@0 | 203 | |
michael@0 | 204 | #endif // PROCESSOR_STACKWALKER_UNITTEST_UTILS_H_ |