Prevent data-uri function from embedding files larger than 32KB.

Although IE8 does support data-uris, it only does so with a limit of 32KB. It's a silly limitation, but a source of potential bugs. When the limit is exceeded, the data-uri() function will simply return a normal url() value with a relative path to the asset.

One may pass --no-ie-compat to lessc to avoid this safeguard.
This commit is contained in:
Daniel Stockman
2013-02-18 18:54:11 -08:00
committed by Luke Page
parent 7116b3b1c5
commit e4fe935ea1
9 changed files with 39 additions and 0 deletions

View File

@@ -19,6 +19,7 @@ var options = {
strictImports: false,
rootpath: '',
relativeUrls: false,
ieCompat: true,
strictMaths: true
};
var continueProcessing = true,
@@ -72,6 +73,9 @@ args = args.filter(function (arg) {
case 'no-color':
options.color = false;
break;
case 'no-ie-compat':
options.ieCompat = false;
break;
case 'include-path':
if (!match[2]) {
sys.puts("include-path option requires a parameter");

View File

@@ -11,6 +11,7 @@
'strictImports', // option -
'dumpLineNumbers', // option - whether to dump line numbers
'compress', // option - whether to compress
'ieCompat', // option - whether to enforce IE compatibility (IE8 data-uri)
'mime', // browser only - mime type for sheet import
'entryPath', // browser only - path of entry less file
'rootFilename', // browser only - href of the entry less file

View File

@@ -416,6 +416,24 @@ tree.functions = {
var buf = fs.readFileSync(filePath);
// IE8 cannot handle a data-uri larger than 32KB. If this is exceeded
// and the --ieCompat flag is enabled, return a normal url() instead.
var DATA_URI_MAX_KB = 32,
fileSizeInKB = parseInt((buf.length / 1024), 10);
if (fileSizeInKB >= DATA_URI_MAX_KB) {
// the url() must be relative, not an absolute file path
filePath = path.relative(this.currentDirectory, filePath);
if (this.env.ieCompat !== false) {
// TODO: respect verbose or silent flags here
console.error("Skipped data-uri embedding of %s because its size (%dKB) exceeds IE8-safe %dKB!", filePath, fileSizeInKB, DATA_URI_MAX_KB);
return new(tree.URL)(new(tree.Anonymous)(filePath));
} else {
// if explicitly disabled (via --no-ie-compat on CLI, or env.ieCompat === false), merely warn
console.warn("WARNING: Embedding %s (%dKB) exceeds IE8's data-uri size limit of %dKB!", filePath, fileSizeInKB, DATA_URI_MAX_KB);
}
}
buf = useBase64 ? buf.toString('base64')
: encodeURIComponent(buf);

View File

@@ -31,6 +31,7 @@ var lessc_helper = {
sys.puts(" -h, --help Print help (this message) and exit.");
sys.puts(" --include-path Set include paths. Separated by `:'. Use `;' on Windows.");
sys.puts(" --no-color Disable colorized output.");
sys.puts(" --no-ie-compat Disable IE compatibility checks.");
sys.puts(" -l, --lint Syntax check only (lint).");
sys.puts(" -s, --silent Suppress output of error messages.");
sys.puts(" --strict-imports Force evaluation of imports.");

View File

@@ -44,3 +44,6 @@
uri-1: url('http://localhost:8081/browser/less/../../data/page.html');
uri-2: url('http://localhost:8081/browser/less/../../data/page.html');
}
#data-uri-toobig {
uri: url('http://localhost:8081/browser/less/../../data/data-uri-fail.png');
}

View File

@@ -43,3 +43,7 @@
uri-1: data-uri('text/html', '../../data/page.html');
uri-2: data-uri('../../data/page.html');
}
#data-uri-toobig {
uri: data-uri('../../data/data-uri-fail.png');
}

View File

@@ -52,3 +52,6 @@
uri-1: url('data:text/html,%3Ch1%3EThis%20page%20is%20100%25%20Awesome.%3C%2Fh1%3E%0A');
uri-2: url('data:text/html,%3Ch1%3EThis%20page%20is%20100%25%20Awesome.%3C%2Fh1%3E%0A');
}
#data-uri-toobig {
uri: url(../data/data-uri-fail.png);
}

BIN
test/data/data-uri-fail.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

View File

@@ -46,3 +46,8 @@
uri-1: data-uri('text/html', '../data/page.html');
uri-2: data-uri('../data/page.html');
}
// so, weirdly, the browser output is quoted, the less output is UNquoted
#data-uri-toobig {
uri: data-uri('../data/data-uri-fail.png');
}