mirror of
https://github.com/django/django.git
synced 2025-05-23 15:26:29 +00:00
[5.1.x] Fixed #36298 -- Truncated the overwritten file content in file_move_safe().
Regression in 58cd4902a71a3695dd6c21dc957f59c333db364c. Thanks Baptiste Mispelon for the report. Backport of 8ad3e80e88201f4c557f6fa79fcfc0f8a0961830 from main.
This commit is contained in:
parent
bbf376bbc8
commit
39b144badd
@ -55,6 +55,7 @@ def file_move_safe(
|
|||||||
| os.O_CREAT
|
| os.O_CREAT
|
||||||
| getattr(os, "O_BINARY", 0)
|
| getattr(os, "O_BINARY", 0)
|
||||||
| (os.O_EXCL if not allow_overwrite else 0)
|
| (os.O_EXCL if not allow_overwrite else 0)
|
||||||
|
| os.O_TRUNC
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
|
15
docs/releases/4.2.21.txt
Normal file
15
docs/releases/4.2.21.txt
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
===========================
|
||||||
|
Django 4.2.21 release notes
|
||||||
|
===========================
|
||||||
|
|
||||||
|
*Expected May 7, 2025*
|
||||||
|
|
||||||
|
Django 4.2.21 fixes a data loss bug in 4.2.20.
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
========
|
||||||
|
|
||||||
|
* Fixed a data corruption possibility in ``file_move_safe()`` when
|
||||||
|
``allow_overwrite=True``, where leftover content from a previously larger
|
||||||
|
file could remain after overwriting with a smaller one due to lack of
|
||||||
|
truncation (:ticket:`36298`).
|
15
docs/releases/5.1.9.txt
Normal file
15
docs/releases/5.1.9.txt
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
==========================
|
||||||
|
Django 5.1.9 release notes
|
||||||
|
==========================
|
||||||
|
|
||||||
|
*Expected May 7, 2025*
|
||||||
|
|
||||||
|
Django 5.1.9 fixes a data loss bug in 5.1.8.
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
========
|
||||||
|
|
||||||
|
* Fixed a data corruption possibility in ``file_move_safe()`` when
|
||||||
|
``allow_overwrite=True``, where leftover content from a previously larger
|
||||||
|
file could remain after overwriting with a smaller one due to lack of
|
||||||
|
truncation (:ticket:`36298`).
|
@ -25,6 +25,7 @@ versions of the documentation contain the release notes for any later releases.
|
|||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
|
|
||||||
|
5.1.9
|
||||||
5.1.8
|
5.1.8
|
||||||
5.1.7
|
5.1.7
|
||||||
5.1.6
|
5.1.6
|
||||||
@ -62,6 +63,7 @@ versions of the documentation contain the release notes for any later releases.
|
|||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
|
|
||||||
|
4.2.21
|
||||||
4.2.20
|
4.2.20
|
||||||
4.2.19
|
4.2.19
|
||||||
4.2.18
|
4.2.18
|
||||||
|
@ -496,6 +496,27 @@ class FileMoveSafeTests(unittest.TestCase):
|
|||||||
os.close(handle_b)
|
os.close(handle_b)
|
||||||
os.close(handle_c)
|
os.close(handle_c)
|
||||||
|
|
||||||
|
def test_file_move_ensure_truncation(self):
|
||||||
|
with tempfile.NamedTemporaryFile(delete=False) as src:
|
||||||
|
src.write(b"content")
|
||||||
|
src_name = src.name
|
||||||
|
self.addCleanup(
|
||||||
|
lambda: os.remove(src_name) if os.path.exists(src_name) else None
|
||||||
|
)
|
||||||
|
|
||||||
|
with tempfile.NamedTemporaryFile(delete=False) as dest:
|
||||||
|
dest.write(b"This is a longer content.")
|
||||||
|
dest_name = dest.name
|
||||||
|
self.addCleanup(os.remove, dest_name)
|
||||||
|
|
||||||
|
with mock.patch("django.core.files.move.os.rename", side_effect=OSError()):
|
||||||
|
file_move_safe(src_name, dest_name, allow_overwrite=True)
|
||||||
|
|
||||||
|
with open(dest_name, "rb") as f:
|
||||||
|
content = f.read()
|
||||||
|
|
||||||
|
self.assertEqual(content, b"content")
|
||||||
|
|
||||||
|
|
||||||
class SpooledTempTests(unittest.TestCase):
|
class SpooledTempTests(unittest.TestCase):
|
||||||
def test_in_memory_spooled_temp(self):
|
def test_in_memory_spooled_temp(self):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user