diff options
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/howto/custom-file-storage.txt | 20 | ||||
| -rw-r--r-- | docs/internals/deprecation.txt | 4 | ||||
| -rw-r--r-- | docs/ref/files/storage.txt | 20 | ||||
| -rw-r--r-- | docs/releases/1.8.txt | 21 |
4 files changed, 55 insertions, 10 deletions
diff --git a/docs/howto/custom-file-storage.txt b/docs/howto/custom-file-storage.txt index 9b217b8031..3d2c96e2bd 100644 --- a/docs/howto/custom-file-storage.txt +++ b/docs/howto/custom-file-storage.txt @@ -50,7 +50,7 @@ typically have to be overridden: * :meth:`Storage.size` * :meth:`Storage.url` -Note however that not all these methods are required and may be deliberately +Note however that not all these methods are required and may be deliberately omitted. As it happens, it is possible to leave each method unimplemented and still have a working Storage. @@ -87,7 +87,6 @@ instead). .. method:: get_valid_name(name) - Returns a filename suitable for use with the underlying storage system. The ``name`` argument passed to this method is the original filename sent to the server, after having any path information removed. Override this to customize @@ -96,21 +95,28 @@ how non-standard characters are converted to safe filenames. The code provided on ``Storage`` retains only alpha-numeric characters, periods and underscores from the original filename, removing everything else. -.. method:: get_available_name(name) +.. method:: get_available_name(name, max_length=None) Returns a filename that is available in the storage mechanism, possibly taking the provided filename into account. The ``name`` argument passed to this method will have already cleaned to a filename valid for the storage system, according to the ``get_valid_name()`` method described above. -.. versionchanged:: 1.7 +The length of the filename will not exceed ``max_length``, if provided. If a +free unique filename cannot be found, a :exc:`SuspiciousFileOperation +<django.core.exceptions.SuspiciousOperation>` exception is raised. + +If a file with ``name`` already exists, an underscore plus a random 7 character +alphanumeric string is appended to the filename before the extension. - If a file with ``name`` already exists, an underscore plus a random 7 - character alphanumeric string is appended to the filename before the - extension. +.. versionchanged:: 1.7 Previously, an underscore followed by a number (e.g. ``"_1"``, ``"_2"``, etc.) was appended to the filename until an available name in the destination directory was found. A malicious user could exploit this deterministic algorithm to create a denial-of-service attack. This change was also made in Django 1.6.6, 1.5.9, and 1.4.14. + +.. versionchanged:: 1.8 + + The ``max_length`` argument was added. diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt index 345202545e..fe392cff97 100644 --- a/docs/internals/deprecation.txt +++ b/docs/internals/deprecation.txt @@ -143,6 +143,10 @@ details on these changes. * Support for the ``=`` comparison operator in the ``if`` template tag will be removed. +* The backwards compatibility shims to allow ``Storage.get_available_name()`` + and ``Storage.save()`` to be defined without a ``max_length`` argument will + be removed. + .. _deprecation-removed-in-1.9: 1.9 diff --git a/docs/ref/files/storage.txt b/docs/ref/files/storage.txt index a16b6b6c9d..88da416dcf 100644 --- a/docs/ref/files/storage.txt +++ b/docs/ref/files/storage.txt @@ -114,12 +114,17 @@ The Storage Class in the storage system, or ``False`` if the name is available for a new file. - .. method:: get_available_name(name) + .. method:: get_available_name(name, max_length=None) Returns a filename based on the ``name`` parameter that's free and available for new content to be written to on the target storage system. + The length of the filename will not exceed ``max_length``, if provided. + If a free unique filename cannot be found, a + :exc:`SuspiciousFileOperation + <django.core.exceptions.SuspiciousOperation>` exception will be raised. + If a file with ``name`` already exists, an underscore plus a random 7 character alphanumeric string is appended to the filename before the extension. @@ -133,6 +138,10 @@ The Storage Class attack. This change was also made in Django 1.6.6, 1.5.9, and 1.4.14. + .. versionchanged:: 1.8 + + The ``max_length`` argument was added. + .. method:: get_valid_name(name) Returns a filename based on the ``name`` parameter that's suitable @@ -165,17 +174,24 @@ The Storage Class standard ``open()``. For storage systems that aren't accessible from the local filesystem, this will raise ``NotImplementedError`` instead. - .. method:: save(name, content) + .. method:: save(name, content, max_length=None) Saves a new file using the storage system, preferably with the name specified. If there already exists a file with this name ``name``, the storage system may modify the filename as necessary to get a unique name. The actual name of the stored file will be returned. + The ``max_length`` argument is passed along to + :meth:`get_available_name`. + The ``content`` argument must be an instance of :class:`django.core.files.File` or of a subclass of :class:`~django.core.files.File`. + .. versionchanged:: 1.8 + + The ``max_length`` argument was added. + .. method:: size(name) Returns the total size, in bytes, of the file referenced by ``name``. diff --git a/docs/releases/1.8.txt b/docs/releases/1.8.txt index c4e4e34894..122064971c 100644 --- a/docs/releases/1.8.txt +++ b/docs/releases/1.8.txt @@ -317,7 +317,15 @@ Email File Storage ^^^^^^^^^^^^ -* ... +* :meth:`Storage.get_available_name() + <django.core.files.storage.Storage.get_available_name>` and + :meth:`Storage.save() <django.core.files.storage.Storage.save>` + now take a ``max_length`` argument to implement storage-level maximum + filename length constraints. Filenames exceeding this argument will get + truncated. This prevents a database error when appending a unique suffix to a + long filename that already exists on the storage. See the :ref:`deprecation + note <storage-max-length-update>` about adding this argument to your custom + storage classes. File Uploads ^^^^^^^^^^^^ @@ -1432,6 +1440,17 @@ loader that inherits ``BaseLoader``, you must inherit ``Loader`` instead. Private API ``django.test.utils.TestTemplateLoader`` is deprecated in favor of ``django.template.loaders.locmem.Loader``. +.. _storage-max-length-update: + +Support for the ``max_length`` argument on custom ``Storage`` classes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``Storage`` subclasses should add ``max_length=None`` as a parameter to +:meth:`~django.core.files.storage.Storage.get_available_name` and/or +:meth:`~django.core.files.storage.Storage.save` if they override either method. +Support for storages that do not accept this argument will be removed in +Django 2.0. + ``qn`` replaced by ``compiler`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
