diff --git a/filebrowser/templatetags/fb_tags.py b/filebrowser/templatetags/fb_tags.py index b1d1ff0d1..bf01662a6 100644 --- a/filebrowser/templatetags/fb_tags.py +++ b/filebrowser/templatetags/fb_tags.py @@ -8,7 +8,7 @@ from django.utils.safestring import mark_safe from filebrowser.settings import EXTENSIONS, SELECT_FORMATS - +from filebrowser.utils import json_for_script register = template.Library() @@ -155,7 +155,7 @@ def get_file_extensions(qs): for item in v: if item: extensions.append(item) - return mark_safe(extensions) + return json_for_script(extensions) # Django 1.9 auto escapes simple_tag unless marked as safe diff --git a/filebrowser/utils.py b/filebrowser/utils.py index 8c66a9d00..c6baff9ca 100644 --- a/filebrowser/utils.py +++ b/filebrowser/utils.py @@ -4,9 +4,15 @@ import os import unicodedata import math +import json +from six import iteritems + +from django.core.serializers.json import DjangoJSONEncoder from django.utils import six from django.utils.module_loading import import_string +from django.utils.html import format_html +from django.utils.safestring import mark_safe from filebrowser.settings import STRICT_PIL, NORMALIZE_FILENAME, CONVERT_FILENAME from filebrowser.settings import VERSION_PROCESSORS @@ -19,6 +25,32 @@ except ImportError: import Image +_json_script_escapes = ( + ('>', '\\u003E'), + ('<', '\\u003C'), + ('&', '\\u0026'), +) + + +def json_for_script(value, encoder=DjangoJSONEncoder): + """ + Implementation of json_script from Django 2.1 + https://github.com/django/django/commit/8c709d79cbd1a7bb975f58090c17a1178a0efb80 + + If get_file_extensions is a list of unicode characters, JavaScript is unable to handle it and it will break upload.html + This will convert a list of unicode characters into a regular list, mark it safe, and will escape allthe HTML/XML special + characters with their unicode escapes + """ + json_str = json.dumps(value, cls=encoder) + + for bad_char, html_entity in _json_script_escapes: + json_str = json_str.replace(bad_char, html_entity) + + return format_html( + '{}', + mark_safe(json_str) + ) + def convert_filename(value): """ diff --git a/tests/test_templatetags.py b/tests/test_templatetags.py index c4322758d..8fb8807be 100644 --- a/tests/test_templatetags.py +++ b/tests/test_templatetags.py @@ -18,5 +18,5 @@ def test_get_all(self): def test_get_filtered(self): self.assertEqual( get_file_extensions(QueryDict('type=image')), - "['.jpg', '.jpeg', '.gif', '.png', '.tif', '.tiff']" + "[\".jpg\", \".jpeg\", \".gif\", \".png\", \".tif\", \".tiff\"]" )