[FIX] web: truncate filename when importing custom module via studio
Issue: When uploading a large custom module via studio for importing, Chrome crashes with an internal SIGKILL and Firefox manages to load, but is really sluggish. Steps to reproduce: - Install Studio - In the Apps Dashboard > Customizations > Import - Upload a large custom module (50 MiB) - Chrome crashes, while on Firefox the page is sluggish Cause: In the module `base_import_module`, the `module_file` doesn't have a corresponding `filename`, therefor the name used to be displayed in the wizard is the content of the binary file in base64 encoding... For a module that is of a large size, this is a *gigantic* string that crashes Chrome and slows down the DOM on Firefox. Fix: Truncate the maximum filename that is displayed in the template to the max length necessary to encode in base64 (0xFF) 255 bytes, as 255 bytes is the maximum filename size on Linux/Windows/MacOS. Affected versions: 16.0 up to master Reference: opw-3491998 closes odoo/odoo#134532 X-original-commit: 218c9875c0422beb2a5b199797e531ed3625a13b Signed-off-by: Aaron Bohy (aab) <aab@odoo.com> Signed-off-by: Piryns Victor (pivi) <pivi@odoo.com>
This commit is contained in:
@@ -7,3 +7,12 @@
|
||||
export function isBinarySize(value) {
|
||||
return /^\d+(\.\d*)? [^0-9]+$/.test(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the length necessary for a base64 str to encode maxBytes
|
||||
* @param {number} maxBytes number of bytes we want to encode in base64
|
||||
* @returns {number} number of char
|
||||
*/
|
||||
export function toBase64Length(maxBytes) {
|
||||
return Math.ceil(maxBytes * 4 / 3);
|
||||
}
|
||||
|
||||
@@ -2,13 +2,16 @@
|
||||
|
||||
import { registry } from "@web/core/registry";
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
import { isBinarySize } from "@web/core/utils/binary";
|
||||
import { isBinarySize, toBase64Length } from "@web/core/utils/binary";
|
||||
import { download } from "@web/core/network/download";
|
||||
import { standardFieldProps } from "../standard_field_props";
|
||||
import { FileUploader } from "../file_handler";
|
||||
import { _t } from "@web/core/l10n/translation";
|
||||
|
||||
import { Component } from "@odoo/owl";
|
||||
|
||||
export const MAX_FILENAME_SIZE_BYTES = 0xFF; // filenames do not exceed 255 bytes on Linux/Windows/MacOS
|
||||
|
||||
export class BinaryField extends Component {
|
||||
static template = "web.BinaryField";
|
||||
static components = {
|
||||
@@ -32,7 +35,7 @@ export class BinaryField extends Component {
|
||||
this.props.record.data[this.props.fileNameField] ||
|
||||
this.props.record.data[this.props.name] ||
|
||||
""
|
||||
);
|
||||
).slice(0, toBase64Length(MAX_FILENAME_SIZE_BYTES));
|
||||
}
|
||||
|
||||
update({ data, name }) {
|
||||
|
||||
@@ -15,6 +15,8 @@ import { makeView, setupViewRegistries } from "@web/../tests/views/helpers";
|
||||
import { browser } from "@web/core/browser/browser";
|
||||
import { errorService } from "@web/core/errors/error_service";
|
||||
import { registry } from "@web/core/registry";
|
||||
import { MAX_FILENAME_SIZE_BYTES } from "@web/views/fields/binary/binary_field";
|
||||
import { toBase64Length } from "@web/core/utils/binary";
|
||||
|
||||
const BINARY_FILE =
|
||||
"R0lGODlhDAAMAKIFAF5LAP/zxAAAANyuAP/gaP///wAAAAAAACH5BAEAAAUALAAAAAAMAAwAAAMlWLPcGjDKFYi9lxKBOaGcF35DhWHamZUW0K4mAbiwWtuf0uxFAgA7";
|
||||
@@ -472,6 +474,28 @@ QUnit.module("Fields", (hooks) => {
|
||||
assert.containsNone(target, "button.fa-download");
|
||||
});
|
||||
|
||||
QUnit.test("Binary filename doesn't exceed 255 bytes", async function (assert) {
|
||||
const LARGE_BINARY_FILE = BINARY_FILE.repeat(5);
|
||||
assert.ok((LARGE_BINARY_FILE.length / 4 * 3) > MAX_FILENAME_SIZE_BYTES,
|
||||
"The initial binary file should be larger than max bytes that can represent the filename");
|
||||
serverData.models.partner.fields.document.default = LARGE_BINARY_FILE;
|
||||
await makeView({
|
||||
serverData,
|
||||
type: "form",
|
||||
resModel: "partner",
|
||||
arch: `
|
||||
<form>
|
||||
<field name="document"/>
|
||||
</form>
|
||||
`,
|
||||
});
|
||||
assert.strictEqual(
|
||||
target.querySelector(".o_field_binary input[type=text]").value.length,
|
||||
toBase64Length(MAX_FILENAME_SIZE_BYTES),
|
||||
"The filename shouldn't exceed the maximum size in bytes in base64"
|
||||
);
|
||||
});
|
||||
|
||||
QUnit.test("BinaryField filename is updated when using the pager", async function (assert) {
|
||||
serverData.models.partner.records.push(
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user