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
This commit is contained in:
Cory McWilliams 2016-04-16 21:30:52 +00:00
parent 74af1d361c
commit 6410b13ece
10 changed files with 89 additions and 56 deletions

View File

@ -328,13 +328,18 @@ function getProcess(packageOwner, packageName, key, options) {
} }
} }
if (manifest && manifest.require) { 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); process.task.setImports(imports);
print("Activating task"); print("Activating task");
process.task.activate(); process.task.activate();
print("Executing task"); print("Executing task");
process.task.execute(fileName).then(function() { process.task.execute({name: fileName, source: File.readFile(fileName)}).then(function() {
print("Task ready"); print("Task ready");
broadcastEvent('onSessionBegin', [getUser(process, process)]); broadcastEvent('onSessionBegin', [getUser(process, process)]);
resolveReady(process); resolveReady(process);

View File

@ -105,6 +105,7 @@ Task::Task() {
Task::~Task() { Task::~Task() {
_exportObject.Reset(); _exportObject.Reset();
_sourceObject.Reset();
{ {
v8::Isolate::Scope isolateScope(_isolate); 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, "print"), v8::FunctionTemplate::New(_isolate, print));
global->Set(v8::String::NewFromUtf8(_isolate, "setTimeout"), v8::FunctionTemplate::New(_isolate, setTimeout)); 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->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, "exit"), v8::FunctionTemplate::New(_isolate, exit));
global->Set(v8::String::NewFromUtf8(_isolate, "utf8Length"), v8::FunctionTemplate::New(_isolate, utf8Length)); 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, "version"), version);
global->SetAccessor(v8::String::NewFromUtf8(_isolate, "statistics"), statistics); global->SetAccessor(v8::String::NewFromUtf8(_isolate, "statistics"), statistics);
if (_trusted) { 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, "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, "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, "Task"), v8::FunctionTemplate::New(_isolate, TaskStub::create));
global->Set(v8::String::NewFromUtf8(_isolate, "TlsContext"), v8::FunctionTemplate::New(_isolate, TlsContextWrapper::create)); global->Set(v8::String::NewFromUtf8(_isolate, "TlsContext"), v8::FunctionTemplate::New(_isolate, TlsContextWrapper::create));
File::configure(_isolate, global); 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<v8::Context> context = v8::Context::New(_isolate, 0, global); v8::Local<v8::Context> context = v8::Context::New(_isolate, 0, global);
@ -654,29 +659,10 @@ void Task::onReceivePacket(int packetType, const char* begin, size_t length, voi
} }
} }
break; break;
case kSetTrusted: case kSetRequires:
{ {
assert(length == sizeof(bool)); v8::Handle<v8::Object> result = v8::Handle<v8::Object>::Cast(Serialize::load(to, from, std::vector<char>(begin, begin + length)));
bool trusted = false; to->_sourceObject = v8::Persistent<v8::Object, v8::CopyablePersistentTraits<v8::Object> >(to->_isolate, result);
memcpy(&trusted, begin, sizeof(bool));
to->_trusted = trusted;
}
break;
case kAddPath:
{
v8::Handle<v8::Array> result = v8::Handle<v8::Array>::Cast(Serialize::load(to, from, std::vector<char>(begin, begin + length)));
if (!result.IsEmpty()) {
for (size_t i = 0; i < result->Length(); ++i) {
v8::Handle<v8::Value> handle = result->Get(i);
if (!handle.IsEmpty()) {
v8::Handle<v8::String> entry = handle.As<v8::String>();
if (!entry.IsEmpty()) {
v8::String::Utf8Value value(entry);
to->_path.push_back(*value);
}
}
}
}
} }
break; break;
case kActivate: case kActivate:
@ -685,14 +671,16 @@ void Task::onReceivePacket(int packetType, const char* begin, size_t length, voi
case kExecute: case kExecute:
{ {
assert(length >= sizeof(promiseid_t)); assert(length >= sizeof(promiseid_t));
v8::Handle<v8::Value> arg;
promiseid_t promise; promiseid_t promise;
std::memcpy(&promise, begin, sizeof(promiseid_t)); std::memcpy(&promise, begin, sizeof(promiseid_t));
arg = Serialize::load(to, from, std::vector<char>(begin + sizeof(promiseid_t), begin + length));
v8::TryCatch tryCatch(to->_isolate); v8::TryCatch tryCatch(to->_isolate);
tryCatch.SetCaptureMessage(true); tryCatch.SetCaptureMessage(true);
tryCatch.SetVerbose(true); tryCatch.SetVerbose(true);
to->execute(*v8::String::Utf8Value(arg)); v8::Handle<v8::Value> value = Serialize::load(to, from, std::vector<char>(begin + sizeof(promiseid_t), begin + length));
v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value);
v8::Handle<v8::String> source = v8::Handle<v8::String>::Cast(object->Get(v8::String::NewFromUtf8(to->_isolate, "source")));
v8::Handle<v8::String> name = v8::Handle<v8::String>::Cast(object->Get(v8::String::NewFromUtf8(to->_isolate, "name")));
to->executeSource(source, name);
if (tryCatch.HasCaught()) { if (tryCatch.HasCaught()) {
sendPromiseReject(to, from, promise, Serialize::store(to, tryCatch)); 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<v8::Value>& args) { void Task::require(const v8::FunctionCallbackInfo<v8::Value>& args) {
std::cout << "regular require\n";
v8::HandleScope scope(args.GetIsolate()); v8::HandleScope scope(args.GetIsolate());
Task* task = Task::get(args.GetIsolate()); Task* task = Task::get(args.GetIsolate());
v8::String::Utf8Value pathValue(args[0]); v8::String::Utf8Value pathValue(args[0]);
@ -788,3 +777,58 @@ void Task::require(const v8::FunctionCallbackInfo<v8::Value>& args) {
args.GetReturnValue().Set(args.GetIsolate()->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(args.GetIsolate(), "require(): No module specified.")))); args.GetReturnValue().Set(args.GetIsolate()->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(args.GetIsolate(), "require(): No module specified."))));
} }
} }
v8::Handle<v8::Value> Task::executeSource(v8::Handle<v8::String>& source, v8::Handle<v8::String>& name) {
v8::Isolate::Scope isolateScope(_isolate);
v8::HandleScope handleScope(_isolate);
v8::Context::Scope contextScope(v8::Local<v8::Context>::New(_isolate, _context));
v8::Handle<v8::Value> result;
v8::String::Utf8Value nameValue(name);
if (!source.IsEmpty()) {
v8::Handle<v8::Script> 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<v8::Value>& args) {
std::cout << "childRequire\n";
v8::HandleScope scope(args.GetIsolate());
Task* task = Task::get(args.GetIsolate());
v8::Handle<v8::Object> requiresObject = v8::Local<v8::Object>::New(args.GetIsolate(), task->_sourceObject);
if (!requiresObject.IsEmpty()) {
v8::Handle<v8::String> name = args[0]->ToString();
v8::String::Utf8Value nameValue(name);
ScriptExportMap::iterator it = task->_scriptExports.find(*nameValue);
if (it != task->_scriptExports.end()) {
v8::Handle<v8::Object> exports = v8::Local<v8::Object>::New(args.GetIsolate(), it->second);
args.GetReturnValue().Set(exports);
} else {
v8::Handle<v8::Object> exports = v8::Object::New(args.GetIsolate());
v8::Handle<v8::String> source = v8::Handle<v8::String>::Cast(requiresObject->Get(args[0]));
if (!source.IsEmpty()) {
v8::Handle<v8::Object> global = args.GetIsolate()->GetCurrentContext()->Global();
v8::Handle<v8::Value> oldExports = global->Get(v8::String::NewFromUtf8(args.GetIsolate(), "exports"));
global->Set(v8::String::NewFromUtf8(args.GetIsolate(), "exports"), exports);
v8::Handle<v8::Script> 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()))));
}
}
}
}

View File

@ -30,8 +30,7 @@ enum MessageType {
kInvokeExport, kInvokeExport,
kReleaseExport, kReleaseExport,
kReleaseImport, kReleaseImport,
kSetTrusted, kSetRequires,
kAddPath,
kActivate, kActivate,
kExecute, kExecute,
kKill, kKill,
@ -120,6 +119,7 @@ private:
v8::Persistent<v8::Object, v8::CopyablePersistentTraits<v8::Object> > _importObject; v8::Persistent<v8::Object, v8::CopyablePersistentTraits<v8::Object> > _importObject;
v8::Persistent<v8::Object, v8::CopyablePersistentTraits<v8::Object> > _exportObject; v8::Persistent<v8::Object, v8::CopyablePersistentTraits<v8::Object> > _exportObject;
v8::Persistent<v8::Object, v8::CopyablePersistentTraits<v8::Object> > _sourceObject;
v8::Handle<v8::Object> getStatistics(); v8::Handle<v8::Object> getStatistics();
@ -129,6 +129,7 @@ private:
static void exit(const v8::FunctionCallbackInfo<v8::Value>& args); static void exit(const v8::FunctionCallbackInfo<v8::Value>& args);
static void print(const v8::FunctionCallbackInfo<v8::Value>& args); static void print(const v8::FunctionCallbackInfo<v8::Value>& args);
static void require(const v8::FunctionCallbackInfo<v8::Value>& args); static void require(const v8::FunctionCallbackInfo<v8::Value>& args);
static void childRequire(const v8::FunctionCallbackInfo<v8::Value>& args);
static void setTimeout(const v8::FunctionCallbackInfo<v8::Value>& args); static void setTimeout(const v8::FunctionCallbackInfo<v8::Value>& args);
static void timeoutCallback(uv_timer_t* handle); 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<v8::Value> result); static void sendPromiseExportMessage(Task* from, TaskStub* to, MessageType messageType, promiseid_t promiseId, exportid_t exportId, v8::Handle<v8::Value> result);
static v8::Handle<v8::String> loadFile(v8::Isolate* isolate, const char* fileName); static v8::Handle<v8::String> loadFile(v8::Isolate* isolate, const char* fileName);
v8::Handle<v8::Value> executeSource(v8::Handle<v8::String>& source, v8::Handle<v8::String>& name);
friend struct ImportRecord; friend struct ImportRecord;
friend class TaskStub; friend class TaskStub;

View File

@ -83,7 +83,6 @@ void TaskStub::create(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Handle<v8::External> data = v8::External::New(args.GetIsolate(), stub); v8::Handle<v8::External> data = v8::External::New(args.GetIsolate(), stub);
v8::Handle<v8::ObjectTemplate> taskTemplate = v8::ObjectTemplate::New(args.GetIsolate()); v8::Handle<v8::ObjectTemplate> 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(), "setImports"), v8::FunctionTemplate::New(args.GetIsolate(), setImports, data));
taskTemplate->Set(v8::String::NewFromUtf8(args.GetIsolate(), "getExports"), v8::FunctionTemplate::New(args.GetIsolate(), getExports, 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); taskTemplate->SetAccessor(v8::String::NewFromUtf8(args.GetIsolate(), "onExit"), getOnExit, setOnExit, data);
@ -91,7 +90,7 @@ void TaskStub::create(const v8::FunctionCallbackInfo<v8::Value>& args) {
taskTemplate->Set(v8::String::NewFromUtf8(args.GetIsolate(), "execute"), v8::FunctionTemplate::New(args.GetIsolate(), TaskStub::execute, data)); 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(), "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(), "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); taskTemplate->SetInternalFieldCount(1);
v8::Handle<v8::Object> taskObject = taskTemplate->NewInstance(); v8::Handle<v8::Object> 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<v8::Object, TaskStub>& data) { void TaskStub::onRelease(const v8::WeakCallbackData<v8::Object, TaskStub>& data) {
} }
void TaskStub::getTrusted(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value>& args) {
args.GetReturnValue().Set(v8::Boolean::New(args.GetIsolate(), false));
}
void TaskStub::setTrusted(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& args) {
if (TaskStub* stub = TaskStub::get(args.Data())) {
bool trusted = value->BooleanValue();
stub->_stream.send(kSetTrusted, reinterpret_cast<char*>(&trusted), sizeof(trusted));
}
}
void TaskStub::getExports(const v8::FunctionCallbackInfo<v8::Value>& args) { void TaskStub::getExports(const v8::FunctionCallbackInfo<v8::Value>& args) {
if (TaskStub* stub = TaskStub::get(args.Data())) { if (TaskStub* stub = TaskStub::get(args.Data())) {
TaskTryCatch tryCatch(stub->_owner); TaskTryCatch tryCatch(stub->_owner);
@ -196,11 +184,11 @@ void TaskStub::setImports(const v8::FunctionCallbackInfo<v8::Value>& args) {
} }
} }
void TaskStub::addPath(const v8::FunctionCallbackInfo<v8::Value>& args) { void TaskStub::setRequires(const v8::FunctionCallbackInfo<v8::Value>& args) {
if (TaskStub* stub = TaskStub::get(args.Data())) { if (TaskStub* stub = TaskStub::get(args.Data())) {
std::vector<char> buffer; std::vector<char> buffer;
Serialize::store(Task::get(args.GetIsolate()), buffer, args[0]); 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());
} }
} }

View File

@ -41,13 +41,10 @@ private:
static TaskStub* get(v8::Handle<v8::Value> object); static TaskStub* get(v8::Handle<v8::Value> object);
static void getTrusted(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value>& args);
static void setTrusted(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& args);
static void getExports(const v8::FunctionCallbackInfo<v8::Value>& args); static void getExports(const v8::FunctionCallbackInfo<v8::Value>& args);
static void setImports(const v8::FunctionCallbackInfo<v8::Value>& args); static void setImports(const v8::FunctionCallbackInfo<v8::Value>& args);
static void addPath(const v8::FunctionCallbackInfo<v8::Value>& args); static void setRequires(const v8::FunctionCallbackInfo<v8::Value>& args);
static void getOnExit(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value>& args); static void getOnExit(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value>& args);
static void setOnExit(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& args); static void setOnExit(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& args);

View File

@ -43,12 +43,9 @@ void shedPrivileges() {
if (setrlimit(RLIMIT_MSGQUEUE, &zeroLimit) != 0) { if (setrlimit(RLIMIT_MSGQUEUE, &zeroLimit) != 0) {
perror("setrlimit(RLIMIT_MSGQUEUE, {0, 0})"); perror("setrlimit(RLIMIT_MSGQUEUE, {0, 0})");
} }
/*
XXX
if (setrlimit(RLIMIT_NOFILE, &zeroLimit) != 0) { if (setrlimit(RLIMIT_NOFILE, &zeroLimit) != 0) {
perror("setrlimit(RLIMIT_NOFILE, {0, 0})"); perror("setrlimit(RLIMIT_NOFILE, {0, 0})");
} }
*/
if (setrlimit(RLIMIT_NPROC, &zeroLimit) != 0) { if (setrlimit(RLIMIT_NPROC, &zeroLimit) != 0) {
perror("setrlimit(RLIMIT_NPROC, {0, 0})"); perror("setrlimit(RLIMIT_NPROC, {0, 0})");
} }

View File

@ -6,7 +6,7 @@ task.onExit = function() {
print("child exited"); print("child exited");
}; };
task.activate(); task.activate();
task.execute("child.js").then(function() { task.execute({name: "child.js", source: File.readFile("child.js")}).then(function() {
print("child started"); print("child started");
}); });
EOF EOF

View File

@ -3,7 +3,7 @@
cat > test.js << EOF cat > test.js << EOF
var task = new Task(); var task = new Task();
task.activate(); 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) { task.getExports().then(function(exports) {
return exports.add(1, 1); return exports.add(1, 1);
}).then(function(sum) { }).then(function(sum) {

View File

@ -3,7 +3,7 @@
cat > test.js << EOF cat > test.js << EOF
var task = new Task(); var task = new Task();
task.activate(); 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) { task.getExports().then(function(exports) {
return exports.add(1, 1); return exports.add(1, 1);
}).then(function(sum) { }).then(function(sum) {

View File

@ -3,7 +3,7 @@
cat > test.js << EOF cat > test.js << EOF
var task = new Task(); var task = new Task();
task.activate(); 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) { task.getExports().then(function(exports) {
return exports.add(1, 1); return exports.add(1, 1);
}).then(function(sum) { }).then(function(sum) {