Permalink
Browse files

[IMP] Remove arbitrary file upload limit (25Mb) and turn it to an opt…

…ion (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
  • Loading branch information...
amigrave committed Jan 11, 2017
1 parent 3345256 commit 402379a48a31bc486145e81d8dae2910ae446b48
Showing with 42 additions and 4 deletions.
  1. +35 −1 addons/web/static/src/js/framework/utils.js
  2. +7 −3 addons/web/static/src/js/views/form_widgets.js
@@ -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();

2 comments on commit 402379a

@repodevs

This comment has been minimized.

Show comment
Hide comment
@repodevs

repodevs Jul 19, 2017

Contributor

why this commit not merged in 10.0 branch? cc @Yenthe666 @amigrave @mart-e

Contributor

repodevs replied Jul 19, 2017

why this commit not merged in 10.0 branch? cc @Yenthe666 @amigrave @mart-e

@Yenthe666

This comment has been minimized.

Show comment
Hide comment
@Yenthe666

Yenthe666 Jul 19, 2017

Contributor

Hi @repodevs,

The reason that this is in the master instead of the stable (V10) is because it is a new feature. When new features are added or big changes are made they'll be done against master. This is to prevent dangers of issues or bugs to a minimum in a stable version.

Contributor

Yenthe666 replied Jul 19, 2017

Hi @repodevs,

The reason that this is in the master instead of the stable (V10) is because it is a new feature. When new features are added or big changes are made they'll be done against master. This is to prevent dangers of issues or bugs to a minimum in a stable version.

Please sign in to comment.