From 2758ce529587d042f9ecada354b9fec414577315 Mon Sep 17 00:00:00 2001 From: MAEDA Go Date: Tue, 29 Sep 2026 14:21:09 +0900 Subject: [PATCH] Show an error when pasting an image exceeds the limit of attachments at once Pasting images into a text area with Ctrl+V called addFile() directly and ignored its return value, so once the limit was reached, further pasted images were silently discarded without the error message that is shown when adding files via the file input or drag and drop. Co-Authored-By: Claude Opus 5.5 --- app/assets/javascripts/attachments.js | 5 ++++- test/system/issues_test.rb | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/attachments.js b/app/assets/javascripts/attachments.js index a0d3fef2a..5dac85803 100644 --- a/app/assets/javascripts/attachments.js +++ b/app/assets/javascripts/attachments.js @@ -359,7 +359,10 @@ function copyImageFromClipboard(e) { // get input file in the closest form var inputEl = $(this).closest("form").find('input:file.filedrop'); handleFileDropEvent.target = e.target; - addFile(inputEl, new File([file], filename, { type: file.type }), true); + if (addFile(inputEl, new File([file], filename, { type: file.type }), true) == null) { + window.alert(inputEl.data('max-number-of-files-message')); + break; + } } } } diff --git a/test/system/issues_test.rb b/test/system/issues_test.rb index a06461782..c0b0d8a49 100644 --- a/test/system/issues_test.rb +++ b/test/system/issues_test.rb @@ -191,6 +191,32 @@ class IssuesSystemTest < ApplicationSystemTestCase assert_no_selector '.add_attachment', :visible => true end + def test_pasting_image_beyond_max_attachments_at_once_should_show_error + set_tmp_attachments_directory + log_user('jsmith', 'jsmith') + + Redmine::Configuration.with('max_attachments_at_once' => 2) do + visit '/projects/ecookbook/issues/new' + end + paste_image = lambda do + page.execute_script(<<~JS) + // 1x1 1-bit grayscale PNG image + const png = Uint8Array.from(atob('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQAAAAA3bvkkAAAACklEQVR42mNgAAAAAgAB5Sfe/AAAAABJRU5ErkJggg=='), c => c.charCodeAt(0)); + const clipboardData = new DataTransfer(); + clipboardData.items.add(new File([png], 'image.png', { type: 'image/png' })); + const event = new Event('paste', { bubbles: true, cancelable: true }); + Object.defineProperty(event, 'clipboardData', { value: clipboardData }); + document.getElementById('issue_description').dispatchEvent(event); + JS + end + 2.times { paste_image.call } + assert_selector '.attachments_fields > span', :count => 2 + accept_alert(/maximum number of files that can be attached simultaneously \(2\)/) do + paste_image.call + end + assert_selector '.attachments_fields > span', :count => 2 + end + def test_create_issue_with_new_target_version log_user('jsmith', 'jsmith') -- 2.55.0