Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

Commit

Permalink
refactor($compile): move img[srcset] sanitizing to helper method
Browse files Browse the repository at this point in the history
  • Loading branch information
jbedard committed Jul 30, 2018
1 parent c133ef8 commit 4f68389
Showing 1 changed file with 53 additions and 45 deletions.
98 changes: 53 additions & 45 deletions src/ng/compile.js
Original file line number Diff line number Diff line change
Expand Up @@ -1631,6 +1631,57 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
}


function sanitizeSrcset(value) {
if (!value) {
return value;
}
if (!isString(value)) {
throw $compileMinErr('srcset', 'Can\'t pass trusted values to `$set(\'srcset\', value)`: "{0}"', value.toString());
}

// Such values are a bit too complex to handle automatically inside $sce.
// Instead, we sanitize each of the URIs individually, which works, even dynamically.

// It's not possible to work around this using `$sce.trustAsMediaUrl`.
// If you want to programmatically set explicitly trusted unsafe URLs, you should use
// `$sce.trustAsHtml` on the whole `img` tag and inject it into the DOM using the
// `ng-bind-html` directive.

var result = '';

// first check if there are spaces because it's not the same pattern
var trimmedSrcset = trim(value);
// ( 999x ,| 999w ,| ,|, )
var srcPattern = /(\s+\d+x\s*,|\s+\d+w\s*,|\s+,|,\s+)/;
var pattern = /\s/.test(trimmedSrcset) ? srcPattern : /(,)/;

// split srcset into tuple of uri and descriptor except for the last item
var rawUris = trimmedSrcset.split(pattern);

// for each tuples
var nbrUrisWith2parts = Math.floor(rawUris.length / 2);
for (var i = 0; i < nbrUrisWith2parts; i++) {
var innerIdx = i * 2;
// sanitize the uri
result += $sce.getTrustedMediaUrl(trim(rawUris[innerIdx]));
// add the descriptor
result += ' ' + trim(rawUris[innerIdx + 1]);
}

// split the last item into uri and descriptor
var lastTuple = trim(rawUris[i * 2]).split(/\s/);

// sanitize the last uri
result += $sce.getTrustedMediaUrl(trim(lastTuple[0]));

// and add the last descriptor if any
if (lastTuple.length === 2) {
result += (' ' + trim(lastTuple[1]));
}
return result;
}


function Attributes(element, attributesToCopy) {
if (attributesToCopy) {
var keys = Object.keys(attributesToCopy);
Expand Down Expand Up @@ -1767,51 +1818,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
nodeName = nodeName_(this.$$element);

// Sanitize img[srcset] values.
if (nodeName === 'img' && key === 'srcset' && value) {
if (!isString(value)) {
throw $compileMinErr('srcset', 'Can\'t pass trusted values to `$set(\'srcset\', value)`: "{0}"', value.toString());
}

// Such values are a bit too complex to handle automatically inside $sce.
// Instead, we sanitize each of the URIs individually, which works, even dynamically.

// It's not possible to work around this using `$sce.trustAsMediaUrl`.
// If you want to programmatically set explicitly trusted unsafe URLs, you should use
// `$sce.trustAsHtml` on the whole `img` tag and inject it into the DOM using the
// `ng-bind-html` directive.

var result = '';

// first check if there are spaces because it's not the same pattern
var trimmedSrcset = trim(value);
// ( 999x ,| 999w ,| ,|, )
var srcPattern = /(\s+\d+x\s*,|\s+\d+w\s*,|\s+,|,\s+)/;
var pattern = /\s/.test(trimmedSrcset) ? srcPattern : /(,)/;

// split srcset into tuple of uri and descriptor except for the last item
var rawUris = trimmedSrcset.split(pattern);

// for each tuples
var nbrUrisWith2parts = Math.floor(rawUris.length / 2);
for (var i = 0; i < nbrUrisWith2parts; i++) {
var innerIdx = i * 2;
// sanitize the uri
result += $sce.getTrustedMediaUrl(trim(rawUris[innerIdx]));
// add the descriptor
result += ' ' + trim(rawUris[innerIdx + 1]);
}

// split the last item into uri and descriptor
var lastTuple = trim(rawUris[i * 2]).split(/\s/);

// sanitize the last uri
result += $sce.getTrustedMediaUrl(trim(lastTuple[0]));

// and add the last descriptor if any
if (lastTuple.length === 2) {
result += (' ' + trim(lastTuple[1]));
}
this[key] = value = result;
if (nodeName === 'img' && key === 'srcset') {
this[key] = value = sanitizeSrcset(value, '$set(\'srcset\', value)');
}

if (writeAttr !== false) {
Expand Down

0 comments on commit 4f68389

Please sign in to comment.