diff --git a/src/components/widgets/FileWidget.js b/src/components/widgets/FileWidget.js index 916bbea386..87b477f81e 100644 --- a/src/components/widgets/FileWidget.js +++ b/src/components/widgets/FileWidget.js @@ -4,7 +4,7 @@ import PropTypes from "prop-types"; import { dataURItoBlob, shouldRender, setState } from "../../utils"; function addNameToDataURL(dataURL, name) { - return dataURL.replace(";base64", `;name=${name};base64`); + return dataURL.replace(";base64", `;name=${encodeURIComponent(name)};base64`); } function processFile(file) { diff --git a/test/StringField_test.js b/test/StringField_test.js index 8bb9d2b079..f13a483746 100644 --- a/test/StringField_test.js +++ b/test/StringField_test.js @@ -1520,7 +1520,6 @@ describe("StringField", () => { default: initialValue, }, }); - expect(comp.state.formData).eql(initialValue); }); @@ -1552,6 +1551,37 @@ describe("StringField", () => { ); }); + it("should encode file name with encodeURIComponent", () => { + const nonUriEncodedValue = "fileáéí óú1.txt"; + const uriEncodedValue = "file%C3%A1%C3%A9%C3%AD%20%C3%B3%C3%BA1.txt"; + + sandbox.stub(window, "FileReader").returns({ + set onload(fn) { + fn({ target: { result: "data:text/plain;base64,x=" } }); + }, + readAsDataUrl() {}, + }); + + const { comp, node } = createFormComponent({ + schema: { + type: "string", + format: "data-url", + }, + }); + + Simulate.change(node.querySelector("[type=file]"), { + target: { + files: [{ name: nonUriEncodedValue, size: 1, type: "type" }], + }, + }); + + return new Promise(setImmediate).then(() => + expect(comp.state.formData).eql( + "data:text/plain;name=" + uriEncodedValue + ";base64,x=" + ) + ); + }); + it("should render the widget with the expected id", () => { const { node } = createFormComponent({ schema: {