[vm/io] Range check Socket_SendMessage arguments
Closes https://github.com/dart-lang/sdk/pull/63365 GitOrigin-RevId: 344604dd1a17b73c6665026e7e75693fe0fa7ca7 Change-Id: I8f51d5735a56564f2181bcd1206c9cfdff80f077 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/502960 Reviewed-by: Slava Egorov <vegorov@google.com> Commit-Queue: Slava Egorov <vegorov@google.com>
This commit is contained in:
committed by
dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent
119d9d72b7
commit
1d80afe498
@@ -828,7 +828,12 @@ void FUNCTION_NAME(Socket_SendMessage)(Dart_NativeArguments args) {
|
||||
Dart_Handle buffer_dart = Dart_GetNativeArgument(args, 1);
|
||||
TypedDataScope data(buffer_dart);
|
||||
|
||||
ASSERT((offset + length) <= data.size_in_bytes());
|
||||
const intptr_t end = offset + length;
|
||||
if (!(0 <= offset && offset <= end && end <= data.size_in_bytes())) {
|
||||
delete os_error;
|
||||
Dart_SetReturnValue(args, Dart_NewApiError("Invalid range"));
|
||||
return;
|
||||
}
|
||||
uint8_t* buffer_at_offset =
|
||||
reinterpret_cast<uint8_t*>(data.data()) + offset;
|
||||
bytes_written = SocketBase::SendMessage(
|
||||
|
||||
@@ -1524,7 +1524,7 @@ base class _NativeSocket extends _NativeSocketNativeWrapper
|
||||
_BufferAndStart bufferAndStart = _ensureFastAndSerializableByteData(
|
||||
buffer,
|
||||
offset,
|
||||
bytes,
|
||||
offset + bytes,
|
||||
);
|
||||
if (!const bool.fromEnvironment("dart.vm.product")) {
|
||||
_SocketProfile.collectStatistic(
|
||||
@@ -1568,7 +1568,7 @@ base class _NativeSocket extends _NativeSocketNativeWrapper
|
||||
_BufferAndStart bufferAndStart = _ensureFastAndSerializableByteData(
|
||||
buffer,
|
||||
offset,
|
||||
bytes,
|
||||
offset + bytes,
|
||||
);
|
||||
if (!const bool.fromEnvironment("dart.vm.product")) {
|
||||
_SocketProfile.collectStatistic(
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
// Copyright (c) 2026, 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.
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
|
||||
Future<void> main() async {
|
||||
// sendMessage with control messages is POSIX-only.
|
||||
if (!(Platform.isLinux || Platform.isMacOS)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final server = await ServerSocket.bind(InternetAddress.loopbackIPv4, 0);
|
||||
final got = Completer<List<int>>();
|
||||
|
||||
server.listen((sock) {
|
||||
sock.close();
|
||||
got.complete(sock.expand((v) => v).toList());
|
||||
});
|
||||
|
||||
final client = await RawSocket.connect(
|
||||
InternetAddress.loopbackIPv4,
|
||||
server.port,
|
||||
);
|
||||
|
||||
// `data` is a plain `List<int>` (not a `Uint8List`), forcing the helper
|
||||
// to take its copy path.
|
||||
final data = List<int>.generate(16, (i) => i);
|
||||
|
||||
client.sendMessage(const <SocketControlMessage>[], data, 5, 10);
|
||||
client.close();
|
||||
|
||||
final received = await got.future.timeout(const Duration(seconds: 5));
|
||||
await server.close();
|
||||
|
||||
Expect.equals(10, received.length);
|
||||
Expect.listEquals(<int>[5, 6, 7, 8, 9, 10, 11, 12, 13, 14], received);
|
||||
}
|
||||
Reference in New Issue
Block a user