From dbef1314b1869065c22482126f7e006308eb2536 Mon Sep 17 00:00:00 2001 From: Victoria Ashworth <15619084+vashworth@users.noreply.github.com> Date: Tue, 1 Apr 2025 10:54:24 -0500 Subject: [PATCH] Trim any text before osascript JSON response (#166296) Fixes https://github.com/flutter/flutter/issues/164772. ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md --- .../lib/src/ios/xcode_debug.dart | 17 ++++++++++++--- .../general.shard/ios/xcode_debug_test.dart | 21 +++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/packages/flutter_tools/lib/src/ios/xcode_debug.dart b/packages/flutter_tools/lib/src/ios/xcode_debug.dart index a5d18f07c0..b2f0929b6c 100644 --- a/packages/flutter_tools/lib/src/ios/xcode_debug.dart +++ b/packages/flutter_tools/lib/src/ios/xcode_debug.dart @@ -269,8 +269,19 @@ class XcodeDebug { @visibleForTesting XcodeAutomationScriptResponse? parseScriptResponse(String results) { + // Some users reported text before the json. Trim any text before the opening + // curly brace. + // Example: `start process_extensions{"status":true,"errorMessage":null,"debugResult":{"completed":false,"status":"running","errorMessage":null}}` + final String trimmedResults; + final int jsonBeginIndex = results.indexOf('{'); + if (jsonBeginIndex > -1) { + trimmedResults = results.substring(jsonBeginIndex); + } else { + trimmedResults = results; + } + try { - final Object decodeResult = json.decode(results) as Object; + final Object decodeResult = json.decode(trimmedResults) as Object; if (decodeResult is Map) { final XcodeAutomationScriptResponse response = XcodeAutomationScriptResponse.fromJson( decodeResult, @@ -280,10 +291,10 @@ class XcodeDebug { return response; } } - _logger.printError('osascript returned unexpected JSON response: $results'); + _logger.printError('osascript returned unexpected JSON response: $trimmedResults'); return null; } on FormatException { - _logger.printError('osascript returned non-JSON response: $results'); + _logger.printError('osascript returned non-JSON response: $trimmedResults'); return null; } } diff --git a/packages/flutter_tools/test/general.shard/ios/xcode_debug_test.dart b/packages/flutter_tools/test/general.shard/ios/xcode_debug_test.dart index 1e35fd34a4..a68c784718 100644 --- a/packages/flutter_tools/test/general.shard/ios/xcode_debug_test.dart +++ b/packages/flutter_tools/test/general.shard/ios/xcode_debug_test.dart @@ -617,6 +617,27 @@ void main() { expect(logger.errorText, contains('osascript returned unexpected JSON response')); expect(response, isNull); }); + + testWithoutContext('successfully removes any text before JSON', () async { + final Xcode xcode = setupXcode( + fakeProcessManager: FakeProcessManager.any(), + fileSystem: fileSystem, + flutterRoot: flutterRoot, + ); + final XcodeDebug xcodeDebug = XcodeDebug( + logger: logger, + processManager: fakeProcessManager, + xcode: xcode, + fileSystem: fileSystem, + ); + + final XcodeAutomationScriptResponse? response = xcodeDebug.parseScriptResponse( + 'start process_extensions{"status":true,"errorMessage":null,"debugResult":{"completed":false,"status":"running","errorMessage":null}}', + ); + + expect(logger.errorText, isEmpty); + expect(response, isNotNull); + }); }); group('exit', () {