Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.

Commit 73b4153

Browse files
TedSanderrkirov
authored andcommitted
fix(relative_url_resolver): Fix relative URI resolution for html.
Certain values used in href, src, and action attributes inside of HTML will be rewritten incorrectly. Such as javascript: values, empty strings, #, and data: values. Add improved calculation if URIs are relative or not.
1 parent 62c51a3 commit 73b4153

File tree

2 files changed

+82
-19
lines changed

2 files changed

+82
-19
lines changed

lib/core_dom/resource_url_resolver.dart

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
library angular.core_dom.resource_url_resolver;
99

1010
import 'dart:html';
11-
import 'dart:js' as js;
1211

1312
import 'package:di/di.dart';
1413
import 'package:di/annotations.dart';
@@ -29,12 +28,14 @@ class ResourceUrlResolver {
2928
static final RegExp quotes = new RegExp("[\"\']");
3029

3130
// Reconstruct the Uri without the http or https restriction due to Uri.base.origin
32-
final _baseUri = _getBaseUri();
31+
final String _baseUri;
3332

3433
final TypeToUriMapper _uriMapper;
3534
final ResourceResolverConfig _config;
3635

37-
ResourceUrlResolver(this._uriMapper, this._config);
36+
ResourceUrlResolver(this._uriMapper, this._config): _baseUri = _getBaseUri();
37+
38+
ResourceUrlResolver.forTests(this._uriMapper, this._config, this._baseUri);
3839

3940
static final NodeTreeSanitizer _nullTreeSanitizer = new _NullTreeSanitizer();
4041
static final docForParsing = document.implementation.createHtmlDocument('');
@@ -139,34 +140,42 @@ class ResourceUrlResolver {
139140
/// URIs, while [uri] is assumed to use 'packages/' syntax for
140141
/// package-relative URIs. Resulting URIs will use 'packages/' to indicate
141142
/// package-relative URIs.
142-
String combine(Uri baseUri, String uri) {
143+
String combine(Uri baseUri, String path) {
143144
if (!_config.useRelativeUrls) {
144-
return uri;
145+
return path;
145146
}
146147

147-
if (uri == null) {
148-
uri = baseUri.path;
148+
Uri resolved;
149+
if (path == null) {
150+
resolved = baseUri;
149151
} else {
152+
Uri uri = Uri.parse(path);
150153
// if it's absolute but not package-relative, then just use that
151154
// The "packages/" test is just for backward compatibility. It's ok to
152155
// not resolve them, even through they're relative URLs, because in a Dart
153156
// application, "packages/" is managed by pub which creates a symlinked
154157
// hierarchy and they should all resolve to the same file at any level
155158
// that a "packages/" exists.
156-
if (uri.startsWith("/") || uri.startsWith('packages/')) {
157-
return uri;
159+
if (uri.path.startsWith('/') ||
160+
uri.path.startsWith('packages/') ||
161+
uri.path.trim() == '' || // Covers both empty strings and # fragments
162+
uri.isAbsolute) {
163+
return _uriToPath(uri);
158164
}
165+
// Not an absolute uri. Resolve it to the base.
166+
resolved = baseUri.resolve(path);
159167
}
160-
// If it's not absolute, then resolve it first
161-
Uri resolved = baseUri.resolve(uri);
162-
163-
// If it's package-relative, tack on [packageRoot].
164-
if (resolved.scheme == 'package') {
165-
return '${_config.packageRoot}${resolved.path}';
166-
} else if (resolved.isAbsolute && resolved.toString().startsWith(_baseUri)) {
167-
return resolved.path;
168-
} else {
169-
return resolved.toString();
168+
169+
return _uriToPath(resolved);
170+
}
171+
172+
String _uriToPath(Uri uri) {
173+
if (uri.scheme == 'package') {
174+
return '${_config.packageRoot}${uri.path}';
175+
} else if (uri.isAbsolute && uri.toString().startsWith(_baseUri)) {
176+
return uri.path;
177+
} else {
178+
return uri.toString();
170179
}
171180
}
172181

test/core_dom/resource_url_resolver_spec.dart

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,60 @@ void main() {
241241
_run_resolver(useRelativeUrls: true);
242242
_run_resolver(useRelativeUrls: false);
243243
});
244+
245+
describe('url_resolver uri rewrite', () {
246+
ResourceUrlResolver resolver;
247+
248+
beforeEach((){
249+
var config = new ResourceResolverConfig.resolveRelativeUrls(true);
250+
var typeMapper = new DynamicTypeToUriMapper();
251+
resolver = new ResourceUrlResolver
252+
.forTests(typeMapper, config, 'http://localhost');
253+
});
254+
255+
it('should not rewrite absolute paths, empty paths and custom schemas',
256+
() {
257+
Uri baseUri = new Uri();
258+
expect(resolver.combine(baseUri, "/test")).toEqual("/test");
259+
expect(resolver.combine(baseUri, "#")).toEqual("#");
260+
expect(resolver.combine(baseUri, "#abc")).toEqual("#abc");
261+
expect(resolver.combine(baseUri, "")).toEqual("");
262+
expect(resolver.combine(baseUri, "javascript:void()"))
263+
.toEqual("javascript:void()");
264+
expect(resolver.combine(baseUri, "data:uriloijoi"))
265+
.toEqual("data:uriloijoi");
266+
});
267+
268+
it('should rewrite package relative base uris', () {
269+
Uri baseUri = Uri.parse("/packages/a.b.c/comp.dart");
270+
expect(resolver.combine(baseUri, "test.jpg"))
271+
.toEqual("/packages/a.b.c/test.jpg");
272+
expect(resolver.combine(baseUri, "test/test.jpg"))
273+
.toEqual("/packages/a.b.c/test/test.jpg");
274+
});
275+
276+
it('should rewrite current base uri to absolute without scheme', () {
277+
Uri baseUri = Uri.parse("http://localhost/test/test2/test.jgp");
278+
expect(resolver.combine(baseUri, 'test4.jpg'))
279+
.toEqual('/test/test2/test4.jpg');
280+
});
281+
282+
it('should rewrite external URIs to contain full scheme', () {
283+
Uri baseUri = Uri.parse("http://foo.com/test/test.jgp");
284+
expect(resolver.combine(baseUri, 'test4.jpg'))
285+
.toEqual('http://foo.com/test/test4.jpg');
286+
});
287+
288+
it('should not remove hash from URI', () {
289+
Uri baseUri = Uri.parse("/packages/a.b.c/comp.dart");
290+
expect(resolver.combine(baseUri, "test.jpg#1234"))
291+
.toEqual("/packages/a.b.c/test.jpg#1234");
292+
293+
Uri externalUri = Uri.parse("http://foo.com/test/test.jgp");
294+
expect(resolver.combine(externalUri, 'test4.jpg#1234'))
295+
.toEqual('http://foo.com/test/test4.jpg#1234');
296+
});
297+
});
244298
}
245299

246300
class NullSanitizer implements NodeValidator {

0 commit comments

Comments
 (0)