Unverified Commit 41880855 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] handle archive exception from invalid zip signature (#65869)

Like the ProcessException thrown from zip running on a bad file, the tool should catch the ArchiveException thrown from windows implementation using package:archive.
parent b88f308a
......@@ -4,6 +4,7 @@
import 'dart:async';
import 'package:archive/archive.dart';
import 'package:meta/meta.dart';
import 'android/gradle_utils.dart';
......@@ -1517,6 +1518,13 @@ class ArtifactUpdater {
}
_deleteIgnoringErrors(tempFile);
continue;
} on ArchiveException {
retries -= 1;
if (retries == 0) {
rethrow;
}
_deleteIgnoringErrors(tempFile);
continue;
}
return;
}
......
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:archive/archive.dart';
import 'package:file/memory.dart';
import 'package:file/src/interface/file.dart';
import 'package:file_testing/file_testing.dart';
......@@ -180,6 +181,30 @@ void main() {
expect(fileSystem.file('out/test'), exists);
});
testWithoutContext('ArtifactUpdater will de-download a file if unzipping fails on windows', () async {
final MockOperatingSystemUtils operatingSystemUtils = MockOperatingSystemUtils(windows: true);
final MemoryFileSystem fileSystem = MemoryFileSystem.test();
final BufferLogger logger = BufferLogger.test();
final ArtifactUpdater artifactUpdater = ArtifactUpdater(
fileSystem: fileSystem,
logger: logger,
operatingSystemUtils: operatingSystemUtils,
platform: testPlatform,
httpClient: MockHttpClient(),
tempStorage: fileSystem.currentDirectory.childDirectory('temp')
..createSync(),
);
operatingSystemUtils.failures = 1;
await artifactUpdater.downloadZipArchive(
'test message',
Uri.parse('http:///test.zip'),
fileSystem.currentDirectory.childDirectory('out'),
);
expect(logger.statusText, contains('test message'));
expect(fileSystem.file('out/test'), exists);
});
testWithoutContext('ArtifactUpdater will bail if unzipping fails more than twice', () async {
final MockOperatingSystemUtils operatingSystemUtils = MockOperatingSystemUtils();
final MemoryFileSystem fileSystem = MemoryFileSystem.test();
......@@ -204,6 +229,30 @@ void main() {
expect(fileSystem.file('out/test'), isNot(exists));
});
testWithoutContext('ArtifactUpdater will bail if unzipping fails more than twice on Windows', () async {
final MockOperatingSystemUtils operatingSystemUtils = MockOperatingSystemUtils(windows: true);
final MemoryFileSystem fileSystem = MemoryFileSystem.test();
final BufferLogger logger = BufferLogger.test();
final ArtifactUpdater artifactUpdater = ArtifactUpdater(
fileSystem: fileSystem,
logger: logger,
operatingSystemUtils: operatingSystemUtils,
platform: testPlatform,
httpClient: MockHttpClient(),
tempStorage: fileSystem.currentDirectory.childDirectory('temp')
..createSync(),
);
operatingSystemUtils.failures = 2;
expect(artifactUpdater.downloadZipArchive(
'test message',
Uri.parse('http:///test.zip'),
fileSystem.currentDirectory.childDirectory('out'),
), throwsA(isA<ArchiveException>()));
expect(fileSystem.file('te,[/test'), isNot(exists));
expect(fileSystem.file('out/test'), isNot(exists));
});
testWithoutContext('ArtifactUpdater can download a tar archive', () async {
final MockOperatingSystemUtils operatingSystemUtils = MockOperatingSystemUtils();
final MemoryFileSystem fileSystem = MemoryFileSystem.test();
......@@ -253,12 +302,18 @@ void main() {
}
class MockOperatingSystemUtils extends Mock implements OperatingSystemUtils {
MockOperatingSystemUtils({this.windows = false});
int failures = 0;
final bool windows;
@override
void unzip(File file, Directory targetDirectory) {
if (failures > 0) {
failures -= 1;
if (windows) {
throw ArchiveException('zip');
}
throw const ProcessException('zip', <String>[], 'Failed to unzip');
}
targetDirectory.childFile(file.fileSystem.path.basenameWithoutExtension(file.path))
......@@ -269,6 +324,9 @@ class MockOperatingSystemUtils extends Mock implements OperatingSystemUtils {
void unpack(File gzippedTarFile, Directory targetDirectory) {
if (failures > 0) {
failures -= 1;
if (windows) {
throw ArchiveException('zip');
}
throw const ProcessException('zip', <String>[], 'Failed to unzip');
}
targetDirectory.childFile(gzippedTarFile.fileSystem.path.basenameWithoutExtension(gzippedTarFile.path))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment