Version 2.10.0-114.0.dev
Merge commit '8e61018d4799e706b0d2ef9808185aae8d365c69' into 'dev'
diff --git a/DEPS b/DEPS
index 5e49e15..dd033f0 100644
--- a/DEPS
+++ b/DEPS
@@ -44,7 +44,7 @@
# co19 is a cipd package. Use update.sh in tests/co19[_2] to update these
# hashes. It requires access to the dart-build-access group, which EngProd
# has.
- "co19_rev": "d21ed3a1dd64107916db68afdce21709df65e85f",
+ "co19_rev": "b82516f08b02a10f5a65b7157e8cfdf00f10bdf4",
"co19_2_rev": "e48b3090826cf40b8037648f19d211e8eab1b4b6",
# The internal benchmarks to use. See go/dart-benchmarks-internal
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/modify_parameters.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/modify_parameters.dart
index 9423b2e..20e8a0c 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/modify_parameters.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/modify_parameters.dart
@@ -26,10 +26,6 @@
/// A flag indicating whether the parameter is a positional parameter.
final bool isPositional;
- /// The default value of the parameter, or `null` if the parameter doesn't
- /// have a default value.
- final ValueExtractor defaultValue;
-
/// The value of the new argument in invocations of the function, or `null` if
/// the parameter is optional and no argument needs to be added. The only time
/// an argument needs to be added for an optional parameter is if the
@@ -41,7 +37,7 @@
/// addition of a parameter. If provided, the [argumentValue] will be used as
/// the value of the new argument in invocations of the function.
AddParameter(this.index, this.name, this.isRequired, this.isPositional,
- this.defaultValue, this.argumentValue)
+ this.argumentValue)
: assert(index >= 0),
assert(name != null);
}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart
index b81936e..5ff9d8f 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart
@@ -23,7 +23,6 @@
static const String _classKey = 'class';
static const String _constantKey = 'constant';
static const String _constructorKey = 'constructor';
- static const String _defaultValueKey = 'defaultValue';
static const String _elementKey = 'element';
static const String _enumKey = 'enum';
static const String _extensionKey = 'extension';
@@ -66,6 +65,18 @@
static const String _removeParameterKind = 'removeParameter';
static const String _renameKind = 'rename';
+ /// The valid values for the [_styleKey] in an [_addParameterKind] change.
+ static const List<String> validStyles = [
+ 'optional_named',
+ 'optional_positional',
+ 'required_named',
+ 'required_positional'
+ ];
+
+ /// The highest file version supported by this parser. The version needs to be
+ /// incremented any time the parser is updated to disallow input that would
+ /// have been valid in the most recently published version of server. This
+ /// includes removing support for keys and adding a new required key.
static const int currentVersion = 1;
/// The error reporter to which diagnostics will be reported.
@@ -173,7 +184,8 @@
/// Translate the [node] into a add-parameter modification.
void _translateAddParameterChange(YamlMap node) {
_singleKey(node, [_indexKey, _nameKey]);
- _reportUnsupportedKeys(node, const {_indexKey, _kindKey, _nameKey});
+ _reportUnsupportedKeys(node,
+ const {_argumentValueKey, _indexKey, _kindKey, _nameKey, _styleKey});
var index = _translateInteger(node.valueAt(_indexKey), _indexKey);
if (index == null) {
return;
@@ -185,19 +197,12 @@
var style = _translateString(node.valueAt(_styleKey), _styleKey);
if (style == null) {
return;
+ } else if (!validStyles.contains(style)) {
+ // TODO(brianwilkerson) Report the invalid style.
+ return;
}
var isRequired = style.startsWith('required_');
var isPositional = style.endsWith('_positional');
- // TODO(brianwilkerson) I originally thought we'd need a default value, but
- // it seems like we ought to be able to get it from the overridden method,
- // so investigate removing this field.
- var defaultValue = _translateValueExtractor(
- node.valueAt(_defaultValueKey), _defaultValueKey);
- if (isRequired && defaultValue != null) {
- // TODO(brianwilkerson) Report that required parameters can't have a
- // default value.
- return;
- }
var argumentValue = _translateValueExtractor(
node.valueAt(_argumentValueKey), _argumentValueKey);
// TODO(brianwilkerson) We really ought to require an argument value for
@@ -212,8 +217,8 @@
return;
}
_parameterModifications ??= [];
- _parameterModifications.add(AddParameter(
- index, name, isRequired, isPositional, defaultValue, argumentValue));
+ _parameterModifications.add(
+ AddParameter(index, name, isRequired, isPositional, argumentValue));
}
/// Translate the [node] into an add-type-parameter change. Return the
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/modify_parameters_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/modify_parameters_test.dart
index 2287a48..a3f26a4 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/modify_parameters_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/modify_parameters_test.dart
@@ -30,7 +30,7 @@
}
''');
setPackageData(_modify(
- ['C', 'm'], [AddParameter(0, 'a', false, false, null, null)],
+ ['C', 'm'], [AddParameter(0, 'a', false, false, null)],
newName: 'm2'));
await resolveTestUnit('''
import '$importUri';
@@ -56,12 +56,9 @@
void m2([int a, int b]) {}
}
''');
- setPackageData(_modify([
- 'C',
- 'm'
- ], [
- AddParameter(0, 'a', false, true, null, LiteralExtractor('0'))
- ], newName: 'm2'));
+ setPackageData(_modify(
+ ['C', 'm'], [AddParameter(0, 'a', false, true, LiteralExtractor('0'))],
+ newName: 'm2'));
await resolveTestUnit('''
import '$importUri';
@@ -86,12 +83,9 @@
void m2({int a, int b}) {}
}
''');
- setPackageData(_modify([
- 'C',
- 'm'
- ], [
- AddParameter(0, 'a', true, false, null, LiteralExtractor('0'))
- ], newName: 'm2'));
+ setPackageData(_modify(
+ ['C', 'm'], [AddParameter(0, 'a', true, false, LiteralExtractor('0'))],
+ newName: 'm2'));
await resolveTestUnit('''
import '$importUri';
@@ -116,12 +110,9 @@
void m2(int a, int b) {}
}
''');
- setPackageData(_modify([
- 'C',
- 'm'
- ], [
- AddParameter(0, 'a', true, true, null, LiteralExtractor('0'))
- ], newName: 'm2'));
+ setPackageData(_modify(
+ ['C', 'm'], [AddParameter(0, 'a', true, true, LiteralExtractor('0'))],
+ newName: 'm2'));
await resolveTestUnit('''
import '$importUri';
@@ -147,7 +138,7 @@
}
''');
setPackageData(_modify(
- ['C', 'm'], [AddParameter(1, 'b', false, false, null, null)],
+ ['C', 'm'], [AddParameter(1, 'b', false, false, null)],
newName: 'm2'));
await resolveTestUnit('''
import '$importUri';
@@ -173,12 +164,9 @@
void m2(int a, [int b]) {}
}
''');
- setPackageData(_modify([
- 'C',
- 'm'
- ], [
- AddParameter(1, 'b', false, true, null, LiteralExtractor('1'))
- ], newName: 'm2'));
+ setPackageData(_modify(
+ ['C', 'm'], [AddParameter(1, 'b', false, true, LiteralExtractor('1'))],
+ newName: 'm2'));
await resolveTestUnit('''
import '$importUri';
@@ -203,12 +191,9 @@
void m2(int a, {int b}) {}
}
''');
- setPackageData(_modify([
- 'C',
- 'm'
- ], [
- AddParameter(1, 'b', true, false, null, LiteralExtractor('1'))
- ], newName: 'm2'));
+ setPackageData(_modify(
+ ['C', 'm'], [AddParameter(1, 'b', true, false, LiteralExtractor('1'))],
+ newName: 'm2'));
await resolveTestUnit('''
import '$importUri';
@@ -233,12 +218,9 @@
void m2(int a, int b) {}
}
''');
- setPackageData(_modify([
- 'C',
- 'm'
- ], [
- AddParameter(1, 'b', true, true, null, LiteralExtractor('1'))
- ], newName: 'm2'));
+ setPackageData(_modify(
+ ['C', 'm'], [AddParameter(1, 'b', true, true, LiteralExtractor('1'))],
+ newName: 'm2'));
await resolveTestUnit('''
import '$importUri';
@@ -267,9 +249,9 @@
'C',
'm'
], [
- AddParameter(1, 'b', true, true, null, LiteralExtractor('1')),
- AddParameter(2, 'c', true, true, null, LiteralExtractor('2')),
- AddParameter(4, 'e', true, true, null, LiteralExtractor('4')),
+ AddParameter(1, 'b', true, true, LiteralExtractor('1')),
+ AddParameter(2, 'c', true, true, LiteralExtractor('2')),
+ AddParameter(4, 'e', true, true, LiteralExtractor('4')),
], newName: 'm2'));
await resolveTestUnit('''
import '$importUri';
@@ -293,12 +275,9 @@
void m2(int a, int b) {}
}
''');
- setPackageData(_modify([
- 'C',
- 'm'
- ], [
- AddParameter(0, 'a', true, true, null, LiteralExtractor('0'))
- ], newName: 'm2'));
+ setPackageData(_modify(
+ ['C', 'm'], [AddParameter(0, 'a', true, true, LiteralExtractor('0'))],
+ newName: 'm2'));
await resolveTestUnit('''
import '$importUri';
@@ -321,8 +300,8 @@
void m(int a, int b) {}
}
''');
- setPackageData(_modify(['C', 'm'],
- [AddParameter(0, 'a', true, true, null, LiteralExtractor('0'))]));
+ setPackageData(_modify(
+ ['C', 'm'], [AddParameter(0, 'a', true, true, LiteralExtractor('0'))]));
await resolveTestUnit('''
import '$importUri';
@@ -352,7 +331,7 @@
'm'
], [
RemoveParameter(PositionalParameterReference(0)),
- AddParameter(2, 'c', true, true, null, LiteralExtractor('2'))
+ AddParameter(2, 'c', true, true, LiteralExtractor('2'))
], newName: 'm2'));
await resolveTestUnit('''
import '$importUri';
@@ -383,7 +362,7 @@
'm'
], [
RemoveParameter(PositionalParameterReference(1)),
- AddParameter(0, 'a', true, true, null, LiteralExtractor('0'))
+ AddParameter(0, 'a', true, true, LiteralExtractor('0'))
], newName: 'm2'));
await resolveTestUnit('''
import '$importUri';
@@ -415,7 +394,7 @@
], [
RemoveParameter(PositionalParameterReference(0)),
RemoveParameter(PositionalParameterReference(1)),
- AddParameter(0, 'c', true, true, null, LiteralExtractor('2')),
+ AddParameter(0, 'c', true, true, LiteralExtractor('2')),
], newName: 'm2'));
await resolveTestUnit('''
import '$importUri';
@@ -447,7 +426,7 @@
], [
RemoveParameter(PositionalParameterReference(1)),
RemoveParameter(PositionalParameterReference(2)),
- AddParameter(1, 'd', true, true, null, LiteralExtractor('3')),
+ AddParameter(1, 'd', true, true, LiteralExtractor('3')),
], newName: 'm2'));
await resolveTestUnit('''
import '$importUri';
@@ -477,10 +456,10 @@
'C',
'm1'
], [
- AddParameter(0, 'a', true, true, null, LiteralExtractor('0')),
+ AddParameter(0, 'a', true, true, LiteralExtractor('0')),
RemoveParameter(PositionalParameterReference(1)),
RemoveParameter(PositionalParameterReference(3)),
- AddParameter(2, 'd', true, true, null, LiteralExtractor('3')),
+ AddParameter(2, 'd', true, true, LiteralExtractor('3')),
], newName: 'm2'));
await resolveTestUnit('''
import '$importUri';
@@ -848,7 +827,7 @@
setPackageData(_modify([
'f'
], [
- AddParameter(0, 'a', true, true, null, LiteralExtractor('0')),
+ AddParameter(0, 'a', true, true, LiteralExtractor('0')),
], newName: 'g'));
await resolveTestUnit('''
import '$importUri';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test.dart
index e5e8e1f..112308c 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test.dart
@@ -70,9 +70,6 @@
index: 0
name: 'p'
style: optional_positional
- defaultValue:
- kind: 'argument'
- index: 1
''');
var transforms = result.transformsFor('f', ['test.dart']);
expect(transforms, hasLength(1));
@@ -87,9 +84,6 @@
expect(modification.name, 'p');
expect(modification.isRequired, false);
expect(modification.isPositional, true);
- var value = modification.defaultValue as ArgumentExtractor;
- var parameter = value.parameter as PositionalParameterReference;
- expect(parameter.index, 1);
}
void test_addParameter_requiredNamed() {
diff --git a/pkg/analyzer/lib/src/lint/pub.dart b/pkg/analyzer/lib/src/lint/pub.dart
index ab19e57..73efafe 100644
--- a/pkg/analyzer/lib/src/lint/pub.dart
+++ b/pkg/analyzer/lib/src/lint/pub.dart
@@ -24,7 +24,9 @@
YamlMap depsMap = v;
_PSDependencyList deps = _PSDependencyList(_PSNode(key));
- depsMap.nodes.forEach((k, v) => deps.add(_PSDependency(k, v)));
+ depsMap.nodes.forEach((k, v) {
+ if (k is YamlScalar) deps.add(_PSDependency(k, v));
+ });
return deps;
}
@@ -159,25 +161,20 @@
@override
PSGitRepo git;
- factory _PSDependency(dynamic k, YamlNode v) {
- if (k is! YamlScalar) {
- return null;
- }
- YamlScalar key = k;
-
+ factory _PSDependency(YamlScalar key, YamlNode value) {
_PSDependency dep = _PSDependency._();
dep.name = _PSNode(key);
- if (v is YamlScalar) {
+ if (value is YamlScalar) {
// Simple version
- dep.version = PSEntry(null, _PSNode(v));
- } else if (v is YamlMap) {
+ dep.version = PSEntry(null, _PSNode(value));
+ } else if (value is YamlMap) {
// hosted:
// name: transmogrify
// url: http://your-package-server.com
// version: '>=0.4.0 <1.0.0'
- YamlMap details = v;
+ YamlMap details = value;
details.nodes.forEach((k, v) {
if (k is! YamlScalar) {
return;
diff --git a/pkg/dds/CHANGELOG.md b/pkg/dds/CHANGELOG.md
index 96848ba..5ea6b54 100644
--- a/pkg/dds/CHANGELOG.md
+++ b/pkg/dds/CHANGELOG.md
@@ -1,3 +1,8 @@
+# 1.3.3
+
+- Fixed issue where `DartDevelopmentService.sseUri` did not return a URI with a
+ `sse` scheme.
+
# 1.3.2
- Add IPv6 hosting support.
diff --git a/pkg/dds/lib/src/dds_impl.dart b/pkg/dds/lib/src/dds_impl.dart
index 192e9ad5..a4c2f81 100644
--- a/pkg/dds/lib/src/dds_impl.dart
+++ b/pkg/dds/lib/src/dds_impl.dart
@@ -205,7 +205,7 @@
}
final pathSegments = _cleanupPathSegments(uri);
pathSegments.add(_kSseHandlerPath);
- return uri.replace(pathSegments: pathSegments);
+ return uri.replace(scheme: 'sse', pathSegments: pathSegments);
}
String _getNamespace(_DartDevelopmentServiceClient client) =>
diff --git a/pkg/dds/pubspec.yaml b/pkg/dds/pubspec.yaml
index 447170c..16e8c0b 100644
--- a/pkg/dds/pubspec.yaml
+++ b/pkg/dds/pubspec.yaml
@@ -3,7 +3,7 @@
A library used to spawn the Dart Developer Service, used to communicate with
a Dart VM Service instance.
-version: 1.3.2
+version: 1.3.3
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/dds
diff --git a/pkg/dds/test/sse_smoke_test.dart b/pkg/dds/test/sse_smoke_test.dart
index 682fa18..823f816 100644
--- a/pkg/dds/test/sse_smoke_test.dart
+++ b/pkg/dds/test/sse_smoke_test.dart
@@ -66,7 +66,6 @@
'binary': Platform.environment['CHROME_PATH'] ?? '',
},
});
- print('Capabilities: $capabilities');
webdriver = await createDriver(
desired: capabilities,
);
@@ -93,8 +92,10 @@
expect(dds.isRunning, true);
await webdriver.get('http://localhost:${server.port}');
final testeeConnection = await handler.connections.next;
- testeeConnection.sink.add(dds.sseUri.toString());
+ // Replace the sse scheme with http as sse isn't supported for CORS.
+ testeeConnection.sink
+ .add(dds.sseUri.replace(scheme: 'http').toString());
final response = json.decode(await testeeConnection.stream.first);
final version = service.Version.parse(response);
expect(version.major > 0, isTrue);
diff --git a/pkg/dds/test/uri_test.dart b/pkg/dds/test/uri_test.dart
index 8afd523..8c7e64e 100644
--- a/pkg/dds/test/uri_test.dart
+++ b/pkg/dds/test/uri_test.dart
@@ -44,6 +44,7 @@
expect(
dds.sseUri,
serviceUri.replace(
+ scheme: 'sse',
pathSegments: ['\$debugHandler'],
),
);
@@ -73,6 +74,7 @@
expect(
dds.sseUri,
serviceUri.replace(
+ scheme: 'sse',
pathSegments: [authCode, '\$debugHandler'],
),
);
diff --git a/pkg/nnbd_migration/lib/src/front_end/resources/migration.css b/pkg/nnbd_migration/lib/src/front_end/resources/migration.css
index 0d594f0..4c121b8 100644
--- a/pkg/nnbd_migration/lib/src/front_end/resources/migration.css
+++ b/pkg/nnbd_migration/lib/src/front_end/resources/migration.css
@@ -371,8 +371,8 @@
}
.region.added-region {
- background-color: #263952; /* $dark-selection-color */
- color: #c0c2c5; /* $dark-editor-text */
+ background-color: #178afd;
+ color: #fff;
}
.region.removed-region {
@@ -381,12 +381,12 @@
}
.region.informative-region {
- background-color: #178afd; /* $dark-selection-color */
+ background-color: #263952;
color: #fff;
display: inline-block;
- height: 14px;
+ height: 15px;
position: relative;
- top: 1px;
+ top: 2px;
}
.target {
diff --git a/pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart b/pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart
index 5de078e..bb624c2 100644
--- a/pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/resources/resources.g.dart
@@ -7486,7 +7486,7 @@
''';
String _migration_css;
-// migration_css md5 is 'c3045f5a8c1f62b4e8f5efd90e079029'
+// migration_css md5 is 'aa4c1eeef41fd9f06779ba7bac691ac2'
String _migration_css_base64 = '''
LyogQ29weXJpZ2h0IChjKSAyMDE5LCB0aGUgRGFydCBwcm9qZWN0IGF1dGhvcnMuIFBsZWFzZSBzZWUg
dGhlIEFVVEhPUlMgZmlsZSAgKi8KLyogZm9yIGRldGFpbHMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFVz
@@ -7590,100 +7590,99 @@
ZS1ubyB7CiAgYm9yZGVyLXJpZ2h0OiBzb2xpZCAjY2NjIDJweDsKfQoKLnJlZ2lvbiB7CiAgZGlzcGxh
eTogaW5saW5lLWJsb2NrOwogIHBvc2l0aW9uOiByZWxhdGl2ZTsKICB2aXNpYmlsaXR5OiB2aXNpYmxl
OwogIHotaW5kZXg6IDIwMDsKfQoKLnJlZ2lvbi5hZGRlZC1yZWdpb24gewogIGJhY2tncm91bmQtY29s
-b3I6ICMyNjM5NTI7IC8qICRkYXJrLXNlbGVjdGlvbi1jb2xvciAqLwogIGNvbG9yOiAjYzBjMmM1OyAv
-KiAkZGFyay1lZGl0b3ItdGV4dCAqLwp9CgoucmVnaW9uLnJlbW92ZWQtcmVnaW9uIHsKICBiYWNrZ3Jv
-dW5kLWNvbG9yOiAjRkE1NTdkOyAvKiAkZGFyay1waW5rICovCiAgY29sb3I6ICNmZmY7Cn0KCi5yZWdp
-b24uaW5mb3JtYXRpdmUtcmVnaW9uIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMTc4YWZkOyAvKiAkZGFy
-ay1zZWxlY3Rpb24tY29sb3IgKi8KICBjb2xvcjogI2ZmZjsKICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7
-CiAgaGVpZ2h0OiAxNHB4OwogIHBvc2l0aW9uOiByZWxhdGl2ZTsKICB0b3A6IDFweDsKfQoKLnRhcmdl
-dCB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzQ0NDsKICBwb3NpdGlvbjogcmVsYXRpdmU7CiAgdmlzaWJp
-bGl0eTogdmlzaWJsZTsKICBmb250LXdlaWdodDogNjAwOwp9CgouaW5mby1wYW5lbCB7CiAgZmxleDog
-MSAyMDBweDsKICBtYXJnaW46IDA7CiAgaGVpZ2h0OiAxMDAlOwogIGRpc3BsYXk6IGZsZXg7CiAgZmxl
-eC1kaXJlY3Rpb246IGNvbHVtbjsKfQoKLmluZm8tcGFuZWwgLmVkaXQtcGFuZWwgewogIGJhY2tncm91
-bmQtY29sb3I6ICMxMjIwMmY7CiAgb3ZlcmZsb3c6IGF1dG87Cn0KCi5pbmZvLXBhbmVsIC5wYW5lbC1j
-b250ZW50IHsKICBwYWRkaW5nOiA3cHg7Cn0KCi5pbmZvLXBhbmVsIC5wYW5lbC1jb250ZW50PiA6Zmly
-c3QtY2hpbGQgewogIG1hcmdpbi10b3A6IDA7Cn0KCi5pbmZvLXBhbmVsIC5ub3dyYXAgewogIHdoaXRl
-LXNwYWNlOiBub3dyYXA7Cn0KCi5pbmZvLXBhbmVsIHVsLAouaW5mby1wYW5lbCBvbCB7CiAgcGFkZGlu
-Zy1sZWZ0OiAyMHB4Owp9CgouaW5mby1wYW5lbCBsaSB7CiAgbWFyZ2luOiAwIDAgNXB4IDA7Cn0KCi5p
-bmZvLXBhbmVsIGEgewogIGNvbG9yOiAjMTM5YmI1Owp9CgouaW5mby1wYW5lbCBhOmhvdmVyIHsKICBj
-b2xvcjogIzFlYzdlNzsgLyogIzEzOWJiNSBsaWdodGVuZWQgMjAlICovCn0KCi5pbmZvLXBhbmVsIC5l
-ZGl0LWxpc3QgewogIGJhY2tncm91bmQtY29sb3I6ICMxMjIwMmY7CiAgb3ZlcmZsb3c6IGF1dG87Cn0K
-Ci5lZGl0LXBhbmVsIHsKICBtYXJnaW4tdG9wOiA2cHg7CiAgZmxleDogMSAxMDBweDsKfQoKLmVkaXQt
-bGlzdCB7CiAgZmxleDogMiAxMDBweDsKfQoKLmVkaXQtbGlzdCAuZWRpdCB7CiAgbWFyZ2luOiAzcHgg
-MDsKfQoKLmVkaXQtbGlzdCAuZWRpdC1saW5rIHsKICBjdXJzb3I6IHBvaW50ZXI7Cn0KCi5wb3B1cC1w
-YW5lIHsKICBkaXNwbGF5OiBub25lOwogIHBvc2l0aW9uOiBmaXhlZDsKICB0b3A6IDE1MHB4OwogIGxl
-ZnQ6IDE1MHB4OwogIHJpZ2h0OiAxNTBweDsKICBib3R0b206IDE1MHB4OwogIGJvcmRlcjogMXB4IHNv
-bGlkIGJsYWNrOwogIGJvcmRlci10b3A6IDJweCBzb2xpZCBibGFjazsKICBib3JkZXItcmFkaXVzOiA3
-cHg7CiAgYm94LXNoYWRvdzogMHB4IDBweCAyMHB4IDJweCAjYjRiZmNiMjI7CiAgei1pbmRleDogNDAw
-OwogIGJhY2tncm91bmQ6ICMyYjMwMzY7CiAgcGFkZGluZzogMjBweDsKfQoKLnBvcHVwLXBhbmUgLmNs
-b3NlIHsKICBwb3NpdGlvbjogYWJzb2x1dGU7CiAgcmlnaHQ6IDEwcHg7CiAgdG9wOiAxMHB4OwogIGN1
-cnNvcjogcG9pbnRlcjsKICB0ZXh0LXNoYWRvdzogMXB4IDFweCAycHggIzg4ODsKICBib3gtc2hhZG93
-OiAxcHggMXB4IDJweCAjMTExOwp9CgoucG9wdXAtcGFuZSBoMiB7CiAgcGFkZGluZzogMjFweDsKICBo
-ZWlnaHQ6IDEwJTsKICBtYXJnaW46IDBweDsKICBib3gtc2l6aW5nOiBib3JkZXItYm94Owp9CgoucG9w
-dXAtcGFuZSBwIHsKICBoZWlnaHQ6IDEwJTsKICBib3gtc2l6aW5nOiBib3JkZXItYm94OwogIHBhZGRp
-bmc6IDBweCAyMHB4Owp9CgoucG9wdXAtcGFuZSBwcmUgewogIGJhY2tncm91bmQ6ICMxMjIwMmY7CiAg
-cGFkZGluZzogMjBweDsKICBib3R0b206IDBweDsKICBvdmVyZmxvdzogYXV0byBzY3JvbGw7CiAgaGVp
-Z2h0OiA2NSU7CiAgbWFyZ2luOiAwcHg7CiAgYm94LXNpemluZzogYm9yZGVyLWJveDsKfQoKLnBvcHVw
-LXBhbmUgLmJ1dHRvbi5ib3R0b20gewogIG1hcmdpbjogMjBweCAwcHg7CiAgZGlzcGxheTogYmxvY2s7
-CiAgdGV4dC1hbGlnbjogY2VudGVyOwp9CgoucmVydW5uaW5nLXBhbmUgewogIGRpc3BsYXk6IG5vbmU7
-Cn0KCmJvZHkucmVydW5uaW5nIC5yZXJ1bm5pbmctcGFuZSB7CiAgZGlzcGxheTogYmxvY2s7CiAgcG9z
-aXRpb246IGZpeGVkOwogIHRvcDogMHB4OwogIGJvdHRvbTogMHB4OwogIGxlZnQ6IDBweDsKICByaWdo
-dDogMHB4OwogIGJhY2tncm91bmQtY29sb3I6ICMwMDAwMDBBQTsgLyogdHJhbnNsdWNlbnQgYmxhY2sg
-Ki8KICB6LWluZGV4OiA0MDA7Cn0KCi5yZXJ1bm5pbmctcGFuZSBoMSB7CiAgcG9zaXRpb246IGFic29s
-dXRlOwogIHRvcDogNTAlOwogIGxlZnQ6IDUwJTsKICB0cmFuc2Zvcm06IHRyYW5zbGF0ZSgtNTAlLCAt
-NTAlKTsKfQoKLmVkaXQtcGFuZWwgLnR5cGUtZGVzY3JpcHRpb24gewogIC8qIEZyb20gRGFydFBhZCAk
-ZGFyay1vcmFuZ2UgKi8KICBjb2xvcjogI2ZmOTE2ZTsKICBmb250LWZhbWlseTogbW9ub3NwYWNlOwp9
-Cgp1bC50cmFjZSB7CiAgZm9udC1zaXplOiAxM3B4OwogIGxpc3Qtc3R5bGUtdHlwZTogbm9uZTsKICBw
-YWRkaW5nLWxlZnQ6IDBweDsKfQoKdWwudHJhY2UgbGkgewogIGNvbG9yOiB3aGl0ZTsKfQoKdWwudHJh
-Y2UgbGkgLmZ1bmN0aW9uIHsKICAvKiBmcm9tIC5obGpzLXZhcmlhYmxlICovCiAgY29sb3I6ICMxNmFk
-Y2E7CiAgZm9udC1mYW1pbHk6IG1vbm9zcGFjZTsKICBmb250LXdlaWdodDogNjAwOwp9Cgp1bC50cmFj
-ZSBsaSBwLmRyYXdlciB7CiAgbWFyZ2luOiAzcHggMHB4OwogIHBhZGRpbmc6IDBweCAwcHggMHB4IDE0
-cHg7Cn0KCnVsLnRyYWNlIGxpIHAuZHJhd2VyIGJ1dHRvbiB7CiAgbWFyZ2luLXJpZ2h0OiAzcHg7Cn0K
-Ci5lbGV2YXRpb24tejQgewogIGJveC1zaGFkb3c6IDBweCAycHggNHB4IC0xcHggcmdiYSgwLCAwLCAw
-LCAwLjIpLAogICAgICAwcHggNHB4IDVweCAwcHggcmdiYSgwLCAwLCAwLCAwLjE0KSwKICAgICAgMHB4
-IDFweCAxMHB4IDBweCByZ2JhKDAsIDAsIDAsIC4xMik7Cn0KCmEgewogIGNvbG9yOiAjY2NjOwogIGZp
-bGw6ICNjY2M7CiAgdGV4dC1kZWNvcmF0aW9uOiBub25lOwp9CgphOmhvdmVyIHsKICBjb2xvcjogI2Ri
-ZGJkYjsgLyogI2NjYyBsaWdodGVudGVkIDMwJSovCiAgZmlsbDogI2ZmZjsKfQoKLmFkZC1oaW50LWxp
-bmsgewogIGRpc3BsYXk6IGlubGluZS1ibG9jazsKICBtYXJnaW46IDNweDsKfQoKLmFkZC1oaW50LWxp
-bms6aG92ZXIgewogIGNvbG9yOiAjZmZmOwp9CgpoZWFkZXIgYnV0dG9uIHsKICB0ZXh0LXRyYW5zZm9y
-bTogdXBwZXJjYXNlOwp9CgpoZWFkZXIgYSB7CiAgbWFyZ2luOiAwOwp9CgovKiBDYXJlZnVsIGhlcmUu
-IGBhLmJ1dHRvbmAgaXMgcmVwZXRpdGl2ZSBidXQgcmVxdWlyZWQgdG8gZ2V0IGNvcnJlY3QKICogc3Bl
-Y2lmaWNpdHkgKi8KYnV0dG9uLCAuYnV0dG9uLCBhLmJ1dHRvbiB7CiAgYmFja2dyb3VuZC1jb2xvcjog
-cmdiYSgyMiwgMTM4LCAyNTMsIDAuMTUpOwogIGJvcmRlcjogbm9uZTsKICBib3JkZXItcmFkaXVzOiAz
-cHg7CiAgcGFkZGluZzogM3B4IDEwcHg7CiAgZm9udC13ZWlnaHQ6IDUwMDsKICBmb250LWZvbnQ6IFJv
-Ym90bywgc2Fucy1zZXJpZjsKICBjb2xvcjogI2ZmZjsKfQoKYnV0dG9uOmhvdmVyLCAuYnV0dG9uOmhv
-dmVyIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDIyLCAxMzgsIDI1MywgMC4yOSk7CiAgY3Vyc29y
-OiBwb2ludGVyOwp9CgpidXR0b25bZGlzYWJsZWRdIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDI1
-NSwyNTUsMjU1LC4xMik7CiAgY29sb3I6IHJnYmEoMjU1LDI1NSwyNTUsLjM3KTsKICBjdXJzb3I6IG5v
-dC1hbGxvd2VkOwp9CgovKiBDaGFuZ2UgZWRpdCBwYW5lbCBidXR0b24gY29sb3JzICovCi5lZGl0LXBh
-bmVsIC5idXR0b24sIC5lZGl0LXBhbmVsIGJ1dHRvbiB7CiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSg2
-MywgMTA0LCAxNDgsIDAuNik7CiAgY29sb3I6IHdoaXRlOwp9Ci5lZGl0LXBhbmVsIC5idXR0b246aG92
-ZXIsIC5lZGl0LXBhbmVsIGJ1dHRvbjpob3ZlciB7CiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgxMDEs
-IDE1MywgMjA4LCAwLjYpOwogIGNvbG9yOiB3aGl0ZTsKfQoKLyoKICogQWRqdXN0bWVudHMgdG8gYWxp
-Z24gbWF0ZXJpYWwgaWNvbnMgaW4gdGhlIHRvb2xiYXIgYnV0dG9ucy4KKi8KLmFjdGlvbi1idXR0b24g
-PiBzcGFuIHsKICBwb3NpdGlvbjpyZWxhdGl2ZTsKICB0b3A6IC0zcHg7Cn0KCi5hY3Rpb24tYnV0dG9u
-IC5tYXRlcmlhbC1pY29ucyB7CiAgdG9wOiA0cHg7Cn0KCi8qIERvbid0IHNoaWZ0IHRoZSBpY29uIHdo
-ZW4gaXQncyBhIGRpcmVjdCBjaGlsZCBvZiB0aGUgYnV0dG9uICovCi5hY3Rpb24tYnV0dG9uID4gLm1h
-dGVyaWFsLWljb25zIHsKICB0b3A6IDFweDsKfQoKLyogU2hpZnQgdGhlIHRleHQgdG8gY2VudGVyIHdp
-dGggdGhlIGljb24uICovCi5hY3Rpb24tYnV0dG9uID4gc3Bhbi5sYWJlbCB7CiAgcG9zaXRpb246cmVs
-YXRpdmU7CiAgdG9wOiAtNHB4Owp9CgouYWN0aW9uLWJ1dHRvbiAubWF0ZXJpYWwtaWNvbnMgewogIGZv
-bnQtc2l6ZTogMjBweDsKICBwb3NpdGlvbjogcmVsYXRpdmU7Cn0KCi5wbGFjZWhvbGRlciB7CiAgY29s
-b3I6ICM3Nzc7CiAgdGV4dC1hbGlnbjogY2VudGVyOwogIG1hcmdpbi10b3A6IDNlbSAhaW1wb3J0YW50
-Owp9CgovKioKICogSExKUyBPdmVycmlkZXMKICovCi5obGpzIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAj
-MTIyMDJmOyAvKiAkZGFyay1jb2RlLWJhY2tncm91bmQtY29sb3IgKi8KICBjb2xvcjogI2MwYzJjNTsg
-LyogJGRhcmstZWRpdG9yLXRleHQgKi8KICBkaXNwbGF5OiBibG9jazsKICBvdmVyZmxvdy14OiBhdXRv
-OwogIHBhZGRpbmc6IDAuNWVtOwogIC8qKgogICAqIFRoaXMgYWxsb3dzIHRoZSBwZXItbGluZSBoaWdo
-bGlnaHRzIHRvIHNob3cuCiAgICovCiAgYmFja2dyb3VuZDogbm9uZTsKfQoKLmhsanMta2V5d29yZCwK
-LmhsanMtc2VsZWN0b3ItdGFnLAouaGxqcy1kZWxldGlvbiB7CiAgY29sb3I6ICM1MWM2ODY7IC8qIGNt
-LWtleXdvcmQgKi8KfQoKLmhsanMtbnVtYmVyIHsKICBjb2xvcjogIzYyNzk3ODsgLyogY20tbnVtYmVy
-ICovCn0KCi5obGpzLWNvbW1lbnQgewogIGNvbG9yOiAjOTE5OGI0OyAvKiBjbS1jb21tZW50ICovCn0K
-Ci5obGpzLWxpdGVyYWwgewogIGNvbG9yOiAjZWU4NjY2OyAvKiBjbS1hdG9tICovCn0KCi5obGpzLXN0
-cmluZyB7CiAgY29sb3I6ICNlNTUwNzQ7IC8qIGNtLXN0cmluZyAqLwp9CgouaGxqcy12YXJpYWJsZSB7
-CiAgY29sb3I6ICMxNmFkY2E7IC8qIGNtLXZhcmlhYmxlICovCn0KCi5obGpzLWxpbmsgewogIGNvbG9y
-OiAjZTU1MDc0OyAvKiBjbS1zdHJpbmcgKi8KfQouaGxqcy1zZWN0aW9uLAouaGxqcy10eXBlLAouaGxq
-cy1idWlsdF9pbiwKLmhsanMtdGl0bGUgewogIGNvbG9yOiAjZWU4NjY2OyAvKiBjbS12YXJpYWJsZS0y
-ICovCn0KCi5obGpzLWFkZGl0aW9uIHsKICBjb2xvcjogIzI2Mzk1MjsgLyogJGRhcmstc2VsZWN0aW9u
-LWNvbG9yICovCn0KCi5obGpzLW1ldGEgewogIGNvbG9yOiAjNjI3OTc4Owp9Cg==
+b3I6ICMxNzhhZmQ7CiAgY29sb3I6ICNmZmY7Cn0KCi5yZWdpb24ucmVtb3ZlZC1yZWdpb24gewogIGJh
+Y2tncm91bmQtY29sb3I6ICNGQTU1N2Q7IC8qICRkYXJrLXBpbmsgKi8KICBjb2xvcjogI2ZmZjsKfQoK
+LnJlZ2lvbi5pbmZvcm1hdGl2ZS1yZWdpb24gewogIGJhY2tncm91bmQtY29sb3I6ICMyNjM5NTI7CiAg
+Y29sb3I6ICNmZmY7CiAgZGlzcGxheTogaW5saW5lLWJsb2NrOwogIGhlaWdodDogMTVweDsKICBwb3Np
+dGlvbjogcmVsYXRpdmU7CiAgdG9wOiAycHg7Cn0KCi50YXJnZXQgewogIGJhY2tncm91bmQtY29sb3I6
+ICM0NDQ7CiAgcG9zaXRpb246IHJlbGF0aXZlOwogIHZpc2liaWxpdHk6IHZpc2libGU7CiAgZm9udC13
+ZWlnaHQ6IDYwMDsKfQoKLmluZm8tcGFuZWwgewogIGZsZXg6IDEgMjAwcHg7CiAgbWFyZ2luOiAwOwog
+IGhlaWdodDogMTAwJTsKICBkaXNwbGF5OiBmbGV4OwogIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47Cn0K
+Ci5pbmZvLXBhbmVsIC5lZGl0LXBhbmVsIHsKICBiYWNrZ3JvdW5kLWNvbG9yOiAjMTIyMDJmOwogIG92
+ZXJmbG93OiBhdXRvOwp9CgouaW5mby1wYW5lbCAucGFuZWwtY29udGVudCB7CiAgcGFkZGluZzogN3B4
+Owp9CgouaW5mby1wYW5lbCAucGFuZWwtY29udGVudD4gOmZpcnN0LWNoaWxkIHsKICBtYXJnaW4tdG9w
+OiAwOwp9CgouaW5mby1wYW5lbCAubm93cmFwIHsKICB3aGl0ZS1zcGFjZTogbm93cmFwOwp9CgouaW5m
+by1wYW5lbCB1bCwKLmluZm8tcGFuZWwgb2wgewogIHBhZGRpbmctbGVmdDogMjBweDsKfQoKLmluZm8t
+cGFuZWwgbGkgewogIG1hcmdpbjogMCAwIDVweCAwOwp9CgouaW5mby1wYW5lbCBhIHsKICBjb2xvcjog
+IzEzOWJiNTsKfQoKLmluZm8tcGFuZWwgYTpob3ZlciB7CiAgY29sb3I6ICMxZWM3ZTc7IC8qICMxMzli
+YjUgbGlnaHRlbmVkIDIwJSAqLwp9CgouaW5mby1wYW5lbCAuZWRpdC1saXN0IHsKICBiYWNrZ3JvdW5k
+LWNvbG9yOiAjMTIyMDJmOwogIG92ZXJmbG93OiBhdXRvOwp9CgouZWRpdC1wYW5lbCB7CiAgbWFyZ2lu
+LXRvcDogNnB4OwogIGZsZXg6IDEgMTAwcHg7Cn0KCi5lZGl0LWxpc3QgewogIGZsZXg6IDIgMTAwcHg7
+Cn0KCi5lZGl0LWxpc3QgLmVkaXQgewogIG1hcmdpbjogM3B4IDA7Cn0KCi5lZGl0LWxpc3QgLmVkaXQt
+bGluayB7CiAgY3Vyc29yOiBwb2ludGVyOwp9CgoucG9wdXAtcGFuZSB7CiAgZGlzcGxheTogbm9uZTsK
+ICBwb3NpdGlvbjogZml4ZWQ7CiAgdG9wOiAxNTBweDsKICBsZWZ0OiAxNTBweDsKICByaWdodDogMTUw
+cHg7CiAgYm90dG9tOiAxNTBweDsKICBib3JkZXI6IDFweCBzb2xpZCBibGFjazsKICBib3JkZXItdG9w
+OiAycHggc29saWQgYmxhY2s7CiAgYm9yZGVyLXJhZGl1czogN3B4OwogIGJveC1zaGFkb3c6IDBweCAw
+cHggMjBweCAycHggI2I0YmZjYjIyOwogIHotaW5kZXg6IDQwMDsKICBiYWNrZ3JvdW5kOiAjMmIzMDM2
+OwogIHBhZGRpbmc6IDIwcHg7Cn0KCi5wb3B1cC1wYW5lIC5jbG9zZSB7CiAgcG9zaXRpb246IGFic29s
+dXRlOwogIHJpZ2h0OiAxMHB4OwogIHRvcDogMTBweDsKICBjdXJzb3I6IHBvaW50ZXI7CiAgdGV4dC1z
+aGFkb3c6IDFweCAxcHggMnB4ICM4ODg7CiAgYm94LXNoYWRvdzogMXB4IDFweCAycHggIzExMTsKfQoK
+LnBvcHVwLXBhbmUgaDIgewogIHBhZGRpbmc6IDIxcHg7CiAgaGVpZ2h0OiAxMCU7CiAgbWFyZ2luOiAw
+cHg7CiAgYm94LXNpemluZzogYm9yZGVyLWJveDsKfQoKLnBvcHVwLXBhbmUgcCB7CiAgaGVpZ2h0OiAx
+MCU7CiAgYm94LXNpemluZzogYm9yZGVyLWJveDsKICBwYWRkaW5nOiAwcHggMjBweDsKfQoKLnBvcHVw
+LXBhbmUgcHJlIHsKICBiYWNrZ3JvdW5kOiAjMTIyMDJmOwogIHBhZGRpbmc6IDIwcHg7CiAgYm90dG9t
+OiAwcHg7CiAgb3ZlcmZsb3c6IGF1dG8gc2Nyb2xsOwogIGhlaWdodDogNjUlOwogIG1hcmdpbjogMHB4
+OwogIGJveC1zaXppbmc6IGJvcmRlci1ib3g7Cn0KCi5wb3B1cC1wYW5lIC5idXR0b24uYm90dG9tIHsK
+ICBtYXJnaW46IDIwcHggMHB4OwogIGRpc3BsYXk6IGJsb2NrOwogIHRleHQtYWxpZ246IGNlbnRlcjsK
+fQoKLnJlcnVubmluZy1wYW5lIHsKICBkaXNwbGF5OiBub25lOwp9Cgpib2R5LnJlcnVubmluZyAucmVy
+dW5uaW5nLXBhbmUgewogIGRpc3BsYXk6IGJsb2NrOwogIHBvc2l0aW9uOiBmaXhlZDsKICB0b3A6IDBw
+eDsKICBib3R0b206IDBweDsKICBsZWZ0OiAwcHg7CiAgcmlnaHQ6IDBweDsKICBiYWNrZ3JvdW5kLWNv
+bG9yOiAjMDAwMDAwQUE7IC8qIHRyYW5zbHVjZW50IGJsYWNrICovCiAgei1pbmRleDogNDAwOwp9Cgou
+cmVydW5uaW5nLXBhbmUgaDEgewogIHBvc2l0aW9uOiBhYnNvbHV0ZTsKICB0b3A6IDUwJTsKICBsZWZ0
+OiA1MCU7CiAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoLTUwJSwgLTUwJSk7Cn0KCi5lZGl0LXBhbmVsIC50
+eXBlLWRlc2NyaXB0aW9uIHsKICAvKiBGcm9tIERhcnRQYWQgJGRhcmstb3JhbmdlICovCiAgY29sb3I6
+ICNmZjkxNmU7CiAgZm9udC1mYW1pbHk6IG1vbm9zcGFjZTsKfQoKdWwudHJhY2UgewogIGZvbnQtc2l6
+ZTogMTNweDsKICBsaXN0LXN0eWxlLXR5cGU6IG5vbmU7CiAgcGFkZGluZy1sZWZ0OiAwcHg7Cn0KCnVs
+LnRyYWNlIGxpIHsKICBjb2xvcjogd2hpdGU7Cn0KCnVsLnRyYWNlIGxpIC5mdW5jdGlvbiB7CiAgLyog
+ZnJvbSAuaGxqcy12YXJpYWJsZSAqLwogIGNvbG9yOiAjMTZhZGNhOwogIGZvbnQtZmFtaWx5OiBtb25v
+c3BhY2U7CiAgZm9udC13ZWlnaHQ6IDYwMDsKfQoKdWwudHJhY2UgbGkgcC5kcmF3ZXIgewogIG1hcmdp
+bjogM3B4IDBweDsKICBwYWRkaW5nOiAwcHggMHB4IDBweCAxNHB4Owp9Cgp1bC50cmFjZSBsaSBwLmRy
+YXdlciBidXR0b24gewogIG1hcmdpbi1yaWdodDogM3B4Owp9CgouZWxldmF0aW9uLXo0IHsKICBib3gt
+c2hhZG93OiAwcHggMnB4IDRweCAtMXB4IHJnYmEoMCwgMCwgMCwgMC4yKSwKICAgICAgMHB4IDRweCA1
+cHggMHB4IHJnYmEoMCwgMCwgMCwgMC4xNCksCiAgICAgIDBweCAxcHggMTBweCAwcHggcmdiYSgwLCAw
+LCAwLCAuMTIpOwp9CgphIHsKICBjb2xvcjogI2NjYzsKICBmaWxsOiAjY2NjOwogIHRleHQtZGVjb3Jh
+dGlvbjogbm9uZTsKfQoKYTpob3ZlciB7CiAgY29sb3I6ICNkYmRiZGI7IC8qICNjY2MgbGlnaHRlbnRl
+ZCAzMCUqLwogIGZpbGw6ICNmZmY7Cn0KCi5hZGQtaGludC1saW5rIHsKICBkaXNwbGF5OiBpbmxpbmUt
+YmxvY2s7CiAgbWFyZ2luOiAzcHg7Cn0KCi5hZGQtaGludC1saW5rOmhvdmVyIHsKICBjb2xvcjogI2Zm
+ZjsKfQoKaGVhZGVyIGJ1dHRvbiB7CiAgdGV4dC10cmFuc2Zvcm06IHVwcGVyY2FzZTsKfQoKaGVhZGVy
+IGEgewogIG1hcmdpbjogMDsKfQoKLyogQ2FyZWZ1bCBoZXJlLiBgYS5idXR0b25gIGlzIHJlcGV0aXRp
+dmUgYnV0IHJlcXVpcmVkIHRvIGdldCBjb3JyZWN0CiAqIHNwZWNpZmljaXR5ICovCmJ1dHRvbiwgLmJ1
+dHRvbiwgYS5idXR0b24gewogIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMjIsIDEzOCwgMjUzLCAwLjE1
+KTsKICBib3JkZXI6IG5vbmU7CiAgYm9yZGVyLXJhZGl1czogM3B4OwogIHBhZGRpbmc6IDNweCAxMHB4
+OwogIGZvbnQtd2VpZ2h0OiA1MDA7CiAgZm9udC1mb250OiBSb2JvdG8sIHNhbnMtc2VyaWY7CiAgY29s
+b3I6ICNmZmY7Cn0KCmJ1dHRvbjpob3ZlciwgLmJ1dHRvbjpob3ZlciB7CiAgYmFja2dyb3VuZC1jb2xv
+cjogcmdiYSgyMiwgMTM4LCAyNTMsIDAuMjkpOwogIGN1cnNvcjogcG9pbnRlcjsKfQoKYnV0dG9uW2Rp
+c2FibGVkXSB7CiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgyNTUsMjU1LDI1NSwuMTIpOwogIGNvbG9y
+OiByZ2JhKDI1NSwyNTUsMjU1LC4zNyk7CiAgY3Vyc29yOiBub3QtYWxsb3dlZDsKfQoKLyogQ2hhbmdl
+IGVkaXQgcGFuZWwgYnV0dG9uIGNvbG9ycyAqLwouZWRpdC1wYW5lbCAuYnV0dG9uLCAuZWRpdC1wYW5l
+bCBidXR0b24gewogIGJhY2tncm91bmQtY29sb3I6IHJnYmEoNjMsIDEwNCwgMTQ4LCAwLjYpOwogIGNv
+bG9yOiB3aGl0ZTsKfQouZWRpdC1wYW5lbCAuYnV0dG9uOmhvdmVyLCAuZWRpdC1wYW5lbCBidXR0b246
+aG92ZXIgewogIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMTAxLCAxNTMsIDIwOCwgMC42KTsKICBjb2xv
+cjogd2hpdGU7Cn0KCi8qCiAqIEFkanVzdG1lbnRzIHRvIGFsaWduIG1hdGVyaWFsIGljb25zIGluIHRo
+ZSB0b29sYmFyIGJ1dHRvbnMuCiovCi5hY3Rpb24tYnV0dG9uID4gc3BhbiB7CiAgcG9zaXRpb246cmVs
+YXRpdmU7CiAgdG9wOiAtM3B4Owp9CgouYWN0aW9uLWJ1dHRvbiAubWF0ZXJpYWwtaWNvbnMgewogIHRv
+cDogNHB4Owp9CgovKiBEb24ndCBzaGlmdCB0aGUgaWNvbiB3aGVuIGl0J3MgYSBkaXJlY3QgY2hpbGQg
+b2YgdGhlIGJ1dHRvbiAqLwouYWN0aW9uLWJ1dHRvbiA+IC5tYXRlcmlhbC1pY29ucyB7CiAgdG9wOiAx
+cHg7Cn0KCi8qIFNoaWZ0IHRoZSB0ZXh0IHRvIGNlbnRlciB3aXRoIHRoZSBpY29uLiAqLwouYWN0aW9u
+LWJ1dHRvbiA+IHNwYW4ubGFiZWwgewogIHBvc2l0aW9uOnJlbGF0aXZlOwogIHRvcDogLTRweDsKfQoK
+LmFjdGlvbi1idXR0b24gLm1hdGVyaWFsLWljb25zIHsKICBmb250LXNpemU6IDIwcHg7CiAgcG9zaXRp
+b246IHJlbGF0aXZlOwp9CgoucGxhY2Vob2xkZXIgewogIGNvbG9yOiAjNzc3OwogIHRleHQtYWxpZ246
+IGNlbnRlcjsKICBtYXJnaW4tdG9wOiAzZW0gIWltcG9ydGFudDsKfQoKLyoqCiAqIEhMSlMgT3ZlcnJp
+ZGVzCiAqLwouaGxqcyB7CiAgYmFja2dyb3VuZC1jb2xvcjogIzEyMjAyZjsgLyogJGRhcmstY29kZS1i
+YWNrZ3JvdW5kLWNvbG9yICovCiAgY29sb3I6ICNjMGMyYzU7IC8qICRkYXJrLWVkaXRvci10ZXh0ICov
+CiAgZGlzcGxheTogYmxvY2s7CiAgb3ZlcmZsb3cteDogYXV0bzsKICBwYWRkaW5nOiAwLjVlbTsKICAv
+KioKICAgKiBUaGlzIGFsbG93cyB0aGUgcGVyLWxpbmUgaGlnaGxpZ2h0cyB0byBzaG93LgogICAqLwog
+IGJhY2tncm91bmQ6IG5vbmU7Cn0KCi5obGpzLWtleXdvcmQsCi5obGpzLXNlbGVjdG9yLXRhZywKLmhs
+anMtZGVsZXRpb24gewogIGNvbG9yOiAjNTFjNjg2OyAvKiBjbS1rZXl3b3JkICovCn0KCi5obGpzLW51
+bWJlciB7CiAgY29sb3I6ICM2Mjc5Nzg7IC8qIGNtLW51bWJlciAqLwp9CgouaGxqcy1jb21tZW50IHsK
+ICBjb2xvcjogIzkxOThiNDsgLyogY20tY29tbWVudCAqLwp9CgouaGxqcy1saXRlcmFsIHsKICBjb2xv
+cjogI2VlODY2NjsgLyogY20tYXRvbSAqLwp9CgouaGxqcy1zdHJpbmcgewogIGNvbG9yOiAjZTU1MDc0
+OyAvKiBjbS1zdHJpbmcgKi8KfQoKLmhsanMtdmFyaWFibGUgewogIGNvbG9yOiAjMTZhZGNhOyAvKiBj
+bS12YXJpYWJsZSAqLwp9CgouaGxqcy1saW5rIHsKICBjb2xvcjogI2U1NTA3NDsgLyogY20tc3RyaW5n
+ICovCn0KLmhsanMtc2VjdGlvbiwKLmhsanMtdHlwZSwKLmhsanMtYnVpbHRfaW4sCi5obGpzLXRpdGxl
+IHsKICBjb2xvcjogI2VlODY2NjsgLyogY20tdmFyaWFibGUtMiAqLwp9CgouaGxqcy1hZGRpdGlvbiB7
+CiAgY29sb3I6ICMyNjM5NTI7IC8qICRkYXJrLXNlbGVjdGlvbi1jb2xvciAqLwp9CgouaGxqcy1tZXRh
+IHsKICBjb2xvcjogIzYyNzk3ODsKfQo=
''';
String _migration_js;
diff --git a/pkg/vm_service/test/server_test.dart b/pkg/vm_service/test/server_test.dart
index ab0347c..37a9549 100644
--- a/pkg/vm_service/test/server_test.dart
+++ b/pkg/vm_service/test/server_test.dart
@@ -57,6 +57,7 @@
),
libraries: [],
breakpoints: [],
+ isSystemIsolate: false,
);
var request = rpcRequest("getIsolate", params: {'isolateId': isolate.id});
when(serviceMock.getIsolate(isolate.id))
@@ -84,6 +85,7 @@
),
libraries: [],
breakpoints: [],
+ isSystemIsolate: false,
);
var request = rpcRequest("setVMTimelineFlags", params: {
'isolateId': isolate.id,
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 0696dcb..2cc3c84 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -1240,8 +1240,9 @@
// Note: must read platform only *after* VM flags are parsed because
// they might affect how the platform is loaded.
#if !defined(DART_PRECOMPILED_RUNTIME)
+ // Load vm_platform_strong.dill for dart:* source support.
+ dfe.Init();
if (script_name != nullptr) {
- dfe.Init();
uint8_t* application_kernel_buffer = NULL;
intptr_t application_kernel_buffer_size = 0;
dfe.ReadScript(script_name, &application_kernel_buffer,
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index b33315f..4b381cb 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -158,62 +158,91 @@
Class& klass = Class::Handle(zone);
Closure& closure = Closure::Handle(zone);
- MallocGrowableArray<ObjectPtr> working_set;
- std::unique_ptr<WeakTable> visited(new WeakTable());
+ bool error_found = false;
+ Function& erroneous_closure_function = Function::Handle(zone);
+ Class& erroneous_nativewrapper_class = Class::Handle(zone);
+ const char* error_message = nullptr;
- NoSafepointScope no_safepoint;
- SendMessageValidator visitor(isolate->group(), visited.get(), &working_set);
+ {
+ NoSafepointScope no_safepoint;
+ // working_set contains only elements that have not been visited yet that
+ // need to be processed.
+ // So before adding elements to working_set ensure to check visited flag,
+ // set visited flag at the same time as the element is added.
+ MallocGrowableArray<ObjectPtr> working_set;
+ std::unique_ptr<WeakTable> visited(new WeakTable());
- visited->SetValueExclusive(obj.raw(), 1);
- working_set.Add(obj.raw());
+ SendMessageValidator visitor(isolate->group(), visited.get(), &working_set);
- while (!working_set.is_empty()) {
- ObjectPtr raw = working_set.RemoveLast();
+ visited->SetValueExclusive(obj.raw(), 1);
+ working_set.Add(obj.raw());
- if (visited->GetValueExclusive(raw) > 0) {
- continue;
- }
- visited->SetValueExclusive(raw, 1);
+ while (!working_set.is_empty() && !error_found) {
+ ObjectPtr raw = working_set.RemoveLast();
- const intptr_t cid = raw->GetClassId();
- switch (cid) {
- // List below matches the one in raw_object_snapshot.cc
+ const intptr_t cid = raw->GetClassId();
+ switch (cid) {
+ // List below matches the one in raw_object_snapshot.cc
#define MESSAGE_SNAPSHOT_ILLEGAL(type) \
case k##type##Cid: \
- return Exceptions::CreateUnhandledException( \
- zone, Exceptions::kArgumentValue, \
- "Illegal argument in isolate message : (object is a " #type ")");
+ error_message = \
+ "Illegal argument in isolate message : (object is a " #type ")"; \
+ error_found = true; \
+ break;
- MESSAGE_SNAPSHOT_ILLEGAL(DynamicLibrary);
- MESSAGE_SNAPSHOT_ILLEGAL(MirrorReference);
- MESSAGE_SNAPSHOT_ILLEGAL(Pointer);
- MESSAGE_SNAPSHOT_ILLEGAL(ReceivePort);
- MESSAGE_SNAPSHOT_ILLEGAL(RegExp);
- MESSAGE_SNAPSHOT_ILLEGAL(StackTrace);
- MESSAGE_SNAPSHOT_ILLEGAL(UserTag);
+ MESSAGE_SNAPSHOT_ILLEGAL(DynamicLibrary);
+ MESSAGE_SNAPSHOT_ILLEGAL(MirrorReference);
+ MESSAGE_SNAPSHOT_ILLEGAL(Pointer);
+ MESSAGE_SNAPSHOT_ILLEGAL(ReceivePort);
+ MESSAGE_SNAPSHOT_ILLEGAL(RegExp);
+ MESSAGE_SNAPSHOT_ILLEGAL(StackTrace);
+ MESSAGE_SNAPSHOT_ILLEGAL(UserTag);
- case kClosureCid: {
- closure = Closure::RawCast(raw);
- FunctionPtr func = closure.function();
- // We only allow closure of top level methods or static functions in a
- // class to be sent in isolate messages.
- if (!Function::IsImplicitStaticClosureFunction(func)) {
- return Exceptions::CreateUnhandledException(
- zone, Exceptions::kArgumentValue, "Closures are not allowed");
- }
- break;
- }
- default:
- if (cid >= kNumPredefinedCids) {
- klass = class_table->At(cid);
- if (klass.num_native_fields() != 0) {
- return Exceptions::CreateUnhandledException(
- zone, Exceptions::kArgumentValue,
- "Objects that extend NativeWrapper are not allowed");
+ case kClosureCid: {
+ closure = Closure::RawCast(raw);
+ FunctionPtr func = closure.function();
+ // We only allow closure of top level methods or static functions in a
+ // class to be sent in isolate messages.
+ if (!Function::IsImplicitStaticClosureFunction(func)) {
+ // All other closures are errors.
+ erroneous_closure_function = func;
+ error_found = true;
+ break;
}
+ break;
}
+ default:
+ if (cid >= kNumPredefinedCids) {
+ klass = class_table->At(cid);
+ if (klass.num_native_fields() != 0) {
+ erroneous_nativewrapper_class = klass.raw();
+ error_found = true;
+ break;
+ }
+ }
+ }
+ raw->ptr()->VisitPointers(&visitor);
}
- raw->ptr()->VisitPointers(&visitor);
+ }
+ if (error_found) {
+ const char* exception_message;
+ if (error_message != nullptr) {
+ exception_message = error_message;
+ } else if (!erroneous_closure_function.IsNull()) {
+ exception_message = OS::SCreate(zone,
+ "Illegal argument in isolate message"
+ " : (object is a closure - %s)",
+ erroneous_closure_function.ToCString());
+ } else {
+ ASSERT(!erroneous_nativewrapper_class.IsNull());
+ exception_message =
+ OS::SCreate(zone,
+ "Illegal argument in isolate message"
+ " : (object extends NativeWrapper - %s)",
+ erroneous_nativewrapper_class.ToCString());
+ }
+ return Exceptions::CreateUnhandledException(
+ zone, Exceptions::kArgumentValue, exception_message);
}
isolate->set_forward_table_new(nullptr);
return obj.raw();
diff --git a/runtime/tests/vm/dart/sendandexit_test.dart b/runtime/tests/vm/dart/sendandexit_test.dart
index f1fb1db..58e02c6 100644
--- a/runtime/tests/vm/dart/sendandexit_test.dart
+++ b/runtime/tests/vm/dart/sendandexit_test.dart
@@ -25,83 +25,93 @@
}
verifyCantSendAnonymousClosure() async {
- final result = await spawnWorker(doNothingWorker, () {});
- Expect.equals(
- "Invalid argument(s): Illegal argument in isolate message :"
- " (object is a closure - Function '<anonymous closure>': static.)",
- result.toString());
+ final receivePort = ReceivePort();
+ Expect.throws(
+ () => sendAndExit(receivePort.sendPort, () {}),
+ (e) =>
+ e.toString() ==
+ 'Invalid argument: "Illegal argument in isolate message : '
+ '(object is a closure - Function \'<anonymous closure>\': static.)"');
+ receivePort.close();
}
class NativeWrapperClass extends NativeFieldWrapperClass1 {}
verifyCantSendNative() async {
- final result = await spawnWorker(doNothingWorker, NativeWrapperClass());
- Expect.isTrue(result.toString().startsWith("Invalid argument(s): "
- "Illegal argument in isolate message : "
- "(object extends NativeWrapper"));
-}
-
-verifyCantSendRegexp() async {
- var receivePort = ReceivePort();
- final result = await spawnWorker(doNothingWorker, receivePort);
- Expect.equals(
- "Invalid argument(s): Illegal argument in isolate message : "
- "(object is a ReceivePort)",
- result.toString());
+ final receivePort = ReceivePort();
+ Expect.throws(
+ () => sendAndExit(receivePort.sendPort, NativeWrapperClass()),
+ (e) => e.toString().startsWith('Invalid argument: '
+ '"Illegal argument in isolate message : '
+ '(object extends NativeWrapper'));
receivePort.close();
}
-class Message {
- SendPort sendPort;
- Function closure;
+verifyCantSendReceivePort() async {
+ final receivePort = ReceivePort();
+ Expect.throws(
+ () => sendAndExit(receivePort.sendPort, receivePort),
+ // closure is encountered first before we reach ReceivePort instance
+ (e) => e.toString().startsWith(
+ 'Invalid argument: "Illegal argument in isolate message : '
+ '(object is a closure - Function \''));
+ receivePort.close();
+}
- Message(this.sendPort, this.closure);
+verifyCantSendRegexp() async {
+ final receivePort = ReceivePort();
+ final regexp = RegExp("");
+ Expect.throws(
+ () => sendAndExit(receivePort.sendPort, regexp),
+ (e) =>
+ e.toString() ==
+ 'Invalid argument: '
+ '"Illegal argument in isolate message : (object is a RegExp)"');
+ receivePort.close();
}
add(a, b) => a + b;
-worker(Message message) async {
- final port = new ReceivePort();
- final inbox = new StreamIterator<dynamic>(port);
- message.sendPort.send(message.closure(2, 3));
- port.close();
+worker(SendPort sendPort) async {
+ sendAndExit(sendPort, add);
}
verifyCanSendStaticMethod() async {
final port = ReceivePort();
final inbox = StreamIterator<dynamic>(port);
- final isolate = await Isolate.spawn(worker, Message(port.sendPort, add));
+ final isolate = await Isolate.spawn(worker, port.sendPort);
await inbox.moveNext();
- Expect.equals(inbox.current, 5);
+ Expect.equals(5, (inbox.current)(2, 3));
port.close();
}
verifyExitMessageIsPostedLast() async {
final port = ReceivePort();
final inbox = new StreamIterator<dynamic>(port);
- final isolate = await Isolate.spawn(worker, Message(port.sendPort, add),
- onExit: port.sendPort);
+ final isolate =
+ await Isolate.spawn(worker, port.sendPort, onExit: port.sendPort);
final receivedData = Completer<dynamic>();
final isolateExited = Completer<bool>();
port.listen((dynamic resultData) {
if (receivedData.isCompleted) {
Expect.equals(
- resultData, null); // exit message comes after data is receivedData
+ null, resultData); // exit message comes after data is receivedData
isolateExited.complete(true);
} else {
receivedData.complete(resultData);
}
});
- Expect.equals(await isolateExited.future, true);
- Expect.equals(await receivedData.future, 5);
+ Expect.equals(true, await isolateExited.future);
+ Expect.equals(5, (await receivedData.future)(2, 3));
port.close();
}
main() async {
await verifyCantSendAnonymousClosure();
await verifyCantSendNative();
+ await verifyCantSendReceivePort();
await verifyCantSendRegexp();
await verifyCanSendStaticMethod();
await verifyExitMessageIsPostedLast();
diff --git a/runtime/tests/vm/dart_2/sendandexit_test.dart b/runtime/tests/vm/dart_2/sendandexit_test.dart
index f1fb1db..58e02c6 100644
--- a/runtime/tests/vm/dart_2/sendandexit_test.dart
+++ b/runtime/tests/vm/dart_2/sendandexit_test.dart
@@ -25,83 +25,93 @@
}
verifyCantSendAnonymousClosure() async {
- final result = await spawnWorker(doNothingWorker, () {});
- Expect.equals(
- "Invalid argument(s): Illegal argument in isolate message :"
- " (object is a closure - Function '<anonymous closure>': static.)",
- result.toString());
+ final receivePort = ReceivePort();
+ Expect.throws(
+ () => sendAndExit(receivePort.sendPort, () {}),
+ (e) =>
+ e.toString() ==
+ 'Invalid argument: "Illegal argument in isolate message : '
+ '(object is a closure - Function \'<anonymous closure>\': static.)"');
+ receivePort.close();
}
class NativeWrapperClass extends NativeFieldWrapperClass1 {}
verifyCantSendNative() async {
- final result = await spawnWorker(doNothingWorker, NativeWrapperClass());
- Expect.isTrue(result.toString().startsWith("Invalid argument(s): "
- "Illegal argument in isolate message : "
- "(object extends NativeWrapper"));
-}
-
-verifyCantSendRegexp() async {
- var receivePort = ReceivePort();
- final result = await spawnWorker(doNothingWorker, receivePort);
- Expect.equals(
- "Invalid argument(s): Illegal argument in isolate message : "
- "(object is a ReceivePort)",
- result.toString());
+ final receivePort = ReceivePort();
+ Expect.throws(
+ () => sendAndExit(receivePort.sendPort, NativeWrapperClass()),
+ (e) => e.toString().startsWith('Invalid argument: '
+ '"Illegal argument in isolate message : '
+ '(object extends NativeWrapper'));
receivePort.close();
}
-class Message {
- SendPort sendPort;
- Function closure;
+verifyCantSendReceivePort() async {
+ final receivePort = ReceivePort();
+ Expect.throws(
+ () => sendAndExit(receivePort.sendPort, receivePort),
+ // closure is encountered first before we reach ReceivePort instance
+ (e) => e.toString().startsWith(
+ 'Invalid argument: "Illegal argument in isolate message : '
+ '(object is a closure - Function \''));
+ receivePort.close();
+}
- Message(this.sendPort, this.closure);
+verifyCantSendRegexp() async {
+ final receivePort = ReceivePort();
+ final regexp = RegExp("");
+ Expect.throws(
+ () => sendAndExit(receivePort.sendPort, regexp),
+ (e) =>
+ e.toString() ==
+ 'Invalid argument: '
+ '"Illegal argument in isolate message : (object is a RegExp)"');
+ receivePort.close();
}
add(a, b) => a + b;
-worker(Message message) async {
- final port = new ReceivePort();
- final inbox = new StreamIterator<dynamic>(port);
- message.sendPort.send(message.closure(2, 3));
- port.close();
+worker(SendPort sendPort) async {
+ sendAndExit(sendPort, add);
}
verifyCanSendStaticMethod() async {
final port = ReceivePort();
final inbox = StreamIterator<dynamic>(port);
- final isolate = await Isolate.spawn(worker, Message(port.sendPort, add));
+ final isolate = await Isolate.spawn(worker, port.sendPort);
await inbox.moveNext();
- Expect.equals(inbox.current, 5);
+ Expect.equals(5, (inbox.current)(2, 3));
port.close();
}
verifyExitMessageIsPostedLast() async {
final port = ReceivePort();
final inbox = new StreamIterator<dynamic>(port);
- final isolate = await Isolate.spawn(worker, Message(port.sendPort, add),
- onExit: port.sendPort);
+ final isolate =
+ await Isolate.spawn(worker, port.sendPort, onExit: port.sendPort);
final receivedData = Completer<dynamic>();
final isolateExited = Completer<bool>();
port.listen((dynamic resultData) {
if (receivedData.isCompleted) {
Expect.equals(
- resultData, null); // exit message comes after data is receivedData
+ null, resultData); // exit message comes after data is receivedData
isolateExited.complete(true);
} else {
receivedData.complete(resultData);
}
});
- Expect.equals(await isolateExited.future, true);
- Expect.equals(await receivedData.future, 5);
+ Expect.equals(true, await isolateExited.future);
+ Expect.equals(5, (await receivedData.future)(2, 3));
port.close();
}
main() async {
await verifyCantSendAnonymousClosure();
await verifyCantSendNative();
+ await verifyCantSendReceivePort();
await verifyCantSendRegexp();
await verifyCanSendStaticMethod();
await verifyExitMessageIsPostedLast();
diff --git a/sdk/lib/_http/http_impl.dart b/sdk/lib/_http/http_impl.dart
index 3cf75d9..eb0dee4 100644
--- a/sdk/lib/_http/http_impl.dart
+++ b/sdk/lib/_http/http_impl.dart
@@ -2412,6 +2412,9 @@
}
bool isSecure = uri.isScheme("https");
+ if (!isSecure && !isInsecureConnectionAllowed(uri.host)) {
+ throw new StateError("Insecure HTTP is not allowed by platform: $uri");
+ }
int port = uri.port;
if (port == 0) {
port =
diff --git a/tests/standalone/io/http_ban_http_allowed_cases_test.dart b/tests/standalone/io/http_ban_http_allowed_cases_test.dart
new file mode 100644
index 0000000..92e23c7
--- /dev/null
+++ b/tests/standalone/io/http_ban_http_allowed_cases_test.dart
@@ -0,0 +1,73 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This test file disallows VM from accepting insecure connections to all
+// domains and tests that HTTP connections to non-localhost targets fail.
+// HTTPS connections and localhost connections should still succeed.
+
+// SharedOptions=-Ddart.library.io.may_insecurely_connect_to_all_domains=false
+
+import "dart:async";
+import "dart:io";
+
+import "package:async_helper/async_helper.dart";
+
+import "http_bind_test.dart";
+
+Future<String> getLocalHostIP() async {
+ final interfaces = await NetworkInterface.list(
+ includeLoopback: false, type: InternetAddressType.IPv4);
+ return interfaces.first.addresses.first.address;
+}
+
+Future<void> testBanHttp(String serverHost,
+ Future<void> testCode(HttpClient client, Uri uri)) async {
+ final httpClient = new HttpClient();
+ final server = await HttpServer.bind(serverHost, 0);
+ final uri = Uri(scheme: 'http', host: serverHost, port: server.port);
+ try {
+ await testCode(httpClient, uri);
+ } finally {
+ httpClient.close(force: true);
+ await server.close();
+ }
+}
+
+Future<void> testWithLoopback() async {
+ await testBanHttp("127.0.0.1", (httpClient, uri) async {
+ await asyncTest(() async =>
+ await httpClient.getUrl(Uri.parse('http://localhost:${uri.port}')));
+ await asyncTest(() async =>
+ await httpClient.getUrl(Uri.parse('http://127.0.0.1:${uri.port}')));
+ });
+}
+
+Future<void> testWithIPv6() async {
+ if (await supportsIPV6()) {
+ await testBanHttp("::1", (httpClient, uri) async {
+ await asyncTest(() => httpClient.getUrl(uri));
+ });
+ }
+}
+
+Future<void> testWithHttps() async {
+ await testBanHttp(await getLocalHostIP(), (httpClient, uri) async {
+ asyncExpectThrows(
+ () => httpClient.getUrl(Uri(
+ scheme: 'https',
+ host: uri.host,
+ port: uri.port,
+ )),
+ (e) => e is SocketException || e is HandshakeException);
+ });
+}
+
+main() {
+ asyncStart();
+ Future.wait(<Future>[
+ testWithLoopback(),
+ testWithIPv6(),
+ testWithHttps(),
+ ]).then((_) => asyncEnd());
+}
diff --git a/tests/standalone/io/http_ban_insecure_connections_test.dart b/tests/standalone/io/http_ban_insecure_connections_test.dart
new file mode 100644
index 0000000..ae51a37
--- /dev/null
+++ b/tests/standalone/io/http_ban_insecure_connections_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This test file disallows VM from accepting insecure connections to all
+// domains and tests that HTTP connections to non-localhost targets fail.
+// HTTPS connections and localhost connections should still succeed.
+
+// SharedOptions=-Ddart.library.io.may_insecurely_connect_to_all_domains=false
+
+import "dart:async";
+import "dart:io";
+
+import "package:async_helper/async_helper.dart";
+
+Future<void> testWithHostname() async {
+ final httpClient = new HttpClient();
+ final uri = Uri(scheme: 'http', host: 'domain.invalid', port: 12345);
+ asyncExpectThrows(
+ () async => await httpClient.getUrl(uri),
+ (e) =>
+ e is StateError &&
+ e.message.contains("Insecure HTTP is not allowed by platform"));
+}
+
+main() {
+ asyncStart();
+ testWithHostname().then((_) => asyncEnd());
+}
diff --git a/tests/standalone/standalone_kernel.status b/tests/standalone/standalone_kernel.status
index aa8621f..1134509 100644
--- a/tests/standalone/standalone_kernel.status
+++ b/tests/standalone/standalone_kernel.status
@@ -16,6 +16,7 @@
[ $system == android ]
entrypoints_verification_test: Skip # Requires shared objects which the test script doesn't "adb push".
+io/http_ban_http_allowed_cases_test: Skip # Depends on grabbing local hostname which isn't supported.
io/network_policy_configuration_test: Skip # Can't pass -D params containing quotes to adb.
io/network_policy_invalid_domain_test: Skip # Can't pass -D params containing quotes to adb.
io/network_policy_tie_breaker_test: Skip # Can't pass -D params containing quotes to adb.
diff --git a/tests/standalone_2/io/http_ban_http_allowed_cases_test.dart b/tests/standalone_2/io/http_ban_http_allowed_cases_test.dart
new file mode 100644
index 0000000..92e23c7
--- /dev/null
+++ b/tests/standalone_2/io/http_ban_http_allowed_cases_test.dart
@@ -0,0 +1,73 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This test file disallows VM from accepting insecure connections to all
+// domains and tests that HTTP connections to non-localhost targets fail.
+// HTTPS connections and localhost connections should still succeed.
+
+// SharedOptions=-Ddart.library.io.may_insecurely_connect_to_all_domains=false
+
+import "dart:async";
+import "dart:io";
+
+import "package:async_helper/async_helper.dart";
+
+import "http_bind_test.dart";
+
+Future<String> getLocalHostIP() async {
+ final interfaces = await NetworkInterface.list(
+ includeLoopback: false, type: InternetAddressType.IPv4);
+ return interfaces.first.addresses.first.address;
+}
+
+Future<void> testBanHttp(String serverHost,
+ Future<void> testCode(HttpClient client, Uri uri)) async {
+ final httpClient = new HttpClient();
+ final server = await HttpServer.bind(serverHost, 0);
+ final uri = Uri(scheme: 'http', host: serverHost, port: server.port);
+ try {
+ await testCode(httpClient, uri);
+ } finally {
+ httpClient.close(force: true);
+ await server.close();
+ }
+}
+
+Future<void> testWithLoopback() async {
+ await testBanHttp("127.0.0.1", (httpClient, uri) async {
+ await asyncTest(() async =>
+ await httpClient.getUrl(Uri.parse('http://localhost:${uri.port}')));
+ await asyncTest(() async =>
+ await httpClient.getUrl(Uri.parse('http://127.0.0.1:${uri.port}')));
+ });
+}
+
+Future<void> testWithIPv6() async {
+ if (await supportsIPV6()) {
+ await testBanHttp("::1", (httpClient, uri) async {
+ await asyncTest(() => httpClient.getUrl(uri));
+ });
+ }
+}
+
+Future<void> testWithHttps() async {
+ await testBanHttp(await getLocalHostIP(), (httpClient, uri) async {
+ asyncExpectThrows(
+ () => httpClient.getUrl(Uri(
+ scheme: 'https',
+ host: uri.host,
+ port: uri.port,
+ )),
+ (e) => e is SocketException || e is HandshakeException);
+ });
+}
+
+main() {
+ asyncStart();
+ Future.wait(<Future>[
+ testWithLoopback(),
+ testWithIPv6(),
+ testWithHttps(),
+ ]).then((_) => asyncEnd());
+}
diff --git a/tests/standalone_2/io/http_ban_insecure_connections_test.dart b/tests/standalone_2/io/http_ban_insecure_connections_test.dart
new file mode 100644
index 0000000..ae51a37
--- /dev/null
+++ b/tests/standalone_2/io/http_ban_insecure_connections_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This test file disallows VM from accepting insecure connections to all
+// domains and tests that HTTP connections to non-localhost targets fail.
+// HTTPS connections and localhost connections should still succeed.
+
+// SharedOptions=-Ddart.library.io.may_insecurely_connect_to_all_domains=false
+
+import "dart:async";
+import "dart:io";
+
+import "package:async_helper/async_helper.dart";
+
+Future<void> testWithHostname() async {
+ final httpClient = new HttpClient();
+ final uri = Uri(scheme: 'http', host: 'domain.invalid', port: 12345);
+ asyncExpectThrows(
+ () async => await httpClient.getUrl(uri),
+ (e) =>
+ e is StateError &&
+ e.message.contains("Insecure HTTP is not allowed by platform"));
+}
+
+main() {
+ asyncStart();
+ testWithHostname().then((_) => asyncEnd());
+}
diff --git a/tests/standalone_2/standalone_2_kernel.status b/tests/standalone_2/standalone_2_kernel.status
index aa8621f..1134509 100644
--- a/tests/standalone_2/standalone_2_kernel.status
+++ b/tests/standalone_2/standalone_2_kernel.status
@@ -16,6 +16,7 @@
[ $system == android ]
entrypoints_verification_test: Skip # Requires shared objects which the test script doesn't "adb push".
+io/http_ban_http_allowed_cases_test: Skip # Depends on grabbing local hostname which isn't supported.
io/network_policy_configuration_test: Skip # Can't pass -D params containing quotes to adb.
io/network_policy_invalid_domain_test: Skip # Can't pass -D params containing quotes to adb.
io/network_policy_tie_breaker_test: Skip # Can't pass -D params containing quotes to adb.
diff --git a/tools/VERSION b/tools/VERSION
index 5247a95..a458b08 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 10
PATCH 0
-PRERELEASE 113
+PRERELEASE 114
PRERELEASE_PATCH 0
\ No newline at end of file