From bed1547d4f8b1fc995f2c76f30ba5f20276a8ad6 Mon Sep 17 00:00:00 2001 From: Maurits van Rees Date: Mon, 8 Jun 2026 16:05:31 +0200 Subject: [PATCH] Restrict title to 1024 when setting it based on a filename. Set `max_length` in image and file content types. Max 1024 for title, max 10000 for description. For the other types (using `IBasic`), this is being changed in `plone.app.dexterity`. Backport of https://github.com/plone/plone.app.contenttypes/pull/744 for Plone 6.0. --- news/+7b7c8b72.bugfix.rst | 3 ++ plone/app/contenttypes/schema/file.xml | 2 ++ plone/app/contenttypes/schema/image.xml | 2 ++ plone/app/contenttypes/subscribers.py | 9 +++-- plone/app/contenttypes/tests/test_file.py | 42 ++++++++++++++++++++++ plone/app/contenttypes/tests/test_image.py | 42 ++++++++++++++++++++++ 6 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 news/+7b7c8b72.bugfix.rst diff --git a/news/+7b7c8b72.bugfix.rst b/news/+7b7c8b72.bugfix.rst new file mode 100644 index 00000000..66e65346 --- /dev/null +++ b/news/+7b7c8b72.bugfix.rst @@ -0,0 +1,3 @@ +Restrict title to 1024 and description to 10000. +This is for images and files. For others, a similar change is done in ``plone.app.dexterity``. +[maurits] diff --git a/plone/app/contenttypes/schema/file.xml b/plone/app/contenttypes/schema/file.xml index 59af7310..f4ba05ac 100644 --- a/plone/app/contenttypes/schema/file.xml +++ b/plone/app/contenttypes/schema/file.xml @@ -9,6 +9,7 @@ type="zope.schema.TextLine" > + 1024 False Title @@ -16,6 +17,7 @@ type="zope.schema.Text" > + 10000 False Description diff --git a/plone/app/contenttypes/schema/image.xml b/plone/app/contenttypes/schema/image.xml index 05c45972..c70e6186 100644 --- a/plone/app/contenttypes/schema/image.xml +++ b/plone/app/contenttypes/schema/image.xml @@ -9,6 +9,7 @@ type="zope.schema.TextLine" > + 1024 False Title @@ -16,6 +17,7 @@ type="zope.schema.Text" > + 10000 False Description diff --git a/plone/app/contenttypes/subscribers.py b/plone/app/contenttypes/subscribers.py index 42958729..a25ebd75 100644 --- a/plone/app/contenttypes/subscribers.py +++ b/plone/app/contenttypes/subscribers.py @@ -1,5 +1,10 @@ from plone.app.contenttypes.interfaces import IImage +try: + from plone.app.dexterity.config import MAX_TITLE_LENGTH as _MAX_TITLE_LENGTH +except ImportError: + _MAX_TITLE_LENGTH = 1024 + def set_title_description(obj, event): """Sets title to filename if no title @@ -14,8 +19,8 @@ def set_title_description(obj, event): else: datafield = obj.file if datafield: - filename = datafield.filename - obj.title = filename + filename = datafield.filename or "" + obj.title = filename[:_MAX_TITLE_LENGTH] description = obj.description if not description: diff --git a/plone/app/contenttypes/tests/test_file.py b/plone/app/contenttypes/tests/test_file.py index cf26591b..b608929b 100644 --- a/plone/app/contenttypes/tests/test_file.py +++ b/plone/app/contenttypes/tests/test_file.py @@ -148,6 +148,48 @@ def test_shortname_file(self): self.browser.getControl("Save").click() self.assertTrue(self.browser.url.endswith("my-special-file/view")) + def test_long_filename(self): + self.browser.open(self.portal_url) + self.browser.getLink("File").click() + file_path = os.path.join(os.path.dirname(__file__), "image.jpg") + file_ctl = self.browser.getControl(name="form.widgets.file") + filename = "i" * 2000 + ".png" + with io.FileIO(file_path, "rb") as f: + file_ctl.add_file(f, "image/png", filename) + self.browser.getControl("Save").click() + # Something, likely Zope, already restricts the id to 255 characters, + # although this does not count the ".png" suffix. + content_id = "i" * 255 + ".png" + self.assertTrue(self.browser.url.endswith(f"{content_id}/view")) + content = self.portal[content_id] + self.assertTrue(content.Title(), filename[:1024]) + + def test_long_title(self): + self.browser.open(self.portal_url) + self.browser.getLink("File").click() + widget = "form.widgets.description" + self.browser.getControl(name=widget).value = "L" * 10001 + file_path = os.path.join(os.path.dirname(__file__), "image.jpg") + file_ctl = self.browser.getControl(name="form.widgets.file") + with io.FileIO(file_path, "rb") as f: + file_ctl.add_file(f, "image/png", "image.jpg") + self.browser.getControl("Save").click() + self.assertTrue("There were some errors." in self.browser.contents) + self.assertTrue("Value is too long" in self.browser.contents) + + def test_long_description(self): + self.browser.open(self.portal_url) + self.browser.getLink("File").click() + widget = "form.widgets.title" + self.browser.getControl(name=widget).value = "L" * 1025 + file_path = os.path.join(os.path.dirname(__file__), "image.jpg") + file_ctl = self.browser.getControl(name="form.widgets.file") + with io.FileIO(file_path, "rb") as f: + file_ctl.add_file(f, "image/png", "image.jpg") + self.browser.getControl("Save").click() + self.assertTrue("There were some errors." in self.browser.contents) + self.assertTrue("Value is too long" in self.browser.contents) + def test_mime_icon_pdf_for_file_(self): self.browser.open(self.portal_url) self.browser.getLink("File").click() diff --git a/plone/app/contenttypes/tests/test_image.py b/plone/app/contenttypes/tests/test_image.py index b31a514a..de400a7c 100644 --- a/plone/app/contenttypes/tests/test_image.py +++ b/plone/app/contenttypes/tests/test_image.py @@ -157,6 +157,48 @@ def test_add_image_with_shortname(self): self.browser.getControl("Save").click() self.assertTrue(self.browser.url.endswith("my-special-image.jpg/view")) + def test_long_filename(self): + self.browser.open(self.portal_url) + self.browser.getLink("Image").click() + file_path = os.path.join(os.path.dirname(__file__), "image.jpg") + file_ctl = self.browser.getControl(name="form.widgets.image") + filename = "i" * 2000 + ".png" + with io.FileIO(file_path, "rb") as f: + file_ctl.add_file(f, "image/png", filename) + self.browser.getControl("Save").click() + # Something, likely Zope, already restricts the id to 255 characters, + # although this does not count the ".png" suffix. + content_id = "i" * 255 + ".png" + self.assertTrue(self.browser.url.endswith(f"{content_id}/view")) + content = self.portal[content_id] + self.assertTrue(content.Title(), filename[:1024]) + + def test_long_title(self): + self.browser.open(self.portal_url) + self.browser.getLink("Image").click() + widget = "form.widgets.description" + self.browser.getControl(name=widget).value = "L" * 10001 + file_path = os.path.join(os.path.dirname(__file__), "image.jpg") + file_ctl = self.browser.getControl(name="form.widgets.image") + with io.FileIO(file_path, "rb") as f: + file_ctl.add_file(f, "image/png", "image.jpg") + self.browser.getControl("Save").click() + self.assertTrue("There were some errors." in self.browser.contents) + self.assertTrue("Value is too long" in self.browser.contents) + + def test_long_description(self): + self.browser.open(self.portal_url) + self.browser.getLink("Image").click() + widget = "form.widgets.title" + self.browser.getControl(name=widget).value = "L" * 1025 + file_path = os.path.join(os.path.dirname(__file__), "image.jpg") + file_ctl = self.browser.getControl(name="form.widgets.image") + with io.FileIO(file_path, "rb") as f: + file_ctl.add_file(f, "image/png", "image.jpg") + self.browser.getControl("Save").click() + self.assertTrue("There were some errors." in self.browser.contents) + self.assertTrue("Value is too long" in self.browser.contents) + def test_image_view_fullscreen(self): self.browser.open(self.portal_url) self.browser.getLink("Image").click()