diff --git a/packages/url_launcher/url_launcher/CHANGELOG.md b/packages/url_launcher/url_launcher/CHANGELOG.md index 4b52a8d46f8b..fff325e08915 100644 --- a/packages/url_launcher/url_launcher/CHANGELOG.md +++ b/packages/url_launcher/url_launcher/CHANGELOG.md @@ -1,3 +1,7 @@ +## 6.0.12 + +* Fixed an error where 'launch' method of url_launcher would cause an error if the provided URL was not valid by RFC 3986. + ## 6.0.11 * Update minimum Flutter SDK to 2.5 and iOS deployment target to 9.0. diff --git a/packages/url_launcher/url_launcher/lib/url_launcher.dart b/packages/url_launcher/url_launcher/lib/url_launcher.dart index 239e3c46c480..300f96f4a179 100644 --- a/packages/url_launcher/url_launcher/lib/url_launcher.dart +++ b/packages/url_launcher/url_launcher/lib/url_launcher.dart @@ -71,8 +71,10 @@ Future launch( Brightness? statusBarBrightness, String? webOnlyWindowName, }) async { - final Uri url = Uri.parse(urlString.trimLeft()); - final bool isWebURL = url.scheme == 'http' || url.scheme == 'https'; + final Uri? url = Uri.tryParse(urlString.trimLeft()); + final bool isWebURL = + url != null && (url.scheme == 'http' || url.scheme == 'https'); + if ((forceSafariVC == true || forceWebView == true) && !isWebURL) { throw PlatformException( code: 'NOT_A_WEB_SCHEME', diff --git a/packages/url_launcher/url_launcher/pubspec.yaml b/packages/url_launcher/url_launcher/pubspec.yaml index c90d2feb08f4..8edb9e21c535 100644 --- a/packages/url_launcher/url_launcher/pubspec.yaml +++ b/packages/url_launcher/url_launcher/pubspec.yaml @@ -3,7 +3,7 @@ description: Flutter plugin for launching a URL. Supports web, phone, SMS, and email schemes. repository: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22 -version: 6.0.11 +version: 6.0.12 environment: sdk: ">=2.14.0 <3.0.0" diff --git a/packages/url_launcher/url_launcher/test/url_launcher_test.dart b/packages/url_launcher/url_launcher/test/url_launcher_test.dart index 04f727a57746..a038746d6bec 100644 --- a/packages/url_launcher/url_launcher/test/url_launcher_test.dart +++ b/packages/url_launcher/url_launcher/test/url_launcher_test.dart @@ -281,6 +281,42 @@ void main() { await launchResult; expect(binding.renderView.automaticSystemUiAdjustment, true); }); + + test('open non-parseable url', () async { + mock + ..setLaunchExpectations( + url: + 'rdp://full%20address=s:mypc:3389&audiomode=i:2&disable%20themes=i:1', + useSafariVC: false, + useWebView: false, + enableJavaScript: false, + enableDomStorage: false, + universalLinksOnly: false, + headers: {}, + webOnlyWindowName: null, + ) + ..setResponse(true); + expect( + await launch( + 'rdp://full%20address=s:mypc:3389&audiomode=i:2&disable%20themes=i:1'), + isTrue); + }); + + test('cannot open non-parseable url with forceSafariVC: true', () async { + expect( + () async => await launch( + 'rdp://full%20address=s:mypc:3389&audiomode=i:2&disable%20themes=i:1', + forceSafariVC: true), + throwsA(isA())); + }); + + test('cannot open non-parseable url with forceWebView: true', () async { + expect( + () async => await launch( + 'rdp://full%20address=s:mypc:3389&audiomode=i:2&disable%20themes=i:1', + forceWebView: true), + throwsA(isA())); + }); }); }