[io] Fix FileSystemEntity.type and Link.exists with IOOverrides

Fixes #63418

When IOOverrides are active, `fseGetType` and `fseGetTypeSync` used
`utf8.encode(path)` which does not null-terminate the path. Native
APIs require null-terminated paths. Through luck the sync path worked
but the async path failed with `notFound`.

Update them to use `FileSystemEntity._toUtf8Array(path)` which correctly
null-terminates the path.

Tested: added a regression test to tests/standalone/io/io_override_test.dart

TAG=agy
CONV=ab6af504-d536-4a8d-88be-bc487b60e24d
R=bkonyi@google.com

CoreLibraryReviewExempt: No API changes.
Change-Id: I24e31efdcbecc703800b96a144e41a095a445cff
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/505201
Reviewed-by: Ben Konyi <bkonyi@google.com>
Commit-Queue: Nate Bosch <nbosch@google.com>
Auto-Submit: Nate Bosch <nbosch@google.com>
This commit is contained in:
Nate Bosch
2026-05-22 14:13:35 -07:00
committed by dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent 1121b4041f
commit b162f6717d
2 changed files with 22 additions and 3 deletions
+8 -2
View File
@@ -259,7 +259,10 @@ abstract base class IOOverrides {
/// When this override is installed, this function overrides the behavior of
/// `FileSystemEntity.type`.
Future<FileSystemEntityType> fseGetType(String path, bool followLinks) {
return FileSystemEntity._getTypeRequest(utf8.encode(path), followLinks);
return FileSystemEntity._getTypeRequest(
FileSystemEntity._toUtf8Array(path),
followLinks,
);
}
/// Returns the [FileSystemEntityType] for [path].
@@ -267,7 +270,10 @@ abstract base class IOOverrides {
/// When this override is installed, this function overrides the behavior of
/// `FileSystemEntity.typeSync`.
FileSystemEntityType fseGetTypeSync(String path, bool followLinks) {
return FileSystemEntity._getTypeSyncHelper(utf8.encode(path), followLinks);
return FileSystemEntity._getTypeSyncHelper(
FileSystemEntity._toUtf8Array(path),
followLinks,
);
}
// _FileSystemWatcher
+14 -1
View File
@@ -349,9 +349,22 @@ void emptyIOOverride() {
);
}
main() async {
Future<void> emptyIOOverrideAsync() async {
await IOOverrides.runWithIOOverrides(
() async => Expect.equals(
await FileSystemEntity.type('/'),
FileSystemEntityType.directory,
),
EmptyOverride(),
);
}
void main() async {
asyncStart();
await ioOverridesRunTest();
globalIOOverridesTest();
globalIOOverridesZoneTest();
emptyIOOverride();
await emptyIOOverrideAsync();
asyncEnd();
}