Skip to content

Commit

Permalink
[vm/isolates] Ensure spawnUri'ed isolates keep their own origin_id.
Browse files Browse the repository at this point in the history
Fixes #47674

TEST=send_object_to_spawn_uri_isolate_test.dart

Change-Id: I96d81df5edbac3054220348be8654250246cad8b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/220066
Reviewed-by: Siva Annamalai <[email protected]>
Commit-Queue: Alexander Aprelev <[email protected]>
  • Loading branch information
aam authored and [email protected] committed Nov 13, 2021
1 parent 6ae9f31 commit c4a07a8
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 2 deletions.
8 changes: 6 additions & 2 deletions runtime/lib/isolate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ DEFINE_NATIVE_ENTRY(SendPortImpl_sendInternal_, 0, 2) {

const Dart_Port destination_port_id = port.Id();
const bool can_send_any_object = isolate->origin_id() == port.origin_id();
// We have to check whether the reciever has the same isolate group (e.g.
// We have to check whether the receiver has the same isolate group (e.g.
// native message handlers such as an IOService handler does not but does
// share the same origin port).
const bool same_group = PortMap::IsReceiverInThisIsolateGroup(
Expand Down Expand Up @@ -717,7 +717,11 @@ class SpawnIsolateTask : public ThreadPool::Task {
}

state_->set_isolate(child);
child->set_origin_id(state_->origin_id());
if (state_->origin_id() != ILLEGAL_PORT) {
// origin_id is set to parent isolate main port id when spawning via
// spawnFunction.
child->set_origin_id(state_->origin_id());
}

bool success = true;
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
//
// This test ensures that one can't send user dart objects to
// an isolate spawned via spawnUri.

import 'dart:async';
import 'dart:io';
import 'dart:isolate';

import 'package:expect/expect.dart';
import "package:test/test.dart";

class Foo {
var bar = 123;
}

Future<void> main(args, message) async {
if (message == null) {
final receivePort = ReceivePort();
final isolate = await Isolate.spawnUri(
Platform.script, <String>[], <SendPort>[receivePort.sendPort],
errorsAreFatal: true);
final result = await receivePort.first;
Expect.equals("done", result);
return;
}

if (args.length > 0) {
Expect.equals("worker", args[0]);
final SendPort sendPort = message[0] as SendPort;
Expect.throws(() => sendPort.send(Foo()));
sendPort.send("done");
} else {
final SendPort sendPort = message[0] as SendPort;

final receivePort = ReceivePort();
try {
final isolate = await Isolate.spawnUri(
Platform.script, <String>["worker"], <SendPort>[receivePort.sendPort],
errorsAreFatal: true);
final result = await receivePort.first;
Expect.equals("done", result);
sendPort.send("done");
} catch (_) {
sendPort.send("fail");
}

sendPort.send("done");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
//
// @dart = 2.9
//
// This test ensures that one can't send user dart objects to
// an isolate spawned via spawnUri.

import 'dart:async';
import 'dart:io';
import 'dart:isolate';

import 'package:expect/expect.dart';
import "package:test/test.dart";

class Foo {
var bar = 123;
}

Future<void> main(args, message) async {
if (message == null) {
final receivePort = ReceivePort();
final isolate = await Isolate.spawnUri(
Platform.script, <String>[], <SendPort>[receivePort.sendPort],
errorsAreFatal: true);
final result = await receivePort.first;
Expect.equals("done", result);
return;
}

if (args.length > 0) {
Expect.equals("worker", args[0]);
final SendPort sendPort = message[0] as SendPort;
Expect.throws(() => sendPort.send(Foo()));
sendPort.send("done");
} else {
final SendPort sendPort = message[0] as SendPort;

final receivePort = ReceivePort();
try {
final isolate = await Isolate.spawnUri(
Platform.script, <String>["worker"], <SendPort>[receivePort.sendPort],
errorsAreFatal: true);
final result = await receivePort.first;
Expect.equals("done", result);
sendPort.send("done");
} catch (_) {
sendPort.send("fail");
}

sendPort.send("done");
}
}
2 changes: 2 additions & 0 deletions runtime/tests/vm/vm.status
Original file line number Diff line number Diff line change
Expand Up @@ -421,8 +421,10 @@ dart_2/*: SkipByDesign # Legacy tests are not supposed to run on NNBD bots.
# These Isolate tests that use spawnURI are hence skipped on purpose.
[ $runtime == dart_precompiled || $runtime == vm && ($arch == simarm || $arch == simarm64 || $arch == simarm64c) ]
dart/data_uri_spawn_test: SkipByDesign # Isolate.spawnUri
dart/isolates/send_object_to_spawn_uri_isolate_test: SkipByDesign # uses spawnUri
dart/issue32950_test: SkipByDesign # uses spawnUri.
dart_2/data_uri_spawn_test: SkipByDesign # Isolate.spawnUri
dart_2/isolates/send_object_to_spawn_uri_isolate_test: SkipByDesign # uses spawnUri
dart_2/issue32950_test: SkipByDesign # uses spawnUri.

[ $runtime != dart_precompiled || $system == android ]
Expand Down

0 comments on commit c4a07a8

Please sign in to comment.