This issue has been created
There is 1 update.
 
 
XWiki Platform / cid:jira-generated-image-avatar-3de75d0c-8e41-493d-87a4-be7eb9fbb7c6 XWIKI-24685 Open

When the move of an attachment fails, a redirection to an attachment that was never created is left behind

 
View issue   ·   Add comment
 

Issue created

 
cid:jira-generated-image-avatar-dabb17b4-a85b-44da-9a35-1ca6b6649f01 Vincent Massol created this issue on 11/Aug/26 15:49
 
Summary: When the move of an attachment fails, a redirection to an attachment that was never created is left behind
Issue Type: cid:jira-generated-image-avatar-3de75d0c-8e41-493d-87a4-be7eb9fbb7c6 Bug
Affects Versions: 14.0
Assignee: Unassigned
Components: Attachments
Created: 11/Aug/26 15:49
Priority: cid:jira-generated-image-static-minor-2f1471eb-1ce1-479b-992f-d58606f39929 Minor
Reporter: Vincent Massol
Description:

When an attachment is moved to another page with Create a redirection checked and the save of the target page fails, the move is rolled back — the attachment is put back on the source page — but the redirection object that was created on the source page is not removed. The source page is therefore left with a redirection pointing to an attachment that was never created.

Since a redirection is resolved before the attachment is served, and the resolution only checks that a redirection object exists (not that the attachment it points to exists), the attachment restored by the rollback also becomes unreachable: downloading it from the source page redirects to the target attachment, which does not exist.

Steps to reproduce:

  1. Create a page A holding an attachment file.txt, and a page B.
  2. Arrange for the save of B to fail (a storage error, for instance) — this is the hard part, the problem is not reachable through the UI without a failing save.
  3. From A, move file.txt to B, keeping Create a redirection checked.

Expected result:

  • Once the move has been rolled back, A holds file.txt and no redirection object.

Actual result:

  • A holds file.txt again (the rollback itself works), but it also holds a RedirectAttachmentClass object pointing to file.txt in B, which was never created.
  • Downloading file.txt from A redirects to the non-existent attachment in B instead of serving the restored attachment.

Notes:

  • Only the move-to-another-page path is affected. Renaming an attachment inside the same page performs a single save and has no rollback.
  • MoveAttachmentJob#initializeAutoRedirection adds the object to the source document before the first save, and the rollback branch of MoveAttachmentJob#transactionalMove restores the attachment but does not remove that object.
  • Present since the move-attachment feature was introduced in 14.0 (XWIKI-1657).
  • The current behaviour is pinned by MoveAttachmentJobTest#processTargetSaveFail, added by XWIKI-24680, so fixing this requires updating that test.
 
 

1 update

 
cid:jira-generated-image-avatar-dabb17b4-a85b-44da-9a35-1ca6b6649f01 Changes by Vincent Massol on 11/Aug/26 15:50
 
Description: When an attachment is moved to another page with _Create *Create a redirection_ redirection* checked and the save of the target page fails, the move is rolled back — the attachment is put back on the source page — but the redirection object that was created on the source page is not removed. The source page is therefore left with a redirection pointing to an attachment that was never created.

Since a redirection is resolved before the attachment is served, and the resolution only checks that a redirection object exists
\ (not that the attachment it points to exists \ ), the attachment restored by the rollback also becomes unreachable: downloading it from the source page redirects to the target attachment, which does not exist.

*Steps to reproduce:*

# Create a page {{A}} holding an attachment {{file.txt}}, and a page {{B}}.
# Arrange for the save of {{B}} to fail
\ (a storage error, for instance \ ) — this is the hard part, the problem is not reachable through the UI without a failing save.
# From {{A}}, move {{file.txt}} to {{B}}, keeping
_Create *Create a redirection_ redirection* checked.

*Expected result:*

* Once the move has been rolled back, {{A}} holds {{file.txt}} and no redirection object.

*Actual result:*

* {{A}} holds {{file.txt}} again
\ (the rollback itself works \ ), but it also holds a {{RedirectAttachmentClass}} object pointing to {{file.txt}} in {{B}}, which was never created.
* Downloading {{file.txt}} from {{A}} redirects to the non
\ -existent attachment in {{B}} instead of serving the restored attachment.

*Notes:*

* Only the move
\ -to \ -another \ -page path is affected. Renaming an attachment inside the same page performs a single save and has no rollback.
* {{MoveAttachmentJob#initializeAutoRedirection}} adds the object to the source document before the first save, and the rollback branch of {{MoveAttachmentJob#transactionalMove}} restores the attachment but does not remove that object.
* Present since the move
\ -attachment feature was introduced in 14.0 \ ( {{ XWIKI \ -1657 }}\ ).
* The current behaviour is pinned by {{MoveAttachmentJobTest#processTargetSaveFail}}, added by
{{ XWIKI \ -24680 }} , so fixing this requires updating that test.