Skip to content

Commit

Permalink
[webview_flutter] fix: unreliable encoding for web (flutter#5737)
Browse files Browse the repository at this point in the history
  • Loading branch information
FlafyDev committed Jul 6, 2022
1 parent a0c773b commit 3a2cd24
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 17 deletions.
4 changes: 4 additions & 0 deletions packages/webview_flutter/webview_flutter_web/CHANGELOG.md
@@ -1,3 +1,7 @@
## 0.1.0+4

* Fixes incorrect escaping of some characters when setting the HTML to the iframe element.

## 0.1.0+3

* Minor fixes for new analysis options.
Expand Down
Expand Up @@ -3,6 +3,7 @@
// found in the LICENSE file.

import 'dart:async';
import 'dart:convert';
import 'dart:html';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
Expand Down Expand Up @@ -183,7 +184,11 @@ class WebWebViewPlatformController implements WebViewPlatformController {
String? baseUrl,
}) async {
// ignore: unsafe_html
_element.src = 'data:text/html,${Uri.encodeFull(html)}';
_element.src = Uri.dataFromString(
html,
mimeType: 'text/html',
encoding: utf8,
).toString();
}

@override
Expand All @@ -199,8 +204,11 @@ class WebWebViewPlatformController implements WebViewPlatformController {
final String contentType =
httpReq.getResponseHeader('content-type') ?? 'text/html';
// ignore: unsafe_html
_element.src =
'data:$contentType,${Uri.encodeFull(httpReq.responseText ?? '')}';
_element.src = Uri.dataFromString(
httpReq.responseText ?? '',
mimeType: contentType,
encoding: utf8,
).toString();
}

@override
Expand Down
2 changes: 1 addition & 1 deletion packages/webview_flutter/webview_flutter_web/pubspec.yaml
Expand Up @@ -2,7 +2,7 @@ name: webview_flutter_web
description: A Flutter plugin that provides a WebView widget on web.
repository: https://github.com/flutter/plugins/tree/main/packages/webview_flutter/webview_flutter_web
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22
version: 0.1.0+3
version: 0.1.0+4

environment:
sdk: ">=2.14.0 <3.0.0"
Expand Down
Expand Up @@ -54,17 +54,33 @@ void main() {
verify(mockElement.src = 'test url');
});

test('loadHtmlString loads html into iframe', () {
// Setup
final MockIFrameElement mockElement = MockIFrameElement();
final WebWebViewPlatformController controller =
WebWebViewPlatformController(
mockElement,
);
// Run
controller.loadHtmlString('test html');
// Verify
verify(mockElement.src = 'data:text/html,${Uri.encodeFull('test html')}');
group('loadHtmlString', () {
test('loadHtmlString loads html into iframe', () {
// Setup
final MockIFrameElement mockElement = MockIFrameElement();
final WebWebViewPlatformController controller =
WebWebViewPlatformController(
mockElement,
);
// Run
controller.loadHtmlString('test html');
// Verify
verify(mockElement.src =
'data:text/html;charset=utf-8,${Uri.encodeFull('test html')}');
});

test('loadHtmlString escapes "#" correctly', () {
// Setup
final MockIFrameElement mockElement = MockIFrameElement();
final WebWebViewPlatformController controller =
WebWebViewPlatformController(
mockElement,
);
// Run
controller.loadHtmlString('#');
// Verify
verify(mockElement.src = argThat(contains('%23')));
});
});

group('loadRequest', () {
Expand Down Expand Up @@ -122,8 +138,40 @@ void main() {
requestHeaders: <String, String>{'Foo': 'Bar'},
sendData: Uint8List.fromList('test body'.codeUnits),
));
verify(
mockElement.src = 'data:text/plain,${Uri.encodeFull('test data')}');
verify(mockElement.src =
'data:;charset=utf-8,${Uri.encodeFull('test data')}');
});

test('loadRequest escapes "#" correctly', () async {
// Setup
final MockIFrameElement mockElement = MockIFrameElement();
final WebWebViewPlatformController controller =
WebWebViewPlatformController(
mockElement,
);
final MockHttpRequest mockHttpRequest = MockHttpRequest();
when(mockHttpRequest.getResponseHeader('content-type'))
.thenReturn('text/html');
when(mockHttpRequest.responseText).thenReturn('#');
final MockHttpRequestFactory mockHttpRequestFactory =
MockHttpRequestFactory();
when(mockHttpRequestFactory.request(
any,
method: anyNamed('method'),
requestHeaders: anyNamed('requestHeaders'),
sendData: anyNamed('sendData'),
)).thenAnswer((_) => Future<HttpRequest>.value(mockHttpRequest));
controller.httpRequestFactory = mockHttpRequestFactory;
// Run
await controller.loadRequest(
WebViewRequest(
uri: Uri.parse('https://flutter.dev'),
method: WebViewRequestMethod.post,
body: Uint8List.fromList('test body'.codeUnits),
headers: <String, String>{'Foo': 'Bar'}),
);
// Verify
verify(mockElement.src = argThat(contains('%23')));
});
});
});
Expand Down

0 comments on commit 3a2cd24

Please sign in to comment.