Skip to content

Commit 1e2be6e

Browse files
Check for bad characters in path on Windows build (#107949)
* Check for bad characters in path on Windows build * Doc comments * Fix formatting * Commenting/formatting * Link to issue in comment * Comments, formatting * Global var rename
1 parent 2a8a089 commit 1e2be6e

File tree

2 files changed

+53
-5
lines changed

2 files changed

+53
-5
lines changed

packages/flutter_tools/lib/src/windows/build_windows.dart

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,29 @@ import '../globals.dart' as globals;
1919
import '../migrations/cmake_custom_command_migration.dart';
2020
import 'visual_studio.dart';
2121

22+
// These characters appear to be fine: @%()-+_{}[]`~
23+
const String _kBadCharacters = r"'#!$^&*=|,;<>?";
24+
2225
/// Builds the Windows project using msbuild.
2326
Future<void> buildWindows(WindowsProject windowsProject, BuildInfo buildInfo, {
2427
String? target,
2528
VisualStudio? visualStudioOverride,
2629
SizeAnalyzer? sizeAnalyzer,
2730
}) async {
31+
// MSBuild files generated by CMake do not properly escape some characters
32+
// In the directories. This check produces more meaningful error messages
33+
// on failure as pertains to https://github.com/flutter/flutter/issues/104802
34+
final String projectPath = windowsProject.parent.directory.absolute.path;
35+
final bool badPath = _kBadCharacters.runes
36+
.any((int i) => projectPath.contains(String.fromCharCode(i)));
37+
if (badPath) {
38+
throwToolExit(
39+
'Path $projectPath contains invalid characters in "$_kBadCharacters". '
40+
'Please rename your directory so as to not include any of these characters '
41+
'and retry.',
42+
);
43+
}
44+
2845
if (!windowsProject.cmakeFile.existsSync()) {
2946
throwToolExit(
3047
'No Windows desktop project configured. See '

packages/flutter_tools/test/commands.shard/hermetic/build_windows_test.dart

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@ import '../../src/fakes.dart';
2121
import '../../src/test_flutter_command_runner.dart';
2222

2323
const String flutterRoot = r'C:\flutter';
24-
const String buildFilePath = r'C:\windows\CMakeLists.txt';
25-
const String visualStudioPath = r'C:\Program Files (x86)\Microsoft Visual Studio\2017\Community';
26-
const String _cmakePath = visualStudioPath + r'\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe';
24+
const String buildFilePath = r'windows\CMakeLists.txt';
25+
const String visualStudioPath =
26+
r'C:\Program Files (x86)\Microsoft Visual Studio\2017\Community';
27+
const String _cmakePath = visualStudioPath +
28+
r'\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe';
2729
const String _defaultGenerator = 'Visual Studio 16 2019';
2830

2931
final Platform windowsPlatform = FakePlatform(
@@ -80,7 +82,7 @@ void main() {
8082
command: <String>[
8183
_cmakePath,
8284
'-S',
83-
fileSystem.path.dirname(buildFilePath),
85+
fileSystem.path.absolute(fileSystem.path.dirname(buildFilePath)),
8486
'-B',
8587
r'build\windows',
8688
'-G',
@@ -923,7 +925,7 @@ if %errorlevel% neq 0 goto :VCEnd</Command>
923925
expect(testLogger.statusText, contains('A summary of your Windows bundle analysis can be found at'));
924926
expect(testLogger.statusText, contains('flutter pub global activate devtools; flutter pub global run devtools --appSizeBase='));
925927
expect(usage.events, contains(
926-
const TestUsageEvent('code-size-analysis', 'windows'),
928+
const TestUsageEvent('code-size-analysis', 'windows'),
927929
));
928930
}, overrides: <Type, Generator>{
929931
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
@@ -933,6 +935,35 @@ if %errorlevel% neq 0 goto :VCEnd</Command>
933935
FileSystemUtils: () => FileSystemUtils(fileSystem: fileSystem, platform: windowsPlatform),
934936
Usage: () => usage,
935937
});
938+
939+
// Confirms that running for Windows in a directory with a
940+
// bad character (' in this case) throws the desired error message
941+
// If the issue https://github.com/flutter/flutter/issues/104802 ever
942+
// is resolved on the VS side, we can allow these paths again
943+
testUsingContext('Test bad path characters', () async {
944+
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio();
945+
final BuildWindowsCommand command = BuildWindowsCommand()
946+
..visualStudioOverride = fakeVisualStudio;
947+
fileSystem.currentDirectory = fileSystem.directory("test_'path")
948+
..createSync();
949+
final String absPath = fileSystem.currentDirectory.absolute.path;
950+
setUpMockCoreProjectFiles();
951+
952+
expect(
953+
createTestCommandRunner(command).run(const <String>['windows', '--no-pub']),
954+
throwsToolExit(
955+
message:
956+
'Path $absPath contains invalid characters in "\'#!\$^&*=|,;<>?". '
957+
'Please rename your directory so as to not include any of these characters '
958+
'and retry.',
959+
),
960+
);
961+
}, overrides: <Type, Generator>{
962+
Platform: () => windowsPlatform,
963+
FileSystem: () => fileSystem,
964+
ProcessManager: () => FakeProcessManager.any(),
965+
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
966+
});
936967
}
937968

938969
class FakeVisualStudio extends Fake implements VisualStudio {

0 commit comments

Comments
 (0)