diff --git a/.ci.yaml b/.ci.yaml old mode 100755 new mode 100644 diff --git a/dev/benchmarks/test_apps/stocks/android/gradle/wrapper/gradle-wrapper.properties b/dev/benchmarks/test_apps/stocks/android/gradle/wrapper/gradle-wrapper.properties old mode 100755 new mode 100644 diff --git a/dev/bots/analyze.dart b/dev/bots/analyze.dart index ba63e75f95..249a4a32d2 100644 --- a/dev/bots/analyze.dart +++ b/dev/bots/analyze.dart @@ -158,6 +158,9 @@ Future run(List arguments) async { ...arguments, ]); + print('$clock Executable allowlist...'); + await _checkForNewExecutables(); + // Try with the --watch analyzer, to make sure it returns success also. // The --benchmark argument exits after one run. print('$clock Dart analysis (with --watch)...'); @@ -1682,6 +1685,63 @@ Future _runFlutterAnalyze(String workingDirectory, { ); } +// These files legitimately require executable permissions +const Set kExecutableAllowlist = { + 'bin/dart', + 'bin/flutter', + 'bin/internal/update_dart_sdk.sh', + + 'dev/bots/accept_android_sdk_licenses.sh', + 'dev/bots/codelabs_build_test.sh', + 'dev/bots/docs.sh', + + 'dev/conductor/bin/conductor', + 'dev/conductor/core/lib/src/proto/compile_proto.sh', + + 'dev/customer_testing/ci.sh', + + 'dev/integration_tests/flutter_gallery/tool/run_instrumentation_test.sh', + + 'dev/integration_tests/ios_add2app_life_cycle/build_and_test.sh', + + 'dev/integration_tests/deferred_components_test/download_assets.sh', + 'dev/integration_tests/deferred_components_test/run_release_test.sh', + + 'dev/tools/gen_keycodes/bin/gen_keycodes', + 'dev/tools/repackage_gradle_wrapper.sh', + + 'packages/flutter_tools/bin/macos_assemble.sh', + 'packages/flutter_tools/bin/tool_backend.sh', + 'packages/flutter_tools/bin/xcode_backend.sh', +}; + +Future _checkForNewExecutables() async { + // 0b001001001 + const int executableBitMask = 0x49; + + final List files = await _gitFiles(flutterRoot); + int unexpectedExecutableCount = 0; + for (final File file in files) { + final String relativePath = path.relative( + file.path, + from: flutterRoot, + ); + final FileStat stat = file.statSync(); + final bool isExecutable = stat.mode & executableBitMask != 0x0; + if (isExecutable && !kExecutableAllowlist.contains(relativePath)) { + unexpectedExecutableCount += 1; + print('$relativePath is executable: ${(stat.mode & 0x1FF).toRadixString(2)}'); + } + } + if (unexpectedExecutableCount > 0) { + throw Exception( + 'found $unexpectedExecutableCount unexpected executable file' + '${unexpectedExecutableCount == 1 ? '' : 's'}! If this was intended, you ' + 'must add this file to kExecutableAllowlist in dev/bots/analyze.dart', + ); + } +} + final RegExp _importPattern = RegExp(r'''^\s*import (['"])package:flutter/([^.]+)\.dart\1'''); final RegExp _importMetaPattern = RegExp(r'''^\s*import (['"])package:meta/meta\.dart\1'''); diff --git a/dev/integration_tests/android_semantics_testing/android/gradle/wrapper/gradle-wrapper.properties b/dev/integration_tests/android_semantics_testing/android/gradle/wrapper/gradle-wrapper.properties old mode 100755 new mode 100644 diff --git a/dev/integration_tests/channels/android/gradle/wrapper/gradle-wrapper.properties b/dev/integration_tests/channels/android/gradle/wrapper/gradle-wrapper.properties old mode 100755 new mode 100644 diff --git a/dev/integration_tests/platform_interaction/android/gradle/wrapper/gradle-wrapper.properties b/dev/integration_tests/platform_interaction/android/gradle/wrapper/gradle-wrapper.properties old mode 100755 new mode 100644 diff --git a/packages/flutter/lib/src/material/stepper.dart b/packages/flutter/lib/src/material/stepper.dart old mode 100755 new mode 100644 diff --git a/packages/flutter_tools/test/commands.shard/permeable/create_test.dart b/packages/flutter_tools/test/commands.shard/permeable/create_test.dart old mode 100755 new mode 100644