From 6410b13ecec1b2592017b1bdcfcd2fbfd06e7e9f Mon Sep 17 00:00:00 2001 From: Cory McWilliams Date: Sat, 16 Apr 2016 21:30:52 +0000 Subject: [PATCH] Now child processes have no ability to open files. git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3206 ed5197a5-7fde-0310-b194-c3ffbd925b24 --- core/core.js | 9 +++- src/Task.cpp | 96 +++++++++++++++++++++++++--------- src/Task.h | 6 ++- src/TaskStub.cpp | 18 ++----- src/TaskStub.h | 5 +- src/main.cpp | 3 -- tests/03-child | 2 +- tests/04-promise | 2 +- tests/05-promise-remote-throw | 2 +- tests/07-promise-remote-reject | 2 +- 10 files changed, 89 insertions(+), 56 deletions(-) diff --git a/core/core.js b/core/core.js index ffc0426b..9b7c182f 100644 --- a/core/core.js +++ b/core/core.js @@ -328,13 +328,18 @@ function getProcess(packageOwner, packageName, key, options) { } } if (manifest && manifest.require) { - process.task.addPath(manifest.require.map(packageNameToPath.bind(process))); + let source = {}; + for (let i in manifest.require) { + let name = manifest.require[i]; + source[manifest[i]] = File.readFile("packages/" + process.packageOwner + "/" + name + "/" + name + ".js"); + } + process.task.setRequires(source); } process.task.setImports(imports); print("Activating task"); process.task.activate(); print("Executing task"); - process.task.execute(fileName).then(function() { + process.task.execute({name: fileName, source: File.readFile(fileName)}).then(function() { print("Task ready"); broadcastEvent('onSessionBegin', [getUser(process, process)]); resolveReady(process); diff --git a/src/Task.cpp b/src/Task.cpp index 33d3e7a9..638f701e 100644 --- a/src/Task.cpp +++ b/src/Task.cpp @@ -105,6 +105,7 @@ Task::Task() { Task::~Task() { _exportObject.Reset(); + _sourceObject.Reset(); { v8::Isolate::Scope isolateScope(_isolate); @@ -166,7 +167,6 @@ void Task::activate() { global->Set(v8::String::NewFromUtf8(_isolate, "print"), v8::FunctionTemplate::New(_isolate, print)); global->Set(v8::String::NewFromUtf8(_isolate, "setTimeout"), v8::FunctionTemplate::New(_isolate, setTimeout)); - global->Set(v8::String::NewFromUtf8(_isolate, "require"), v8::FunctionTemplate::New(_isolate, require)); global->SetAccessor(v8::String::NewFromUtf8(_isolate, "parent"), parent); global->Set(v8::String::NewFromUtf8(_isolate, "exit"), v8::FunctionTemplate::New(_isolate, exit)); global->Set(v8::String::NewFromUtf8(_isolate, "utf8Length"), v8::FunctionTemplate::New(_isolate, utf8Length)); @@ -175,11 +175,16 @@ void Task::activate() { global->SetAccessor(v8::String::NewFromUtf8(_isolate, "version"), version); global->SetAccessor(v8::String::NewFromUtf8(_isolate, "statistics"), statistics); if (_trusted) { + std::cout << "parent require\n"; + global->Set(v8::String::NewFromUtf8(_isolate, "require"), v8::FunctionTemplate::New(_isolate, require)); global->Set(v8::String::NewFromUtf8(_isolate, "Database"), v8::FunctionTemplate::New(_isolate, Database::create)); global->Set(v8::String::NewFromUtf8(_isolate, "Socket"), v8::FunctionTemplate::New(_isolate, Socket::create)); global->Set(v8::String::NewFromUtf8(_isolate, "Task"), v8::FunctionTemplate::New(_isolate, TaskStub::create)); global->Set(v8::String::NewFromUtf8(_isolate, "TlsContext"), v8::FunctionTemplate::New(_isolate, TlsContextWrapper::create)); File::configure(_isolate, global); + } else { + std::cout << "setting up child require\n"; + global->Set(v8::String::NewFromUtf8(_isolate, "require"), v8::FunctionTemplate::New(_isolate, childRequire)); } v8::Local context = v8::Context::New(_isolate, 0, global); @@ -654,29 +659,10 @@ void Task::onReceivePacket(int packetType, const char* begin, size_t length, voi } } break; - case kSetTrusted: + case kSetRequires: { - assert(length == sizeof(bool)); - bool trusted = false; - memcpy(&trusted, begin, sizeof(bool)); - to->_trusted = trusted; - } - break; - case kAddPath: - { - v8::Handle result = v8::Handle::Cast(Serialize::load(to, from, std::vector(begin, begin + length))); - if (!result.IsEmpty()) { - for (size_t i = 0; i < result->Length(); ++i) { - v8::Handle handle = result->Get(i); - if (!handle.IsEmpty()) { - v8::Handle entry = handle.As(); - if (!entry.IsEmpty()) { - v8::String::Utf8Value value(entry); - to->_path.push_back(*value); - } - } - } - } + v8::Handle result = v8::Handle::Cast(Serialize::load(to, from, std::vector(begin, begin + length))); + to->_sourceObject = v8::Persistent >(to->_isolate, result); } break; case kActivate: @@ -685,14 +671,16 @@ void Task::onReceivePacket(int packetType, const char* begin, size_t length, voi case kExecute: { assert(length >= sizeof(promiseid_t)); - v8::Handle arg; promiseid_t promise; std::memcpy(&promise, begin, sizeof(promiseid_t)); - arg = Serialize::load(to, from, std::vector(begin + sizeof(promiseid_t), begin + length)); v8::TryCatch tryCatch(to->_isolate); tryCatch.SetCaptureMessage(true); tryCatch.SetVerbose(true); - to->execute(*v8::String::Utf8Value(arg)); + v8::Handle value = Serialize::load(to, from, std::vector(begin + sizeof(promiseid_t), begin + length)); + v8::Handle object = v8::Handle::Cast(value); + v8::Handle source = v8::Handle::Cast(object->Get(v8::String::NewFromUtf8(to->_isolate, "source"))); + v8::Handle name = v8::Handle::Cast(object->Get(v8::String::NewFromUtf8(to->_isolate, "name"))); + to->executeSource(source, name); if (tryCatch.HasCaught()) { sendPromiseReject(to, from, promise, Serialize::store(to, tryCatch)); } @@ -746,6 +734,7 @@ std::string Task::resolveRequire(const std::string& require) { } void Task::require(const v8::FunctionCallbackInfo& args) { + std::cout << "regular require\n"; v8::HandleScope scope(args.GetIsolate()); Task* task = Task::get(args.GetIsolate()); v8::String::Utf8Value pathValue(args[0]); @@ -788,3 +777,58 @@ void Task::require(const v8::FunctionCallbackInfo& args) { args.GetReturnValue().Set(args.GetIsolate()->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(args.GetIsolate(), "require(): No module specified.")))); } } + +v8::Handle Task::executeSource(v8::Handle& source, v8::Handle& name) { + v8::Isolate::Scope isolateScope(_isolate); + v8::HandleScope handleScope(_isolate); + v8::Context::Scope contextScope(v8::Local::New(_isolate, _context)); + + v8::Handle result; + v8::String::Utf8Value nameValue(name); + if (!source.IsEmpty()) { + v8::Handle script = v8::Script::Compile(source, name); + if (!script.IsEmpty()) { + script->Run(); + } else { + result = _isolate->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(_isolate, (std::string("Failed to compile ") + *nameValue + ".").c_str()))); + } + } else { + result = _isolate->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(_isolate, (std::string("Failed to load ") + *nameValue + ".").c_str()))); + } + return result; +} + +void Task::childRequire(const v8::FunctionCallbackInfo& args) { + std::cout << "childRequire\n"; + v8::HandleScope scope(args.GetIsolate()); + Task* task = Task::get(args.GetIsolate()); + + v8::Handle requiresObject = v8::Local::New(args.GetIsolate(), task->_sourceObject); + if (!requiresObject.IsEmpty()) { + v8::Handle name = args[0]->ToString(); + v8::String::Utf8Value nameValue(name); + ScriptExportMap::iterator it = task->_scriptExports.find(*nameValue); + if (it != task->_scriptExports.end()) { + v8::Handle exports = v8::Local::New(args.GetIsolate(), it->second); + args.GetReturnValue().Set(exports); + } else { + v8::Handle exports = v8::Object::New(args.GetIsolate()); + v8::Handle source = v8::Handle::Cast(requiresObject->Get(args[0])); + if (!source.IsEmpty()) { + v8::Handle global = args.GetIsolate()->GetCurrentContext()->Global(); + v8::Handle oldExports = global->Get(v8::String::NewFromUtf8(args.GetIsolate(), "exports")); + global->Set(v8::String::NewFromUtf8(args.GetIsolate(), "exports"), exports); + v8::Handle script = v8::Script::Compile(source, name); + if (!script.IsEmpty()) { + script->Run(); + } else { + args.GetReturnValue().Set(args.GetIsolate()->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(args.GetIsolate(), (std::string("Failed to compile ") + *nameValue + ".").c_str())))); + } + global->Set(v8::String::NewFromUtf8(args.GetIsolate(), "exports"), oldExports); + args.GetReturnValue().Set(exports); + } else { + args.GetReturnValue().Set(args.GetIsolate()->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(args.GetIsolate(), (std::string("Failed to load ") + *nameValue + ".").c_str())))); + } + } + } +} diff --git a/src/Task.h b/src/Task.h index e6a48568..2144a9e1 100644 --- a/src/Task.h +++ b/src/Task.h @@ -30,8 +30,7 @@ enum MessageType { kInvokeExport, kReleaseExport, kReleaseImport, - kSetTrusted, - kAddPath, + kSetRequires, kActivate, kExecute, kKill, @@ -120,6 +119,7 @@ private: v8::Persistent > _importObject; v8::Persistent > _exportObject; + v8::Persistent > _sourceObject; v8::Handle getStatistics(); @@ -129,6 +129,7 @@ private: static void exit(const v8::FunctionCallbackInfo& args); static void print(const v8::FunctionCallbackInfo& args); static void require(const v8::FunctionCallbackInfo& args); + static void childRequire(const v8::FunctionCallbackInfo& args); static void setTimeout(const v8::FunctionCallbackInfo& args); static void timeoutCallback(uv_timer_t* handle); @@ -157,6 +158,7 @@ private: static void sendPromiseExportMessage(Task* from, TaskStub* to, MessageType messageType, promiseid_t promiseId, exportid_t exportId, v8::Handle result); static v8::Handle loadFile(v8::Isolate* isolate, const char* fileName); + v8::Handle executeSource(v8::Handle& source, v8::Handle& name); friend struct ImportRecord; friend class TaskStub; diff --git a/src/TaskStub.cpp b/src/TaskStub.cpp index 350024c2..faf90964 100644 --- a/src/TaskStub.cpp +++ b/src/TaskStub.cpp @@ -83,7 +83,6 @@ void TaskStub::create(const v8::FunctionCallbackInfo& args) { v8::Handle data = v8::External::New(args.GetIsolate(), stub); v8::Handle taskTemplate = v8::ObjectTemplate::New(args.GetIsolate()); - taskTemplate->SetAccessor(v8::String::NewFromUtf8(args.GetIsolate(), "trusted"), getTrusted, setTrusted, data); taskTemplate->Set(v8::String::NewFromUtf8(args.GetIsolate(), "setImports"), v8::FunctionTemplate::New(args.GetIsolate(), setImports, data)); taskTemplate->Set(v8::String::NewFromUtf8(args.GetIsolate(), "getExports"), v8::FunctionTemplate::New(args.GetIsolate(), getExports, data)); taskTemplate->SetAccessor(v8::String::NewFromUtf8(args.GetIsolate(), "onExit"), getOnExit, setOnExit, data); @@ -91,7 +90,7 @@ void TaskStub::create(const v8::FunctionCallbackInfo& args) { taskTemplate->Set(v8::String::NewFromUtf8(args.GetIsolate(), "execute"), v8::FunctionTemplate::New(args.GetIsolate(), TaskStub::execute, data)); taskTemplate->Set(v8::String::NewFromUtf8(args.GetIsolate(), "kill"), v8::FunctionTemplate::New(args.GetIsolate(), TaskStub::kill, data)); taskTemplate->Set(v8::String::NewFromUtf8(args.GetIsolate(), "statistics"), v8::FunctionTemplate::New(args.GetIsolate(), TaskStub::statistics, data)); - taskTemplate->Set(v8::String::NewFromUtf8(args.GetIsolate(), "addPath"), v8::FunctionTemplate::New(args.GetIsolate(), addPath, data)); + taskTemplate->Set(v8::String::NewFromUtf8(args.GetIsolate(), "setRequires"), v8::FunctionTemplate::New(args.GetIsolate(), setRequires, data)); taskTemplate->SetInternalFieldCount(1); v8::Handle taskObject = taskTemplate->NewInstance(); @@ -166,17 +165,6 @@ void TaskStub::onProcessExit(uv_process_t* process, int64_t status, int terminat void TaskStub::onRelease(const v8::WeakCallbackData& data) { } -void TaskStub::getTrusted(v8::Local property, const v8::PropertyCallbackInfo& args) { - args.GetReturnValue().Set(v8::Boolean::New(args.GetIsolate(), false)); -} - -void TaskStub::setTrusted(v8::Local property, v8::Local value, const v8::PropertyCallbackInfo& args) { - if (TaskStub* stub = TaskStub::get(args.Data())) { - bool trusted = value->BooleanValue(); - stub->_stream.send(kSetTrusted, reinterpret_cast(&trusted), sizeof(trusted)); - } -} - void TaskStub::getExports(const v8::FunctionCallbackInfo& args) { if (TaskStub* stub = TaskStub::get(args.Data())) { TaskTryCatch tryCatch(stub->_owner); @@ -196,11 +184,11 @@ void TaskStub::setImports(const v8::FunctionCallbackInfo& args) { } } -void TaskStub::addPath(const v8::FunctionCallbackInfo& args) { +void TaskStub::setRequires(const v8::FunctionCallbackInfo& args) { if (TaskStub* stub = TaskStub::get(args.Data())) { std::vector buffer; Serialize::store(Task::get(args.GetIsolate()), buffer, args[0]); - stub->_stream.send(kAddPath, &*buffer.begin(), buffer.size()); + stub->_stream.send(kSetRequires, &*buffer.begin(), buffer.size()); } } diff --git a/src/TaskStub.h b/src/TaskStub.h index ec581367..97bf9a3e 100644 --- a/src/TaskStub.h +++ b/src/TaskStub.h @@ -41,13 +41,10 @@ private: static TaskStub* get(v8::Handle object); - static void getTrusted(v8::Local property, const v8::PropertyCallbackInfo& args); - static void setTrusted(v8::Local property, v8::Local value, const v8::PropertyCallbackInfo& args); - static void getExports(const v8::FunctionCallbackInfo& args); static void setImports(const v8::FunctionCallbackInfo& args); - static void addPath(const v8::FunctionCallbackInfo& args); + static void setRequires(const v8::FunctionCallbackInfo& args); static void getOnExit(v8::Local property, const v8::PropertyCallbackInfo& args); static void setOnExit(v8::Local property, v8::Local value, const v8::PropertyCallbackInfo& args); diff --git a/src/main.cpp b/src/main.cpp index 36acf763..ea30c4d6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -43,12 +43,9 @@ void shedPrivileges() { if (setrlimit(RLIMIT_MSGQUEUE, &zeroLimit) != 0) { perror("setrlimit(RLIMIT_MSGQUEUE, {0, 0})"); } - /* - XXX if (setrlimit(RLIMIT_NOFILE, &zeroLimit) != 0) { perror("setrlimit(RLIMIT_NOFILE, {0, 0})"); } - */ if (setrlimit(RLIMIT_NPROC, &zeroLimit) != 0) { perror("setrlimit(RLIMIT_NPROC, {0, 0})"); } diff --git a/tests/03-child b/tests/03-child index 162ee9c9..d8210258 100755 --- a/tests/03-child +++ b/tests/03-child @@ -6,7 +6,7 @@ task.onExit = function() { print("child exited"); }; task.activate(); -task.execute("child.js").then(function() { +task.execute({name: "child.js", source: File.readFile("child.js")}).then(function() { print("child started"); }); EOF diff --git a/tests/04-promise b/tests/04-promise index 3acd0dc2..9cbbad7e 100755 --- a/tests/04-promise +++ b/tests/04-promise @@ -3,7 +3,7 @@ cat > test.js << EOF var task = new Task(); task.activate(); -task.execute("child.js").then(function() { +task.execute({name: "child.js", source: File.readFile("child.js")}).then(function() { task.getExports().then(function(exports) { return exports.add(1, 1); }).then(function(sum) { diff --git a/tests/05-promise-remote-throw b/tests/05-promise-remote-throw index 73b23099..9b63b417 100755 --- a/tests/05-promise-remote-throw +++ b/tests/05-promise-remote-throw @@ -3,7 +3,7 @@ cat > test.js << EOF var task = new Task(); task.activate(); -task.execute("child.js").then(function() { +task.execute({name: "child.js", source: File.readFile("child.js")}).then(function() { task.getExports().then(function(exports) { return exports.add(1, 1); }).then(function(sum) { diff --git a/tests/07-promise-remote-reject b/tests/07-promise-remote-reject index dedac2fa..6f426bc9 100755 --- a/tests/07-promise-remote-reject +++ b/tests/07-promise-remote-reject @@ -3,7 +3,7 @@ cat > test.js << EOF var task = new Task(); task.activate(); -task.execute("child.js").then(function() { +task.execute({name: "child.js", source: File.readFile("child.js")}).then(function() { task.getExports().then(function(exports) { return exports.add(1, 1); }).then(function(sum) {