3282: (v 1.7.14) error 500/DjangoUnicodeDecodeError while doing _generate_preview_html after windows user uploads "unicode" (utf16-le) encoded file as attachment to review

damien******@gmai***** (Google Code) (Is this you? Claim this profile.)
david
david
March 27, 2014
What version are you running?
1.7.14
this could have been fixed in 1.7.22 (https://github.com/reviewboard/reviewboard/commit/c489b5e71d7b323cf6b1c0b8473cb899dffb3d01)
but I haven't tried.

What's the URL of the page containing the problem?
http://reviews.example.com/r/1234/
http://reviews.example.com/api/review-requests/1234/file-attachments/

What steps will reproduce the problem?
1. create a text file using notepad and save it as UTF-16LE (what windows calls "unicode") [1]
2. upload it to the review using "add a file"
3. boom error 500 "something broke contact your friendly admin".
   stack trace in _generate_preview_html

What is the expected output? What do you see instead?
correct preview file

What operating system are you using? What browser?
windows 7 / some version of IE.

Please provide any additional information below.
[1] http://stackoverflow.com/questions/3951722/whats-the-difference-between-unicode-and-utf8

Maybe a testcase where a user uploads an UTF16-LE encoded file to attach to a review would
be a good addition.


2013-11-15 23:29:49,075 - ERROR -  - Exception thrown for user damien at http://reviews.example.com/api/review-requests/1234/file-attachments/

'utf8' codec can't decode byte 0xff in position 0: invalid start byte. You passed in '\xff\xfe' (<type 'str'>)
Traceback (most recent call last):
  File "/usr/lib/python2.6/site-packages/django/core/handlers/base.py", line 111, in get_response
    response = callback(request, *callback_args, **callback_kwargs)
  File "/usr/lib/python2.6/site-packages/django/views/decorators/cache.py", line 89, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "/usr/lib/python2.6/site-packages/django/views/decorators/vary.py", line 19, in inner_func
    response = func(*args, **kwargs)
  File "/usr/lib/python2.6/site-packages/djblets/webapi/resources.py", line 465, in __call__
    result = view(request, api_format=api_format, *args, **kwargs)
  File "/usr/lib/python2.6/site-packages/djblets/util/decorators.py", line 75, in _call
    f = augmented_func(*args, **kwargs)
  File "/usr/lib/python2.6/site-packages/reviewboard/webapi/decorators.py", line 30, in _check
    return webapi_login_required(view_func)(*args, **kwargs)
  File "/usr/lib/python2.6/site-packages/djblets/webapi/decorators.py", line 88, in _checklogin
    return view_func(*args, **kwargs)
  File "/usr/lib/python2.6/site-packages/djblets/webapi/decorators.py", line 235, in _validate
    return view_func(*args, **new_kwargs)
  File "/usr/lib/python2.6/site-packages/reviewboard/webapi/resources.py", line 192, in get_list
    return self._get_list_impl(request, *args, **kwargs)
  File "/usr/lib/python2.6/site-packages/reviewboard/webapi/resources.py", line 201, in _get_list_impl
    return super(WebAPIResource, self).get_list(request, *args, **kwargs)
  File "/usr/lib/python2.6/site-packages/djblets/webapi/decorators.py", line 62, in _call
    return view_func(*args, **kwargs)
  File "/usr/lib/python2.6/site-packages/djblets/webapi/decorators.py", line 235, in _validate
    return view_func(*args, **new_kwargs)
  File "/usr/lib/python2.6/site-packages/djblets/webapi/resources.py", line 803, in get_list
    **self.build_response_args(request))
  File "/usr/lib/python2.6/site-packages/djblets/webapi/core.py", line 332, in __init__
    for obj in results]
  File "/usr/lib/python2.6/site-packages/djblets/webapi/resources.py", line 801, in <lambda>
    obj, request=request, *args, **kwargs),
  File "/usr/lib/python2.6/site-packages/djblets/webapi/resources.py", line 941, in serialize_object
    value = getattr(obj, field)
  File "/usr/lib/python2.6/site-packages/reviewboard/attachments/models.py", line 41, in _get_thumbnail
    return self.mimetype_handler.get_thumbnail()
  File "/usr/lib/python2.6/site-packages/reviewboard/attachments/mimetypes.py", line 251, in get_thumbnail
    self._generate_thumbnail)
  File "/usr/lib/python2.6/site-packages/djblets/util/misc.py", line 165, in cache_memoize
    data = lookup_callable()
  File "/usr/lib/python2.6/site-packages/reviewboard/attachments/mimetypes.py", line 241, in _generate_thumbnail
    % self._generate_preview_html(data_string))
  File "/usr/lib/python2.6/site-packages/reviewboard/attachments/mimetypes.py", line 223, in _generate_preview_html
    preview_lines[i] = escape(preview_lines[i][:self.TEXT_CROP_NUM_LENGTH])
  File "/usr/lib/python2.6/site-packages/django/utils/functional.py", line 176, in wrapper
    return func(*args, **kwargs)
  File "/usr/lib/python2.6/site-packages/django/utils/html.py", line 36, in escape
    return mark_safe(force_unicode(html).replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;').replace('"', '&quot;').replace("'", '&#39;'))
  File "/usr/lib/python2.6/site-packages/django/utils/encoding.py", line 93, in force_unicode
    raise DjangoUnicodeDecodeError(s, *e.args)
david
#1 david
  • +Component-Attachments
david
#2 david
  • +PendingReview
  • +david
david
#3 david
Fixed in release-1.7.x (64b78f6). Thanks!
  • -PendingReview
    +Fixed