Summary
Replacing an existing PDF through Optimole’s Media Library Replace file action can leave the replacement with 0600 filesystem permissions. The replacement is expected to retain web-readable file permissions comparable to a normal Media Library upload. In the reported case, the direct PDF URL instead returns 403 Forbidden until its permissions are manually changed to 0644, making the replaced document unavailable to visitors.
Customer context
Product / area: Optimole, Media Library attachment replacement
Version: Not provided
Environment: WordPress; hosting, web-server, PHP, and filesystem method details were not provided
Integration / third party: None identified
Reported error / symptom: A normally uploaded PDF is 0644 and accessible; replacing that PDF through Edit more details > Replace file leaves it at 0600 and its direct URL returns 403 Forbidden
Impact: The replaced PDF is inaccessible until its filesystem permissions are manually corrected
Reproduction notes
Reported reproduction:
- Upload a PDF normally through the WordPress Media Library and observe
0644; confirm its direct URL is accessible.
- Open the attachment via
Media Library > Edit more details.
- Use Optimole’s
Replace file action to upload another PDF.
- Observe that the replacement has
0600 permissions and its direct URL returns 403 Forbidden.
- Change the mode manually to
0644; the URL becomes accessible immediately.
The customer reports reproducing this with a separate test PDF. The workflow was not independently executed during repository inspection; hosting and version details are missing.
Diagnosis
Conclusion
The reported permission failure is consistent with a reachable Optimole replacement path. The handler moves the PHP upload temporary file directly over the existing attachment, attempts a filesystem permission normalization, and reports success without checking whether that operation succeeded. The customer’s controlled normal-upload versus replacement comparison provides runtime evidence that the replacement can remain at 0600. The precise host-level reason for the failed normalization is not established.
Where this likely occurs
- Media Library attachment edit surface:
inc/media_rename/attachment_edit.php — Optml_Attachment_Edit::replace_file() lines 332–377 validates the uploaded PDF and passes the raw $_FILES['file'] temporary path into the replacer.
- Attachment replacement filesystem path:
inc/media_rename/attachment_replace.php — Optml_Attachment_Replace::replace() lines 61–105 moves the temporary file onto the existing source path at lines 82–84, calls chmod( $original_file, FS_CHMOD_FILE ) at line 86, does not inspect its result, and returns success at line 105.
- Git history: commit
6077f05c (fix: file permissions after move) introduced the permission call and is contained in tags v4.0.0 through v4.2.10. The replacement feature first shipped in the v4.0.0 version boundary.
Engineering notes
The move occurs before permission normalization, so the destination can initially inherit properties of the PHP upload temporary file. FS_CHMOD_FILE and the active WP_Filesystem implementation come from the WordPress runtime; WordPress core source was not present in the inspected plugin checkout, so behavior across filesystem transports was not independently verified. The current Optimole path treats replacement as successful even when permission normalization returns a failure. PDF files follow this same path and do not have an image-only branch around the permission call. The resulting HTTP 403 is produced by the hosting/web-server access layer after the replacement leaves the file unreadable to that layer.
Test coverage status
tests/media_rename/test-attachment-edit.php — test_replace_file_valid_jpeg_replacement() lines 256–287 covers a successful JPEG AJAX replacement but does not assert destination permissions and does not model the reported PDF case. tests/media_rename/test-attachment-replace.php — test_replacements() and do_replace_test() lines 65–139 cover JPEG replacement and metadata outcomes without permission assertions. No relevant PDF or 0600 permission coverage was found during inspection. Tests were inspected but not executed because the product workspace is read-only and the WordPress test environment was not established for this investigation.
What to verify or explore next
- Reproduce with a PDF whose PHP upload temporary file begins at
0600, recording the destination mode before and after Optml_Attachment_Replace::replace().
- Verify the return value of the filesystem permission operation and the runtime value of
FS_CHMOD_FILE in the affected environment.
- Compare direct-filesystem and other supported
WP_Filesystem transports, including file ownership and process umask differences.
- Run the focused media replacement PHPUnit suites in
tests/media_rename/test-attachment-edit.php and tests/media_rename/test-attachment-replace.php under the affected WordPress/PHP environment.
Unknowns / follow-up
The affected Optimole, WordPress, and PHP versions are unknown. The active filesystem transport, destination ownership, process user, umask, and reason for the permission operation’s failure were not provided. No ticket image was available, and no matching existing issue was found in Codeinwp/optimole-wp.
Confidence
Confidence: 88/100
The customer supplied a controlled comparison showing that only Optimole’s replacement path leaves the PDF at 0600, and repository inspection confirms that this path moves the upload temporary file onto the attachment while treating an unchecked permission-normalization call as successful. The exact reason chmod fails in the reported environment remains unknown, but the product path can complete with an inaccessible replacement.
Source: HelpScout #3415371219
Generated by bug-report-triage (ID: bug-report-triage_6a7b390d21f812.49085803)
Summary
Replacing an existing PDF through Optimole’s Media Library
Replace fileaction can leave the replacement with0600filesystem permissions. The replacement is expected to retain web-readable file permissions comparable to a normal Media Library upload. In the reported case, the direct PDF URL instead returns403 Forbiddenuntil its permissions are manually changed to0644, making the replaced document unavailable to visitors.Customer context
Product / area: Optimole, Media Library attachment replacement
Version: Not provided
Environment: WordPress; hosting, web-server, PHP, and filesystem method details were not provided
Integration / third party: None identified
Reported error / symptom: A normally uploaded PDF is
0644and accessible; replacing that PDF throughEdit more details>Replace fileleaves it at0600and its direct URL returns403 ForbiddenImpact: The replaced PDF is inaccessible until its filesystem permissions are manually corrected
Reproduction notes
Reported reproduction:
0644; confirm its direct URL is accessible.Media Library>Edit more details.Replace fileaction to upload another PDF.0600permissions and its direct URL returns403 Forbidden.0644; the URL becomes accessible immediately.The customer reports reproducing this with a separate test PDF. The workflow was not independently executed during repository inspection; hosting and version details are missing.
Diagnosis
Conclusion
The reported permission failure is consistent with a reachable Optimole replacement path. The handler moves the PHP upload temporary file directly over the existing attachment, attempts a filesystem permission normalization, and reports success without checking whether that operation succeeded. The customer’s controlled normal-upload versus replacement comparison provides runtime evidence that the replacement can remain at
0600. The precise host-level reason for the failed normalization is not established.Where this likely occurs
inc/media_rename/attachment_edit.php—Optml_Attachment_Edit::replace_file()lines 332–377 validates the uploaded PDF and passes the raw$_FILES['file']temporary path into the replacer.inc/media_rename/attachment_replace.php—Optml_Attachment_Replace::replace()lines 61–105 moves the temporary file onto the existing source path at lines 82–84, callschmod( $original_file, FS_CHMOD_FILE )at line 86, does not inspect its result, and returns success at line 105.6077f05c(fix: file permissions after move) introduced the permission call and is contained in tagsv4.0.0throughv4.2.10. The replacement feature first shipped in thev4.0.0version boundary.Engineering notes
The move occurs before permission normalization, so the destination can initially inherit properties of the PHP upload temporary file.
FS_CHMOD_FILEand the activeWP_Filesystemimplementation come from the WordPress runtime; WordPress core source was not present in the inspected plugin checkout, so behavior across filesystem transports was not independently verified. The current Optimole path treats replacement as successful even when permission normalization returns a failure. PDF files follow this same path and do not have an image-only branch around the permission call. The resulting HTTP403is produced by the hosting/web-server access layer after the replacement leaves the file unreadable to that layer.Test coverage status
tests/media_rename/test-attachment-edit.php—test_replace_file_valid_jpeg_replacement()lines 256–287 covers a successful JPEG AJAX replacement but does not assert destination permissions and does not model the reported PDF case.tests/media_rename/test-attachment-replace.php—test_replacements()anddo_replace_test()lines 65–139 cover JPEG replacement and metadata outcomes without permission assertions. No relevant PDF or0600permission coverage was found during inspection. Tests were inspected but not executed because the product workspace is read-only and the WordPress test environment was not established for this investigation.What to verify or explore next
0600, recording the destination mode before and afterOptml_Attachment_Replace::replace().FS_CHMOD_FILEin the affected environment.WP_Filesystemtransports, including file ownership and process umask differences.tests/media_rename/test-attachment-edit.phpandtests/media_rename/test-attachment-replace.phpunder the affected WordPress/PHP environment.Unknowns / follow-up
The affected Optimole, WordPress, and PHP versions are unknown. The active filesystem transport, destination ownership, process user, umask, and reason for the permission operation’s failure were not provided. No ticket image was available, and no matching existing issue was found in
Codeinwp/optimole-wp.Confidence
Confidence: 88/100
The customer supplied a controlled comparison showing that only Optimole’s replacement path leaves the PDF at
0600, and repository inspection confirms that this path moves the upload temporary file onto the attachment while treating an unchecked permission-normalization call as successful. The exact reasonchmodfails in the reported environment remains unknown, but the product path can complete with an inaccessible replacement.Source: HelpScout #3415371219
Generated by bug-report-triage (ID: bug-report-triage_6a7b390d21f812.49085803)