Merge remote-tracking branch 'origin/master' into SDK_AT_HEAD
diff --git a/angular_analyzer_plugin/lib/src/angular_driver.dart b/angular_analyzer_plugin/lib/src/angular_driver.dart
index 2f3a3a6..e590c71 100644
--- a/angular_analyzer_plugin/lib/src/angular_driver.dart
+++ b/angular_analyzer_plugin/lib/src/angular_driver.dart
@@ -382,25 +382,24 @@
Future<StandardAngular> getStandardAngular() async {
if (standardAngular == null) {
- final source = _sourceFactory.resolveUri(
- null,
- _hasAngularImported
- ? "package:angular/angular.dart"
- : "package:angular2/angular2.dart");
+ final source =
+ _sourceFactory.resolveUri(null, "package:angular/angular.dart");
if (source == null) {
return standardAngular;
}
- final securitySource = _sourceFactory.resolveUri(
- null,
- _hasAngularImported
- ? "package:angular/security.dart"
- : "package:angular2/security.dart");
+ final securitySource =
+ _sourceFactory.resolveUri(null, "package:angular/security.dart");
+ final protoSecuritySource = _sourceFactory.resolveUri(
+ null, 'package:webutil.html.types.proto/html.pb.dart');
standardAngular = new StandardAngular.fromAnalysis(
- await dartDriver.getResult(source.fullName),
- await dartDriver.getResult(securitySource.fullName));
+ angularResult: await dartDriver.getResult(source.fullName),
+ securityResult: await dartDriver.getResult(securitySource.fullName),
+ protoSecurityResult: protoSecuritySource == null
+ ? null
+ : await dartDriver.getResult(protoSecuritySource.fullName));
}
return standardAngular;
diff --git a/angular_analyzer_plugin/lib/src/resolver.dart b/angular_analyzer_plugin/lib/src/resolver.dart
index 86df668..bdcd056 100644
--- a/angular_analyzer_plugin/lib/src/resolver.dart
+++ b/angular_analyzer_plugin/lib/src/resolver.dart
@@ -1532,7 +1532,7 @@
attribute.valueOffset,
attribute.value.length,
AngularWarningCode.UNSAFE_BINDING,
- [securityContext.safeType.toString()]));
+ [securityContext.safeTypes.join(' or ')]));
return false;
}
@@ -1854,7 +1854,8 @@
final securityContext = input.securityContext;
if (securityContext != null) {
- if (typeSystem.isAssignableTo(attrType, securityContext.safeType)) {
+ if (securityContext.safeTypes
+ .any((safeType) => typeSystem.isAssignableTo(attrType, safeType))) {
return;
} else if (!securityContext.sanitizationAvailable) {
errorListener.onError(new AnalysisError(
@@ -1862,7 +1863,7 @@
attr.valueOffset,
attr.value.length,
AngularWarningCode.UNSAFE_BINDING,
- [securityContext.safeType.toString()]));
+ [securityContext.safeTypes.join(' or ')]));
return;
}
}
diff --git a/angular_analyzer_plugin/lib/src/standard_components.dart b/angular_analyzer_plugin/lib/src/standard_components.dart
index bea9514..5e5132e 100644
--- a/angular_analyzer_plugin/lib/src/standard_components.dart
+++ b/angular_analyzer_plugin/lib/src/standard_components.dart
@@ -234,10 +234,10 @@
}
class SecurityContext {
- final DartType safeType;
+ final List<DartType> safeTypes;
final bool sanitizationAvailable;
- SecurityContext(this.safeType, {this.sanitizationAvailable = true});
+ SecurityContext(this.safeTypes, {this.sanitizationAvailable = true});
}
class SecuritySchema {
@@ -322,23 +322,29 @@
this.securitySchema});
factory StandardAngular.fromAnalysis(
- ResolvedUnitResult ngResult, ResolvedUnitResult securityResult) {
- final ng = ngResult.unit.element.library.exportNamespace;
+ {ResolvedUnitResult angularResult,
+ ResolvedUnitResult securityResult,
+ ResolvedUnitResult protoSecurityResult}) {
+ final ng = angularResult.unit.element.library.exportNamespace;
final security = securityResult.unit.element.library.exportNamespace;
+ final protoSecurity = protoSecurityResult == null
+ ? null
+ : protoSecurityResult.unit.element.library.exportNamespace;
- SecurityContext makeSecurityContext(Element element,
- {bool sanitizationAvailable: true}) =>
- new SecurityContext((element as ClassElement)?.type,
- sanitizationAvailable: sanitizationAvailable);
+ List<DartType> safeTypes(String id) =>
+ [security.get('Safe$id'), protoSecurity?.get('Safe${id}Proto')]
+ .whereType<ClassElement>()
+ .map((e) => e?.type)
+ .where((e) => e != null)
+ .toList();
final securitySchema = new SecuritySchema(
- htmlSecurityContext: makeSecurityContext(security.get('SafeHtml')),
- urlSecurityContext: makeSecurityContext(security.get('SafeUrl')),
- styleSecurityContext: makeSecurityContext(security.get('SafeStyle')),
- scriptSecurityContext: makeSecurityContext(security.get('SafeScript'),
- sanitizationAvailable: false),
- resourceUrlSecurityContext: makeSecurityContext(
- security.get('SafeResourceUrl'),
+ htmlSecurityContext: SecurityContext(safeTypes('Html')),
+ urlSecurityContext: SecurityContext(safeTypes('Url')),
+ styleSecurityContext: SecurityContext(safeTypes('Style')),
+ scriptSecurityContext:
+ SecurityContext(safeTypes('Script'), sanitizationAvailable: false),
+ resourceUrlSecurityContext: SecurityContext(safeTypes('ResourceUrl'),
sanitizationAvailable: false));
return new StandardAngular(
diff --git a/angular_analyzer_plugin/test/angular_driver_test.dart b/angular_analyzer_plugin/test/angular_driver_test.dart
index d406286..52a0494d1c 100644
--- a/angular_analyzer_plugin/test/angular_driver_test.dart
+++ b/angular_analyzer_plugin/test/angular_driver_test.dart
@@ -131,37 +131,37 @@
final imgSrcSecurity = ng.securitySchema.lookup('img', 'src');
expect(imgSrcSecurity, isNotNull);
- expect(imgSrcSecurity.safeType.toString(), 'SafeUrl');
+ expect(imgSrcSecurity.safeTypes[0].toString(), 'SafeUrl');
expect(imgSrcSecurity.sanitizationAvailable, true);
final aHrefSecurity = ng.securitySchema.lookup('a', 'href');
expect(aHrefSecurity, isNotNull);
- expect(aHrefSecurity.safeType.toString(), 'SafeUrl');
+ expect(aHrefSecurity.safeTypes[0].toString(), 'SafeUrl');
expect(aHrefSecurity.sanitizationAvailable, true);
final innerHtmlSecurity = ng.securitySchema.lookupGlobal('innerHTML');
expect(innerHtmlSecurity, isNotNull);
- expect(innerHtmlSecurity.safeType.toString(), 'SafeHtml');
+ expect(innerHtmlSecurity.safeTypes[0].toString(), 'SafeHtml');
expect(innerHtmlSecurity.sanitizationAvailable, true);
final iframeSrcdocSecurity = ng.securitySchema.lookup('iframe', 'srcdoc');
expect(iframeSrcdocSecurity, isNotNull);
- expect(iframeSrcdocSecurity.safeType.toString(), 'SafeHtml');
+ expect(iframeSrcdocSecurity.safeTypes[0].toString(), 'SafeHtml');
expect(iframeSrcdocSecurity.sanitizationAvailable, true);
final styleSecurity = ng.securitySchema.lookupGlobal('style');
expect(styleSecurity, isNotNull);
- expect(styleSecurity.safeType.toString(), 'SafeStyle');
+ expect(styleSecurity.safeTypes[0].toString(), 'SafeStyle');
expect(styleSecurity.sanitizationAvailable, true);
final iframeSrcSecurity = ng.securitySchema.lookup('iframe', 'src');
expect(iframeSrcSecurity, isNotNull);
- expect(iframeSrcSecurity.safeType.toString(), 'SafeResourceUrl');
+ expect(iframeSrcSecurity.safeTypes[0].toString(), 'SafeResourceUrl');
expect(iframeSrcSecurity.sanitizationAvailable, false);
final scriptSrcSecurity = ng.securitySchema.lookup('script', 'src');
expect(scriptSrcSecurity, isNotNull);
- expect(scriptSrcSecurity.safeType.toString(), 'SafeResourceUrl');
+ expect(scriptSrcSecurity.safeTypes[0].toString(), 'SafeResourceUrl');
expect(scriptSrcSecurity.sanitizationAvailable, false);
}
}
@@ -192,7 +192,7 @@
expect(input.setter, isNotNull);
expect(input.setterType.toString(), equals('String'));
expect(input.securityContext, isNotNull);
- expect(input.securityContext.safeType.toString(), equals('SafeHtml'));
+ expect(input.securityContext.safeTypes[0].toString(), equals('SafeHtml'));
expect(input.securityContext.sanitizationAvailable, equals(true));
}
}
@@ -283,7 +283,8 @@
expect(input.setter, isNotNull);
expect(input.setterType.toString(), equals("String"));
expect(input.securityContext, isNotNull);
- expect(input.securityContext.safeType.toString(), equals('SafeUrl'));
+ expect(
+ input.securityContext.safeTypes[0].toString(), equals('SafeUrl'));
expect(input.securityContext.sanitizationAvailable, equals(true));
}
expect(outputElements, hasLength(0));
@@ -319,7 +320,7 @@
expect(input.setter, isNotNull);
expect(input.setterType.toString(), equals("String"));
expect(input.securityContext, isNotNull);
- expect(input.securityContext.safeType.toString(),
+ expect(input.securityContext.safeTypes[0].toString(),
equals('SafeResourceUrl'));
expect(input.securityContext.sanitizationAvailable, equals(false));
}