Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: src/FileSystemJsObject.cpp

Issue 10173031: Don`t use references to JsEngine to avoid use-after-free errors,switch to shared_ptr instead (Closed)
Patch Set: Created April 18, 2013, 4:15 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
1 #include <AdblockPlus/FileSystem.h> 1 #include <AdblockPlus/FileSystem.h>
2 #include <stdexcept> 2 #include <stdexcept>
3 #include <sstream> 3 #include <sstream>
4 #include <vector> 4 #include <vector>
5 5
6 #include <AdblockPlus/JsEngine.h>
7 #include <AdblockPlus/JsValue.h> 6 #include <AdblockPlus/JsValue.h>
8 #include "FileSystemJsObject.h" 7 #include "FileSystemJsObject.h"
9 #include "Utils.h" 8 #include "Utils.h"
10 #include "Thread.h" 9 #include "Thread.h"
11 #include "Utils.h" 10 #include "Utils.h"
12 11
13 using namespace AdblockPlus; 12 using namespace AdblockPlus;
14 13
15 namespace 14 namespace
16 { 15 {
17 class IoThread : public Thread 16 class IoThread : public Thread
18 { 17 {
19 public: 18 public:
20 IoThread(JsEngine& jsEngine, JsValuePtr callback) 19 IoThread(JsEnginePtr jsEngine, JsValuePtr callback)
21 : jsEngine(jsEngine), fileSystem(jsEngine.GetFileSystem()), 20 : jsEngine(jsEngine), fileSystem(jsEngine->GetFileSystem()),
22 callback(callback) 21 callback(callback)
23 { 22 {
24 } 23 }
25 24
26 protected: 25 protected:
27 JsEngine& jsEngine; 26 JsEnginePtr jsEngine;
28 FileSystemPtr fileSystem; 27 FileSystemPtr fileSystem;
29 JsValuePtr callback; 28 JsValuePtr callback;
30 }; 29 };
31 30
32 class ReadThread : public IoThread 31 class ReadThread : public IoThread
33 { 32 {
34 public: 33 public:
35 ReadThread(JsEngine& jsEngine, JsValuePtr callback, 34 ReadThread(JsEnginePtr jsEngine, JsValuePtr callback,
36 const std::string& path) 35 const std::string& path)
37 : IoThread(jsEngine, callback), path(path) 36 : IoThread(jsEngine, callback), path(path)
38 { 37 {
39 } 38 }
40 39
41 void Run() 40 void Run()
42 { 41 {
43 std::string content; 42 std::string content;
44 std::string error; 43 std::string error;
45 try 44 try
46 { 45 {
47 std::tr1::shared_ptr<std::istream> stream = fileSystem->Read(path); 46 std::tr1::shared_ptr<std::istream> stream = fileSystem->Read(path);
48 content = Utils::Slurp(*stream); 47 content = Utils::Slurp(*stream);
49 } 48 }
50 catch (std::exception& e) 49 catch (std::exception& e)
51 { 50 {
52 error = e.what(); 51 error = e.what();
53 } 52 }
54 catch (...) 53 catch (...)
55 { 54 {
56 error = "Unknown error while reading from " + path; 55 error = "Unknown error while reading from " + path;
57 } 56 }
58 57
59 const JsEngine::Context context(jsEngine); 58 const JsEngine::Context context(jsEngine);
60 JsValuePtr result = jsEngine.NewObject(); 59 JsValuePtr result = jsEngine->NewObject();
61 result->SetProperty("content", content); 60 result->SetProperty("content", content);
62 result->SetProperty("error", error); 61 result->SetProperty("error", error);
63 JsValueList params; 62 JsValueList params;
64 params.push_back(result); 63 params.push_back(result);
65 callback->Call(params); 64 callback->Call(params);
66 delete this; 65 delete this;
67 } 66 }
68 67
69 private: 68 private:
70 std::string path; 69 std::string path;
71 }; 70 };
72 71
73 class WriteThread : public IoThread 72 class WriteThread : public IoThread
74 { 73 {
75 public: 74 public:
76 WriteThread(JsEngine& jsEngine, JsValuePtr callback, 75 WriteThread(JsEnginePtr jsEngine, JsValuePtr callback,
77 const std::string& path, const std::string& content) 76 const std::string& path, const std::string& content)
78 : IoThread(jsEngine, callback), path(path), content(content) 77 : IoThread(jsEngine, callback), path(path), content(content)
79 { 78 {
80 } 79 }
81 80
82 void Run() 81 void Run()
83 { 82 {
84 std::string error; 83 std::string error;
85 try 84 try
86 { 85 {
87 std::tr1::shared_ptr<std::ostream> stream(new std::stringstream); 86 std::tr1::shared_ptr<std::ostream> stream(new std::stringstream);
88 *stream << content; 87 *stream << content;
89 fileSystem->Write(path, stream); 88 fileSystem->Write(path, stream);
90 } 89 }
91 catch (std::exception& e) 90 catch (std::exception& e)
92 { 91 {
93 error = e.what(); 92 error = e.what();
94 } 93 }
95 catch (...) 94 catch (...)
96 { 95 {
97 error = "Unknown error while writing to " + path; 96 error = "Unknown error while writing to " + path;
98 } 97 }
99 98
100 const JsEngine::Context context(jsEngine); 99 const JsEngine::Context context(jsEngine);
101 JsValuePtr errorValue = jsEngine.NewValue(error); 100 JsValuePtr errorValue = jsEngine->NewValue(error);
102 JsValueList params; 101 JsValueList params;
103 params.push_back(errorValue); 102 params.push_back(errorValue);
104 callback->Call(params); 103 callback->Call(params);
105 delete this; 104 delete this;
106 } 105 }
107 106
108 private: 107 private:
109 std::string path; 108 std::string path;
110 std::string content; 109 std::string content;
111 }; 110 };
112 111
113 class MoveThread : public IoThread 112 class MoveThread : public IoThread
114 { 113 {
115 public: 114 public:
116 MoveThread(JsEngine& jsEngine, JsValuePtr callback, 115 MoveThread(JsEnginePtr jsEngine, JsValuePtr callback,
117 const std::string& fromPath, const std::string& toPath) 116 const std::string& fromPath, const std::string& toPath)
118 : IoThread(jsEngine, callback), fromPath(fromPath), toPath(toPath) 117 : IoThread(jsEngine, callback), fromPath(fromPath), toPath(toPath)
119 { 118 {
120 } 119 }
121 120
122 void Run() 121 void Run()
123 { 122 {
124 std::string error; 123 std::string error;
125 try 124 try
126 { 125 {
127 fileSystem->Move(fromPath, toPath); 126 fileSystem->Move(fromPath, toPath);
128 } 127 }
129 catch (std::exception& e) 128 catch (std::exception& e)
130 { 129 {
131 error = e.what(); 130 error = e.what();
132 } 131 }
133 catch (...) 132 catch (...)
134 { 133 {
135 error = "Unknown error while moving " + fromPath + " to " + toPath; 134 error = "Unknown error while moving " + fromPath + " to " + toPath;
136 } 135 }
137 136
138 const JsEngine::Context context(jsEngine); 137 const JsEngine::Context context(jsEngine);
139 JsValuePtr errorValue = jsEngine.NewValue(error); 138 JsValuePtr errorValue = jsEngine->NewValue(error);
140 JsValueList params; 139 JsValueList params;
141 params.push_back(errorValue); 140 params.push_back(errorValue);
142 callback->Call(params); 141 callback->Call(params);
143 delete this; 142 delete this;
144 } 143 }
145 144
146 private: 145 private:
147 std::string fromPath; 146 std::string fromPath;
148 std::string toPath; 147 std::string toPath;
149 }; 148 };
150 149
151 class RemoveThread : public IoThread 150 class RemoveThread : public IoThread
152 { 151 {
153 public: 152 public:
154 RemoveThread(JsEngine& jsEngine, JsValuePtr callback, 153 RemoveThread(JsEnginePtr jsEngine, JsValuePtr callback,
155 const std::string& path) 154 const std::string& path)
156 : IoThread(jsEngine, callback), path(path) 155 : IoThread(jsEngine, callback), path(path)
157 { 156 {
158 } 157 }
159 158
160 void Run() 159 void Run()
161 { 160 {
162 std::string error; 161 std::string error;
163 try 162 try
164 { 163 {
165 fileSystem->Remove(path); 164 fileSystem->Remove(path);
166 } 165 }
167 catch (std::exception& e) 166 catch (std::exception& e)
168 { 167 {
169 error = e.what(); 168 error = e.what();
170 } 169 }
171 catch (...) 170 catch (...)
172 { 171 {
173 error = "Unknown error while removing " + path; 172 error = "Unknown error while removing " + path;
174 } 173 }
175 174
176 const JsEngine::Context context(jsEngine); 175 const JsEngine::Context context(jsEngine);
177 JsValuePtr errorValue = jsEngine.NewValue(error); 176 JsValuePtr errorValue = jsEngine->NewValue(error);
178 JsValueList params; 177 JsValueList params;
179 params.push_back(errorValue); 178 params.push_back(errorValue);
180 callback->Call(params); 179 callback->Call(params);
181 delete this; 180 delete this;
182 } 181 }
183 182
184 private: 183 private:
185 std::string path; 184 std::string path;
186 }; 185 };
187 186
188 class StatThread : public IoThread 187 class StatThread : public IoThread
189 { 188 {
190 public: 189 public:
191 StatThread(JsEngine& jsEngine, JsValuePtr callback, 190 StatThread(JsEnginePtr jsEngine, JsValuePtr callback,
192 const std::string& path) 191 const std::string& path)
193 : IoThread(jsEngine, callback), path(path) 192 : IoThread(jsEngine, callback), path(path)
194 { 193 {
195 } 194 }
196 195
197 void Run() 196 void Run()
198 { 197 {
199 std::string error; 198 std::string error;
200 FileSystem::StatResult statResult; 199 FileSystem::StatResult statResult;
201 try 200 try
202 { 201 {
203 statResult = fileSystem->Stat(path); 202 statResult = fileSystem->Stat(path);
204 } 203 }
205 catch (std::exception& e) 204 catch (std::exception& e)
206 { 205 {
207 error = e.what(); 206 error = e.what();
208 } 207 }
209 catch (...) 208 catch (...)
210 { 209 {
211 error = "Unknown error while calling stat on " + path; 210 error = "Unknown error while calling stat on " + path;
212 } 211 }
213 212
214 const JsEngine::Context context(jsEngine); 213 const JsEngine::Context context(jsEngine);
215 JsValuePtr result = jsEngine.NewObject(); 214 JsValuePtr result = jsEngine->NewObject();
216 result->SetProperty("exists", statResult.exists); 215 result->SetProperty("exists", statResult.exists);
217 result->SetProperty("isFile", statResult.isFile); 216 result->SetProperty("isFile", statResult.isFile);
218 result->SetProperty("isDirectory", statResult.isDirectory); 217 result->SetProperty("isDirectory", statResult.isDirectory);
219 result->SetProperty("lastModified", statResult.lastModified); 218 result->SetProperty("lastModified", statResult.lastModified);
220 result->SetProperty("error", error); 219 result->SetProperty("error", error);
221 220
222 JsValueList params; 221 JsValueList params;
223 params.push_back(result); 222 params.push_back(result);
224 callback->Call(params); 223 callback->Call(params);
225 delete this; 224 delete this;
226 } 225 }
227 226
228 private: 227 private:
229 std::string path; 228 std::string path;
230 }; 229 };
231 230
232 v8::Handle<v8::Value> ReadCallback(const v8::Arguments& arguments) 231 v8::Handle<v8::Value> ReadCallback(const v8::Arguments& arguments)
233 { 232 {
234 AdblockPlus::JsEngine& jsEngine = AdblockPlus::JsEngine::FromArguments(argum ents); 233 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments);
235 AdblockPlus::JsValueList converted = jsEngine.ConvertArguments(arguments); 234 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments);
236 235
237 if (converted.size() != 2) 236 if (converted.size() != 2)
238 return v8::ThrowException(v8::String::New( 237 return v8::ThrowException(v8::String::New(
239 "_fileSystem.read requires 2 parameters")); 238 "_fileSystem.read requires 2 parameters"));
240 if (!converted[1]->IsFunction()) 239 if (!converted[1]->IsFunction())
241 return v8::ThrowException(v8::String::New( 240 return v8::ThrowException(v8::String::New(
242 "Second argument to _fileSystem.read must be a function")); 241 "Second argument to _fileSystem.read must be a function"));
243 ReadThread* const readThread = new ReadThread(jsEngine, converted[1], 242 ReadThread* const readThread = new ReadThread(jsEngine, converted[1],
244 converted[0]->AsString()); 243 converted[0]->AsString());
245 readThread->Start(); 244 readThread->Start();
246 return v8::Undefined(); 245 return v8::Undefined();
247 } 246 }
248 247
249 v8::Handle<v8::Value> WriteCallback(const v8::Arguments& arguments) 248 v8::Handle<v8::Value> WriteCallback(const v8::Arguments& arguments)
250 { 249 {
251 AdblockPlus::JsEngine& jsEngine = AdblockPlus::JsEngine::FromArguments(argum ents); 250 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments);
252 AdblockPlus::JsValueList converted = jsEngine.ConvertArguments(arguments); 251 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments);
253 252
254 if (converted.size() != 3) 253 if (converted.size() != 3)
255 return v8::ThrowException(v8::String::New( 254 return v8::ThrowException(v8::String::New(
256 "_fileSystem.write requires 3 parameters")); 255 "_fileSystem.write requires 3 parameters"));
257 if (!converted[2]->IsFunction()) 256 if (!converted[2]->IsFunction())
258 return v8::ThrowException(v8::String::New( 257 return v8::ThrowException(v8::String::New(
259 "Third argument to _fileSystem.write must be a function")); 258 "Third argument to _fileSystem.write must be a function"));
260 WriteThread* const writeThread = new WriteThread(jsEngine, converted[2], 259 WriteThread* const writeThread = new WriteThread(jsEngine, converted[2],
261 converted[0]->AsString(), converted[1]->AsString()); 260 converted[0]->AsString(), converted[1]->AsString());
262 writeThread->Start(); 261 writeThread->Start();
263 return v8::Undefined(); 262 return v8::Undefined();
264 } 263 }
265 264
266 v8::Handle<v8::Value> MoveCallback(const v8::Arguments& arguments) 265 v8::Handle<v8::Value> MoveCallback(const v8::Arguments& arguments)
267 { 266 {
268 AdblockPlus::JsEngine& jsEngine = AdblockPlus::JsEngine::FromArguments(argum ents); 267 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments);
269 AdblockPlus::JsValueList converted = jsEngine.ConvertArguments(arguments); 268 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments);
270 269
271 if (converted.size() != 3) 270 if (converted.size() != 3)
272 return v8::ThrowException(v8::String::New( 271 return v8::ThrowException(v8::String::New(
273 "_fileSystem.move requires 3 parameters")); 272 "_fileSystem.move requires 3 parameters"));
274 if (!converted[2]->IsFunction()) 273 if (!converted[2]->IsFunction())
275 return v8::ThrowException(v8::String::New( 274 return v8::ThrowException(v8::String::New(
276 "Third argument to _fileSystem.move must be a function")); 275 "Third argument to _fileSystem.move must be a function"));
277 MoveThread* const moveThread = new MoveThread(jsEngine, converted[2], 276 MoveThread* const moveThread = new MoveThread(jsEngine, converted[2],
278 converted[0]->AsString(), converted[1]->AsString()); 277 converted[0]->AsString(), converted[1]->AsString());
279 moveThread->Start(); 278 moveThread->Start();
280 return v8::Undefined(); 279 return v8::Undefined();
281 } 280 }
282 281
283 v8::Handle<v8::Value> RemoveCallback(const v8::Arguments& arguments) 282 v8::Handle<v8::Value> RemoveCallback(const v8::Arguments& arguments)
284 { 283 {
285 AdblockPlus::JsEngine& jsEngine = AdblockPlus::JsEngine::FromArguments(argum ents); 284 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments);
286 AdblockPlus::JsValueList converted = jsEngine.ConvertArguments(arguments); 285 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments);
287 286
288 if (converted.size() != 2) 287 if (converted.size() != 2)
289 return v8::ThrowException(v8::String::New( 288 return v8::ThrowException(v8::String::New(
290 "_fileSystem.remove requires 2 parameters")); 289 "_fileSystem.remove requires 2 parameters"));
291 if (!converted[1]->IsFunction()) 290 if (!converted[1]->IsFunction())
292 return v8::ThrowException(v8::String::New( 291 return v8::ThrowException(v8::String::New(
293 "Second argument to _fileSystem.remove must be a function")); 292 "Second argument to _fileSystem.remove must be a function"));
294 RemoveThread* const removeThread = new RemoveThread(jsEngine, converted[1], 293 RemoveThread* const removeThread = new RemoveThread(jsEngine, converted[1],
295 converted[0]->AsString()); 294 converted[0]->AsString());
296 removeThread->Start(); 295 removeThread->Start();
297 return v8::Undefined(); 296 return v8::Undefined();
298 } 297 }
299 298
300 v8::Handle<v8::Value> StatCallback(const v8::Arguments& arguments) 299 v8::Handle<v8::Value> StatCallback(const v8::Arguments& arguments)
301 { 300 {
302 AdblockPlus::JsEngine& jsEngine = AdblockPlus::JsEngine::FromArguments(argum ents); 301 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments);
303 AdblockPlus::JsValueList converted = jsEngine.ConvertArguments(arguments); 302 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments);
304 303
305 if (converted.size() != 2) 304 if (converted.size() != 2)
306 return v8::ThrowException(v8::String::New( 305 return v8::ThrowException(v8::String::New(
307 "_fileSystem.stat requires 2 parameters")); 306 "_fileSystem.stat requires 2 parameters"));
308 if (!converted[1]->IsFunction()) 307 if (!converted[1]->IsFunction())
309 return v8::ThrowException(v8::String::New( 308 return v8::ThrowException(v8::String::New(
310 "Second argument to _fileSystem.stat must be a function")); 309 "Second argument to _fileSystem.stat must be a function"));
311 StatThread* const statThread = new StatThread(jsEngine, converted[1], 310 StatThread* const statThread = new StatThread(jsEngine, converted[1],
312 converted[0]->AsString()); 311 converted[0]->AsString());
313 statThread->Start(); 312 statThread->Start();
314 return v8::Undefined(); 313 return v8::Undefined();
315 } 314 }
316 } 315 }
317 316
318 JsValuePtr FileSystemJsObject::Setup(JsEngine& jsEngine, JsValuePtr obj) 317 JsValuePtr FileSystemJsObject::Setup(JsEnginePtr jsEngine, JsValuePtr obj)
319 { 318 {
320 obj->SetProperty("read", jsEngine.NewCallback(::ReadCallback)); 319 obj->SetProperty("read", jsEngine->NewCallback(::ReadCallback));
321 obj->SetProperty("write", jsEngine.NewCallback(::WriteCallback)); 320 obj->SetProperty("write", jsEngine->NewCallback(::WriteCallback));
322 obj->SetProperty("move", jsEngine.NewCallback(::MoveCallback)); 321 obj->SetProperty("move", jsEngine->NewCallback(::MoveCallback));
323 obj->SetProperty("remove", jsEngine.NewCallback(::RemoveCallback)); 322 obj->SetProperty("remove", jsEngine->NewCallback(::RemoveCallback));
324 obj->SetProperty("stat", jsEngine.NewCallback(::StatCallback)); 323 obj->SetProperty("stat", jsEngine->NewCallback(::StatCallback));
325 return obj; 324 return obj;
326 } 325 }
OLDNEW
« no previous file with comments | « src/FileSystemJsObject.h ('k') | src/FilterEngine.cpp » ('j') | src/JsEngine.cpp » ('J')

Powered by Google App Engine
This is Rietveld