[IMP] Remove arbitrary file upload limit (25Mb) and turn it to an option (Fixes #14824)

The hard coded limit dates back to a time where the browsers would crash
when using FileReader#readAsDataURL() on files of serveral dozens of Mb.
This limit is now obsolete and even IE Edge now supports the FileReader
api.

This commit removes the limit and turns it into an option so it's
possible to limit a particular binary field to a given amount from the
form views, eg:

    <field name="image" widget="image" options='{"max_file_size": "200k"}'/>

Note: this feature only works when the FileReader api is available.
      At time of writing, all major browsers supports this feature:
      http://caniuse.com/#search=FileReader
This commit is contained in:
Fabien Meghazi
2017-01-12 10:50:14 +01:00
parent 3345256579
commit 402379a48a
2 changed files with 42 additions and 4 deletions
+35 -1
View File
@@ -279,7 +279,7 @@ function binary_to_binsize (value) {
/**
* Returns a human readable size
*
* @param {Number} numner of bytes
* @param {Number} number of bytes
*/
function human_size (size) {
var units = _t("Bytes,Kb,Mb,Gb,Tb,Pb,Eb,Zb,Yb").split(',');
@@ -291,6 +291,39 @@ function human_size (size) {
return size.toFixed(2) + ' ' + units[i];
}
/**
* Naive and unlocalized human size parser.
* Returns the numeric amount specified in the given human formatted string.
*
* Eg:
*
* parse_human_size('4 Kb') === 4096
* parse_human_size('10m') === 10485760
* parse_human_size('340.99') === 340.99
*
* @param {String} input human formatted string
*/
function parse_human_size(size) {
var units = "bkmgtpezy".split('');
var parsed = size.toString().match(/^([0-9\.,]*)(\s*)?([a-z]{1,2})?$/i);
if (parsed === null) {
throw("Could not parse: " + size);
}
var amount = parseFloat(parsed[1].replace(',', '.'));
if (isNaN(amount) || !isFinite(amount)) {
throw("Invalid amount: " + size);
}
var unit = parsed[3] ? parsed[3][0].toLowerCase() : '';
var index = units.indexOf(unit);
if (unit && index === -1) {
throw("Invalid unit: " + size);
}
if (index > 0) {
amount = amount * Math.pow(1024, index);
}
return amount;
}
/**
* Returns a human readable number
*
@@ -513,6 +546,7 @@ return {
is_bin_size: is_bin_size,
binary_to_binsize: binary_to_binsize,
human_size: human_size,
parse_human_size: parse_human_size,
human_number: human_number,
round_precision: round_precision,
round_decimals: round_decimals,
@@ -1101,7 +1101,11 @@ var FieldBinary = common.AbstractField.extend(common.ReinitializeFieldMixin, {
this._super(field_manager, node);
this.binary_value = false;
this.useFileAPI = !!window.FileReader;
this.max_upload_size = 25 * 1024 * 1024; // 25Mo
try {
this.max_file_size = utils.parse_human_size(this.options.max_file_size);
} catch(e) {
this.max_file_size = 0;
}
if (!this.useFileAPI) {
this.fileupload_id = _.uniqueId('o_fileupload');
$(window).on(this.fileupload_id, function() {
@@ -1131,9 +1135,9 @@ var FieldBinary = common.AbstractField.extend(common.ReinitializeFieldMixin, {
if ((this.useFileAPI && file_node.files.length) || (!this.useFileAPI && $(file_node).val() !== '')) {
if (this.useFileAPI) {
var file = file_node.files[0];
if (file.size > this.max_upload_size) {
if (this.max_file_size && file.size > this.max_file_size) {
var msg = _t("The selected file exceed the maximum file size of %s.");
this.do_warn(_t("File upload"), _.str.sprintf(msg, utils.human_size(this.max_upload_size)));
this.do_warn(_t("File upload"), _.str.sprintf(msg, utils.human_size(this.max_file_size)));
return false;
}
var filereader = new FileReader();