[io] Avoid uncatchable error in RawDatagramSocket.bind()
Currently the error happens very late in C code which throws a `Dart_NewApiError()` which isn't catchable via try/catch in Dart. Our `dart:io` APIs should never result in uncatchable errors being thrown. This CL adds the verification that the address is a IPv4/IPv6 address (and not a unix domain socket address) before actually binding the code. Issue https://github.com/dart-lang/sdk/issues/60421 TEST=standalone/io/datagram_error_test Change-Id: I0ead36b8c90dd8b04523f9e64d3be63a8e66a56c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/438140 Commit-Queue: Martin Kustermann <kustermann@google.com> Reviewed-by: Slava Egorov <vegorov@google.com>
This commit is contained in:
committed by
Commit Queue
parent
9918fa0593
commit
9b916b2f14
@@ -1241,6 +1241,13 @@ base class _NativeSocket extends _NativeSocketNativeWrapper
|
||||
|
||||
final address = await _resolveHost(host);
|
||||
|
||||
if (address.type != InternetAddressType.IPv6 &&
|
||||
address.type != InternetAddressType.IPv4) {
|
||||
throw SocketException(
|
||||
'Cannot bind datagram socket on non-IPv4/IPv6 address (was: $address)',
|
||||
);
|
||||
}
|
||||
|
||||
var socket = _NativeSocket.datagram(address);
|
||||
var result = socket._nativeCreateBindDatagram(
|
||||
address._in_addr,
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
// Copyright (c) 2025, 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 test program for testing error path in datagram bind call.
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import "package:expect/expect.dart";
|
||||
|
||||
void main() async {
|
||||
try {
|
||||
final socket = await RawDatagramSocket.bind(
|
||||
InternetAddress('/tmp/test_socket', type: InternetAddressType.unix),
|
||||
0,
|
||||
);
|
||||
Expect.fail(
|
||||
"Should not reach this: "
|
||||
"the bind call above should have failed",
|
||||
);
|
||||
socket.listen((data) {
|
||||
print(data);
|
||||
});
|
||||
} catch (e) {
|
||||
Expect.fail(
|
||||
"Should not reach this: "
|
||||
"the bind call above throws unhandled exception",
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,31 +1,24 @@
|
||||
// Copyright (c) 2025, 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 test program for testing error path in datagram bind call.
|
||||
//
|
||||
// OtherResources=datagram_error.dart
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import "package:async_helper/async_helper.dart";
|
||||
import "package:expect/expect.dart";
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
void main() async {
|
||||
var sdkPath = path.absolute(path.dirname(Platform.executable));
|
||||
var dartPath = path.absolute(
|
||||
sdkPath,
|
||||
Platform.isWindows ? 'dart.exe' : 'dart',
|
||||
);
|
||||
// Get the Dart script file that generates output.
|
||||
var scriptFile = new File(
|
||||
Platform.script.resolve("datagram_error.dart").toFilePath(),
|
||||
);
|
||||
var args = <String>[scriptFile.path];
|
||||
ProcessResult syncResult = Process.runSync(dartPath, args);
|
||||
Expect.notEquals(0, syncResult.exitCode);
|
||||
Expect.stringEquals(
|
||||
syncResult.stderr,
|
||||
"Unexpected type for socket address" + Platform.lineTerminator,
|
||||
SocketException? error;
|
||||
try {
|
||||
await RawDatagramSocket.bind(
|
||||
InternetAddress('/tmp/test_socket', type: InternetAddressType.unix),
|
||||
0,
|
||||
);
|
||||
} on SocketException catch (e) {
|
||||
error = e;
|
||||
}
|
||||
Expect.contains(
|
||||
'Cannot bind datagram socket on non-IPv4/IPv6 address',
|
||||
'$error',
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user