toolkit/crashreporter/google-breakpad/src/processor/postfix_evaluator.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

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__

mercurial