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 | // postfix_evaluator.h: Postfix (reverse Polish) notation expression evaluator. |
michael@0 | 33 | // |
michael@0 | 34 | // PostfixEvaluator evaluates an expression, using the expression itself |
michael@0 | 35 | // in postfix (reverse Polish) notation and a dictionary mapping constants |
michael@0 | 36 | // and variables to their values. The evaluator supports standard |
michael@0 | 37 | // arithmetic operations, assignment into variables, and when an optional |
michael@0 | 38 | // MemoryRange is provided, dereferencing. (Any unary key-to-value operation |
michael@0 | 39 | // may be used with a MemoryRange implementation that returns the appropriate |
michael@0 | 40 | // values, but PostfixEvaluator was written with dereferencing in mind.) |
michael@0 | 41 | // |
michael@0 | 42 | // The expression language is simple. Expressions are supplied as strings, |
michael@0 | 43 | // with operands and operators delimited by whitespace. Operands may be |
michael@0 | 44 | // either literal values suitable for ValueType, or constants or variables, |
michael@0 | 45 | // which reference the dictionary. The supported binary operators are + |
michael@0 | 46 | // (addition), - (subtraction), * (multiplication), / (quotient of division), |
michael@0 | 47 | // % (modulus of division), and @ (data alignment). The alignment operator (@) |
michael@0 | 48 | // accepts a value and an alignment size, and produces a result that is a |
michael@0 | 49 | // multiple of the alignment size by truncating the input value. |
michael@0 | 50 | // The unary ^ (dereference) operator is also provided. These operators |
michael@0 | 51 | // allow any operand to be either a literal value, constant, or variable. |
michael@0 | 52 | // Assignment (=) of any type of operand into a variable is also supported. |
michael@0 | 53 | // |
michael@0 | 54 | // The dictionary is provided as a map with string keys. Keys beginning |
michael@0 | 55 | // with the '$' character are treated as variables. All other keys are |
michael@0 | 56 | // treated as constants. Any results must be assigned into variables in the |
michael@0 | 57 | // dictionary. These variables do not need to exist prior to calling |
michael@0 | 58 | // Evaluate, unless used in an expression prior to being assigned to. The |
michael@0 | 59 | // internal stack state is not made available after evaluation, and any |
michael@0 | 60 | // values remaining on the stack are treated as evidence of incomplete |
michael@0 | 61 | // execution and cause the evaluator to indicate failure. |
michael@0 | 62 | // |
michael@0 | 63 | // PostfixEvaluator is intended to support evaluation of "program strings" |
michael@0 | 64 | // obtained from MSVC frame data debugging information in pdb files as |
michael@0 | 65 | // returned by the DIA APIs. |
michael@0 | 66 | // |
michael@0 | 67 | // Author: Mark Mentovai |
michael@0 | 68 | |
michael@0 | 69 | #ifndef PROCESSOR_POSTFIX_EVALUATOR_H__ |
michael@0 | 70 | #define PROCESSOR_POSTFIX_EVALUATOR_H__ |
michael@0 | 71 | |
michael@0 | 72 | |
michael@0 | 73 | #include <map> |
michael@0 | 74 | #include <string> |
michael@0 | 75 | #include <vector> |
michael@0 | 76 | |
michael@0 | 77 | #include "common/using_std_string.h" |
michael@0 | 78 | #include "common/unique_string.h" |
michael@0 | 79 | #include "common/module.h" |
michael@0 | 80 | |
michael@0 | 81 | namespace google_breakpad { |
michael@0 | 82 | |
michael@0 | 83 | using std::map; |
michael@0 | 84 | using std::vector; |
michael@0 | 85 | |
michael@0 | 86 | class MemoryRegion; |
michael@0 | 87 | |
michael@0 | 88 | // A union type for elements in the postfix evaluator's stack. |
michael@0 | 89 | template<typename ValueType> |
michael@0 | 90 | class StackElem { |
michael@0 | 91 | public: |
michael@0 | 92 | StackElem(ValueType val) { isValue = true; u.val = val; } |
michael@0 | 93 | StackElem(const UniqueString* ustr) { isValue = false; u.ustr = ustr; } |
michael@0 | 94 | bool isValue; |
michael@0 | 95 | union { ValueType val; const UniqueString* ustr; } u; |
michael@0 | 96 | }; |
michael@0 | 97 | |
michael@0 | 98 | template<typename ValueType> |
michael@0 | 99 | class PostfixEvaluator { |
michael@0 | 100 | public: |
michael@0 | 101 | typedef UniqueStringMap<ValueType> DictionaryType; |
michael@0 | 102 | typedef UniqueStringMap<bool> DictionaryValidityType; |
michael@0 | 103 | |
michael@0 | 104 | // Create a PostfixEvaluator object that may be used (with Evaluate) on |
michael@0 | 105 | // one or more expressions. PostfixEvaluator does not take ownership of |
michael@0 | 106 | // either argument. |memory| may be NULL, in which case dereferencing |
michael@0 | 107 | // (^) will not be supported. |dictionary| may be NULL, but evaluation |
michael@0 | 108 | // will fail in that case unless set_dictionary is used before calling |
michael@0 | 109 | // Evaluate. |
michael@0 | 110 | PostfixEvaluator(DictionaryType *dictionary, const MemoryRegion *memory) |
michael@0 | 111 | : dictionary_(dictionary), memory_(memory), stack_() {} |
michael@0 | 112 | |
michael@0 | 113 | // Evaluate the expression, starting with an empty stack. The results of |
michael@0 | 114 | // execution will be stored in one (or more) variables in the dictionary. |
michael@0 | 115 | // Returns false if any failures occur during execution, leaving |
michael@0 | 116 | // variables in the dictionary in an indeterminate state. If assigned is |
michael@0 | 117 | // non-NULL, any keys set in the dictionary as a result of evaluation |
michael@0 | 118 | // will also be set to true in assigned, providing a way to determine if |
michael@0 | 119 | // an expression modifies any of its input variables. |
michael@0 | 120 | bool Evaluate(const Module::Expr &expr, DictionaryValidityType *assigned); |
michael@0 | 121 | |
michael@0 | 122 | // Like Evaluate, but expects the expression to denote a value. |
michael@0 | 123 | // If evaluation succeeds and (in the case of a postfix expression) |
michael@0 | 124 | // leaves exactly one value on the stack, pop that value, store it in |
michael@0 | 125 | // *result, and return true. Otherwise, return false. |
michael@0 | 126 | bool EvaluateForValue(const Module::Expr& expression, ValueType* result); |
michael@0 | 127 | |
michael@0 | 128 | DictionaryType* dictionary() const { return dictionary_; } |
michael@0 | 129 | |
michael@0 | 130 | // Reset the dictionary. PostfixEvaluator does not take ownership. |
michael@0 | 131 | void set_dictionary(DictionaryType *dictionary) {dictionary_ = dictionary; } |
michael@0 | 132 | |
michael@0 | 133 | private: |
michael@0 | 134 | // Return values for PopValueOrIdentifier |
michael@0 | 135 | enum PopResult { |
michael@0 | 136 | POP_RESULT_FAIL = 0, |
michael@0 | 137 | POP_RESULT_VALUE, |
michael@0 | 138 | POP_RESULT_IDENTIFIER |
michael@0 | 139 | }; |
michael@0 | 140 | |
michael@0 | 141 | // Retrieves the topmost literal value, constant, or variable from the |
michael@0 | 142 | // stack. Returns POP_RESULT_VALUE if the topmost entry is a literal |
michael@0 | 143 | // value, and sets |value| accordingly. Returns POP_RESULT_IDENTIFIER |
michael@0 | 144 | // if the topmost entry is a constant or variable identifier, and sets |
michael@0 | 145 | // |identifier| accordingly. Returns POP_RESULT_FAIL on failure, such |
michael@0 | 146 | // as when the stack is empty. |
michael@0 | 147 | PopResult PopValueOrIdentifier(ValueType *value, |
michael@0 | 148 | const UniqueString** identifier); |
michael@0 | 149 | |
michael@0 | 150 | // Retrieves the topmost value on the stack. If the topmost entry is |
michael@0 | 151 | // an identifier, the dictionary is queried for the identifier's value. |
michael@0 | 152 | // Returns false on failure, such as when the stack is empty or when |
michael@0 | 153 | // a nonexistent identifier is named. |
michael@0 | 154 | bool PopValue(ValueType *value); |
michael@0 | 155 | |
michael@0 | 156 | // Pushes a UniqueString* on the stack. |
michael@0 | 157 | void PushIdentifier(const UniqueString* ustr); |
michael@0 | 158 | |
michael@0 | 159 | // Retrieves the top two values on the stack, in the style of PopValue. |
michael@0 | 160 | // value2 is popped before value1, so that value1 corresponds to the |
michael@0 | 161 | // entry that was pushed prior to value2. Returns false on failure. |
michael@0 | 162 | bool PopValues(ValueType *value1, ValueType *value2); |
michael@0 | 163 | |
michael@0 | 164 | // Pushes a new value onto the stack. |
michael@0 | 165 | void PushValue(const ValueType &value); |
michael@0 | 166 | |
michael@0 | 167 | // Evaluate expression, updating *assigned if it is non-zero. Return |
michael@0 | 168 | // true if evaluation completes successfully. Do not clear the stack |
michael@0 | 169 | // upon successful evaluation. |
michael@0 | 170 | bool EvaluateInternal(const string &expression, |
michael@0 | 171 | DictionaryValidityType *assigned); |
michael@0 | 172 | |
michael@0 | 173 | bool EvaluateToken(const string &token, |
michael@0 | 174 | const string &expression, |
michael@0 | 175 | DictionaryValidityType *assigned); |
michael@0 | 176 | |
michael@0 | 177 | // The dictionary mapping constant and variable identifiers (strings) to |
michael@0 | 178 | // values. Keys beginning with '$' are treated as variable names, and |
michael@0 | 179 | // PostfixEvaluator is free to create and modify these keys. Weak pointer. |
michael@0 | 180 | DictionaryType *dictionary_; |
michael@0 | 181 | |
michael@0 | 182 | // If non-NULL, the MemoryRegion used for dereference (^) operations. |
michael@0 | 183 | // If NULL, dereferencing is unsupported and will fail. Weak pointer. |
michael@0 | 184 | const MemoryRegion *memory_; |
michael@0 | 185 | |
michael@0 | 186 | // The stack contains state information as execution progresses. Values |
michael@0 | 187 | // are pushed on to it as the expression string is read and as operations |
michael@0 | 188 | // yield values; values are popped when used as operands to operators. |
michael@0 | 189 | vector<StackElem<ValueType> > stack_; |
michael@0 | 190 | }; |
michael@0 | 191 | |
michael@0 | 192 | } // namespace google_breakpad |
michael@0 | 193 | |
michael@0 | 194 | |
michael@0 | 195 | #endif // PROCESSOR_POSTFIX_EVALUATOR_H__ |