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 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sts=4 et sw=4 tw=99:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef jsonparser_h
8 #define jsonparser_h
10 #include "mozilla/Attributes.h"
12 #include "ds/IdValuePair.h"
13 #include "vm/String.h"
15 namespace js {
17 class MOZ_STACK_CLASS JSONParser : private AutoGCRooter
18 {
19 public:
20 enum ErrorHandling { RaiseError, NoError };
22 private:
23 /* Data members */
25 JSContext * const cx;
26 JS::ConstTwoByteChars current;
27 const JS::ConstTwoByteChars begin, end;
29 Value v;
31 const ErrorHandling errorHandling;
33 enum Token { String, Number, True, False, Null,
34 ArrayOpen, ArrayClose,
35 ObjectOpen, ObjectClose,
36 Colon, Comma,
37 OOM, Error };
39 // State related to the parser's current position. At all points in the
40 // parse this keeps track of the stack of arrays and objects which have
41 // been started but not finished yet. The actual JS object is not
42 // allocated until the literal is closed, so that the result can be sized
43 // according to its contents and have its type and shape filled in using
44 // caches.
46 // State for an array that is currently being parsed. This includes all
47 // elements that have been seen so far.
48 typedef Vector<Value, 20> ElementVector;
50 // State for an object that is currently being parsed. This includes all
51 // the key/value pairs that have been seen so far.
52 typedef Vector<IdValuePair, 10> PropertyVector;
54 // Possible states the parser can be in between values.
55 enum ParserState {
56 // An array element has just being parsed.
57 FinishArrayElement,
59 // An object property has just been parsed.
60 FinishObjectMember,
62 // At the start of the parse, before any values have been processed.
63 JSONValue
64 };
66 // Stack element for an in progress array or object.
67 struct StackEntry {
68 ElementVector &elements() {
69 JS_ASSERT(state == FinishArrayElement);
70 return * static_cast<ElementVector *>(vector);
71 }
73 PropertyVector &properties() {
74 JS_ASSERT(state == FinishObjectMember);
75 return * static_cast<PropertyVector *>(vector);
76 }
78 StackEntry(ElementVector *elements)
79 : state(FinishArrayElement), vector(elements)
80 {}
82 StackEntry(PropertyVector *properties)
83 : state(FinishObjectMember), vector(properties)
84 {}
86 ParserState state;
88 private:
89 void *vector;
90 };
92 // All in progress arrays and objects being parsed, in order from outermost
93 // to innermost.
94 Vector<StackEntry, 10> stack;
96 // Unused element and property vectors for previous in progress arrays and
97 // objects. These vectors are not freed until the end of the parse to avoid
98 // unnecessary freeing and allocation.
99 Vector<ElementVector*, 5> freeElements;
100 Vector<PropertyVector*, 5> freeProperties;
102 #ifdef DEBUG
103 Token lastToken;
104 #endif
106 public:
107 /* Public API */
109 /* Create a parser for the provided JSON data. */
110 JSONParser(JSContext *cx, JS::ConstTwoByteChars data, size_t length,
111 ErrorHandling errorHandling = RaiseError)
112 : AutoGCRooter(cx, JSONPARSER),
113 cx(cx),
114 current(data),
115 begin(data),
116 end((data + length).get(), data.get(), length),
117 errorHandling(errorHandling),
118 stack(cx),
119 freeElements(cx),
120 freeProperties(cx)
121 #ifdef DEBUG
122 , lastToken(Error)
123 #endif
124 {
125 JS_ASSERT(current <= end);
126 }
128 ~JSONParser();
130 /*
131 * Parse the JSON data specified at construction time. If it parses
132 * successfully, store the prescribed value in *vp and return true. If an
133 * internal error (e.g. OOM) occurs during parsing, return false.
134 * Otherwise, if invalid input was specifed but no internal error occurred,
135 * behavior depends upon the error handling specified at construction: if
136 * error handling is RaiseError then throw a SyntaxError and return false,
137 * otherwise return true and set *vp to |undefined|. (JSON syntax can't
138 * represent |undefined|, so the JSON data couldn't have specified it.)
139 */
140 bool parse(MutableHandleValue vp);
142 private:
143 Value numberValue() const {
144 JS_ASSERT(lastToken == Number);
145 JS_ASSERT(v.isNumber());
146 return v;
147 }
149 Value stringValue() const {
150 JS_ASSERT(lastToken == String);
151 JS_ASSERT(v.isString());
152 return v;
153 }
155 JSAtom *atomValue() const {
156 Value strval = stringValue();
157 return &strval.toString()->asAtom();
158 }
160 Token token(Token t) {
161 JS_ASSERT(t != String);
162 JS_ASSERT(t != Number);
163 #ifdef DEBUG
164 lastToken = t;
165 #endif
166 return t;
167 }
169 Token stringToken(JSString *str) {
170 this->v = StringValue(str);
171 #ifdef DEBUG
172 lastToken = String;
173 #endif
174 return String;
175 }
177 Token numberToken(double d) {
178 this->v = NumberValue(d);
179 #ifdef DEBUG
180 lastToken = Number;
181 #endif
182 return Number;
183 }
185 enum StringType { PropertyName, LiteralValue };
186 template<StringType ST> Token readString();
188 Token readNumber();
190 Token advance();
191 Token advancePropertyName();
192 Token advancePropertyColon();
193 Token advanceAfterProperty();
194 Token advanceAfterObjectOpen();
195 Token advanceAfterArrayElement();
197 void error(const char *msg);
198 bool errorReturn();
200 JSObject *createFinishedObject(PropertyVector &properties);
201 bool finishObject(MutableHandleValue vp, PropertyVector &properties);
202 bool finishArray(MutableHandleValue vp, ElementVector &elements);
204 void getTextPosition(uint32_t *column, uint32_t *line);
206 friend void AutoGCRooter::trace(JSTracer *trc);
207 void trace(JSTracer *trc);
209 private:
210 JSONParser(const JSONParser &other) MOZ_DELETE;
211 void operator=(const JSONParser &other) MOZ_DELETE;
212 };
214 } /* namespace js */
216 #endif /* jsonparser_h */