Skip to content

Commit b207aed

Browse files
aamCommit Queue
authored and
Commit Queue
committed
[vm/file/win] Normalize absolute paths before adding long-prefix.
Long-prefixed paths can't have '..' segments in them. Delete recursively uses long-prefixes, so the tests that verify long paths handling had to be updated accordingly: it's okay to use long paths when they are prefixed(when they are deleted recursively). This is follow-up to 4928998 Bug: #56125 Change-Id: I6613b1a324e8923d05e5f0a470ee5b2999d1b929 TEST=ci Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/374220 Commit-Queue: Alexander Aprelev <[email protected]> Reviewed-by: Ryan Macnak <[email protected]>
1 parent 0001498 commit b207aed

File tree

3 files changed

+65
-15
lines changed

3 files changed

+65
-15
lines changed

runtime/bin/file_win.cc

+4-1
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,10 @@ static std::unique_ptr<wchar_t[]> ToWinAPIPath(const char* utf8_path,
404404
const int path_short_limit = is_file ? MAX_PATH : MAX_DIRECTORY_PATH;
405405

406406
std::unique_ptr<wchar_t[]> absolute_path;
407-
if (!IsAbsolutePath(path.get())) {
407+
// Need to convert to absolute path if we want to use long prefix
408+
// to normalize the path - this is to get rid of .., . that can't be
409+
// interpreted in the long-prefixed mode).
410+
if (force_long_prefix || !IsAbsolutePath(path.get())) {
408411
absolute_path = ConvertToAbsolutePath(path);
409412
if (absolute_path == nullptr) {
410413
return path;

tests/standalone/io/directory_test.dart

+55-14
Original file line numberDiff line numberDiff line change
@@ -188,16 +188,38 @@ class DirectoryTest {
188188
buffer.write("/../${subDirName}");
189189
}
190190
var long = new Directory("${buffer.toString()}");
191-
var errors = 0;
192-
onError(error) {
191+
Future<void>.value(long.delete()).catchError((error) {
193192
Expect.isTrue(error is FileSystemException);
194-
if (++errors == 2) {
195-
d.delete(recursive: true).then((_) => asyncEnd());
196-
}
197-
}
193+
asyncEnd();
194+
});
195+
});
196+
});
197+
}
198198

199-
Future<void>.value(long.delete()).catchError(onError);
200-
Future<void>.value(long.delete(recursive: true)).catchError(onError);
199+
static void testDeleteTooLongNameRecursive() {
200+
asyncStart();
201+
Directory.systemTemp.createTemp('dart_directory').then((d) {
202+
var subDirName = 'subdir';
203+
var subDir = new Directory("${d.path}/$subDirName");
204+
subDir.create().then((ignore) {
205+
// Construct a long string of the form
206+
// 'tempdir/subdir/../subdir/../subdir'.
207+
var buffer = new StringBuffer();
208+
buffer.write(subDir.path);
209+
for (var i = 0; i < 1000; i++) {
210+
buffer.write("/../${subDirName}");
211+
}
212+
var long = new Directory("${buffer.toString()}");
213+
// Works only on Windows.
214+
long.delete(recursive: true).then((_) {
215+
if (Platform.isWindows) {
216+
asyncEnd();
217+
}
218+
}, onError: ((_) {
219+
if (!Platform.isWindows) {
220+
asyncEnd();
221+
}
222+
}));
201223
});
202224
});
203225
}
@@ -209,8 +231,7 @@ class DirectoryTest {
209231
Expect.throws(() => d.deleteSync(recursive: true));
210232
}
211233

212-
static void testDeleteTooLongNameSync() {
213-
Directory d = Directory.systemTemp.createTempSync('dart_directory_test');
234+
static StringBuffer createLongDirName(Directory d) {
214235
var subDirName = 'subdir';
215236
var subDir = new Directory("${d.path}/$subDirName");
216237
subDir.createSync();
@@ -221,10 +242,29 @@ class DirectoryTest {
221242
for (var i = 0; i < 1000; i++) {
222243
buffer.write("/../${subDirName}");
223244
}
224-
var long = new Directory("${buffer.toString()}");
225-
Expect.throws(long.deleteSync);
226-
Expect.throws(() => long.deleteSync(recursive: true));
227-
d.deleteSync(recursive: true);
245+
return buffer;
246+
}
247+
248+
static void testDeleteTooLongNameSync() {
249+
{
250+
Directory d = Directory.systemTemp.createTempSync('dart_directory_test');
251+
StringBuffer buffer = createLongDirName(d);
252+
var long = new Directory("${buffer.toString()}");
253+
Expect.throws(long.deleteSync);
254+
d.deleteSync(recursive: true);
255+
}
256+
{
257+
Directory d = Directory.systemTemp.createTempSync('dart_directory_test');
258+
StringBuffer buffer = createLongDirName(d);
259+
var long = new Directory("${buffer.toString()}");
260+
// Works only on Windows
261+
if (Platform.isWindows) {
262+
long.deleteSync(recursive: true);
263+
} else {
264+
Expect.throws(() => long.deleteSync(recursive: true));
265+
d.deleteSync(recursive: true);
266+
}
267+
}
228268
}
229269

230270
static void testExistsCreateDelete() {
@@ -465,6 +505,7 @@ class DirectoryTest {
465505
testListTooLongName();
466506
testDeleteNonExistent();
467507
testDeleteTooLongName();
508+
testDeleteTooLongNameRecursive();
468509
testDeleteNonExistentSync();
469510
testDeleteTooLongNameSync();
470511
testExistsCreateDelete();

tests/standalone/io/file_copy_test.dart

+6
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ void testCopySync() {
4343
Expect.throws(() => file1.copySync(dir.path));
4444
Expect.equals(FILE_CONTENT2, file1.readAsStringSync());
4545

46+
Directory('${tmp.path}/abc').createSync();
47+
// Copy to new file works.
48+
var file3 = file1.copySync('${tmp.path}/abc/../file3');
49+
Expect.equals(FILE_CONTENT2, file1.readAsStringSync());
50+
Expect.equals(FILE_CONTENT2, file3.readAsStringSync());
51+
4652
tmp.deleteSync(recursive: true);
4753
}
4854

0 commit comments

Comments
 (0)