3513: Unicode characters in source file prevent review requests from being posted correctly (or at all)
- Fixed
- Review Board
| Ray.L.******@gmai***** (Google Code) (Is this you? Claim this profile.) | |
| Aug. 3, 2014 |
What version are you running?
2.0.2
What's the URL of the page containing the problem?
https://hopper.rose.hp.com/r/new/ (Page behind firewall)
What steps will reproduce the problem?
1. Find a file with at least one non-ASCII character (e.g. single quote ’ instead of ' in a code comment).
2. Check it in into the repository.
3. Try to post a review request for the file in question.
What is the expected output? What do you see instead?
If using the browser, then instead of creating a new review request, it gets stuck with the loading animation.
If using rbt post, then a new review requests is created, but it always fails to upload the diff.
What operating system are you using? What browser?
Confirmed on Ubuntu 14.04 GNU/Linux, Firefox 31.0, Chromium 34.0, Windows 7 with the same browsers and the rbt post command in RHEL 6.5.
Please provide any additional information below.
The issue is related to the *content* of the file and how RB reacts to non-ASCII characters in it. The workaround I found was to:
1. Remove the non-ASCII characters from the files.
2. Check in the files into the repository *without* posting any review requests.
3. Now that the non-ASCII chars have been removed, review requests can be successfully posted.
This was found when trying to post a review request for a file that had been reviewed and checked in 1+ year(s) ago in an older version of RB (*likely* on the 1.6.xx series) without incident.
So it was particularly time-consuming to track down the problem because RB will encounter the issue whenever it tries to read/process the remote content in the repository host. This makes it non-obvious because this happens even if the diff you're trying to upload is 100% ASCII, but as mentioned above, it fails when RB tries to process what's already checked in, which is not immediately clear to user.
While reviewing the rbt post source code, I did not find any explicit statement where the decode('ascii') method is invoked on a string or character --at least not explicitly.
I've attached a simple Python script I wrote while I was trying to reproduce the error message displayed by rbt post, which is how I was able to better confirm what I suspected. It tries to decode('ascii') each character in a file.
Error displayed on Firefox's JavaScript console after pressing 'OK' to create the request with selected diff and base directory:
SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
Debug output and stack trace of rbt post command on RHEL system:
$ rbt post --diff-filename=$HOME/current.diff -d
>>> RBTools 0.6.2
>>> Python 2.6.6 (r266:84292, Nov 21 2013, 10:50:32)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-4)]
>>> Running on Linux-2.6.32-431.5.1.el6.x86_64-x86_64-with-redhat-6.5-Santiago
>>> Home = /home/ray
>>> Current directory = /home/ray/cti/windjammer/common/lib/Connector
>>> Checking for a Subversion repository...
>>> Running: svn info --non-interactive
>>> Running: diff --version
>>> repository info: Path: https://csvnhou-pro.houston.hp.com:18490/svn/cfe-cti, Base path: /trunk/cti/windjammer/common/lib/Connector, Supports changesets: False
>>> Making HTTP GET request to http://hopper.rose.hp.com/api/
>>> Making HTTP GET request to https://hopper.rose.hp.com/api/review-requests/
>>> Making HTTP POST request to https://hopper.rose.hp.com/api/review-requests/
>>> Making HTTP GET request to https://hopper.rose.hp.com/api/review-requests/8600/diffs/
>>> Making HTTP POST request to https://hopper.rose.hp.com/api/review-requests/8600/diffs/
>>> Got API Error 105 (HTTP code 400): One or more fields had errors
>>> Error data: {u'fields': {u'path': [u"'ascii' codec can't decode byte 0xe2 in position 2154: ordinal not in range(128)"]}, u'stat': u'fail', u'err': {u'msg': u'One or more fields had errors', u'code': 105}}
Traceback (most recent call last):
File "/usr/bin/rbt", line 9, in <module>
load_entry_point('RBTools==0.6.2', 'console_scripts', 'rbt')()
File "/usr/lib/python2.6/site-packages/RBTools-0.6.2-py2.6.egg/rbtools/commands/main.py", line 134, in main
command.run_from_argv([RB_MAIN, command_name] + args)
File "/usr/lib/python2.6/site-packages/RBTools-0.6.2-py2.6.egg/rbtools/commands/__init__.py", line 416, in run_from_argv
exit_code = self.main(*args) or 0
File "/usr/lib/python2.6/site-packages/RBTools-0.6.2-py2.6.egg/rbtools/commands/post.py", line 784, in main
submit_as=self.options.submit_as)
File "/usr/lib/python2.6/site-packages/RBTools-0.6.2-py2.6.egg/rbtools/commands/post.py", line 551, in post_request
raise CommandError(u'\n'.join(error_msg))
rbtools.commands.CommandError: Error uploading diff
One or more fields had errors (HTTP 400, API Error 105)
path: 'ascii' codec can't decode byte 0xe2 in position 2154: ordinal not in range(128)
Your review request still exists, but the diff is not attached.
https://hopper.rose.hp.com/r/8600/
I'm not sure I'm able to. I'm not the sys admin for the server and persuading the admin to update the one and only live production environment is unlikely. Perhaps you could try it with the steps I provided above?
Can you confirm which version control system you're using? That will help me identify whether fixes subsequent to 2.0.2 include this one or not.
The VCS is Subversion.
Just to verify, but was this actually confirmed as fixed, or was this simply assumed to be fixed on the basis that there are "several fixes for SVN and unicode"? If this was tested and verified as fixed, then I'll pass along that info. Otherwise, I think this issue should be re-opened and tested first.
There are a hundred moving parts in this particular code, and as part of the aforementioned fixes, we've done a lot of testing. It's theoretically possible that you're encountering something that we haven't seen, in which case, our testing probably wouldn't help. One thing that would help is some debugging on your end to get the traceback from the server side (there's a UnicodeDecodeError occurring, which then gets translated into an error code on the API).
I've included the stack trace from the server's log file. Please see it below:
--------------------------------
2014-07-29 23:26:41,524 - ERROR - - Exception thrown for user <email-removed> at https://hopper.rose.hp.com/api/validation/diffs/
'ascii' codec can't decode byte 0xe2 in position 2154: ordinal not in range(128)
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/Django-1.6.5-py2.7.egg/django/core/handlers/base.py", line 112, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python2.7/dist-packages/Django-1.6.5-py2.7.egg/django/views/decorators/cache.py", line 52, in _wrapped_view_func
response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/Django-1.6.5-py2.7.egg/django/views/decorators/vary.py", line 19, in inner_func
response = func(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/Djblets-0.8.5-py2.7.egg/djblets/webapi/resources.py", line 493, in __call__
result = view(request, api_format=api_format, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/Djblets-0.8.5-py2.7.egg/djblets/webapi/resources.py", line 726, in post
return self.create(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/Djblets-0.8.5-py2.7.egg/djblets/webapi/decorators.py", line 117, in _call
return view_func(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/ReviewBoard-2.0.2-py2.7.egg/reviewboard/webapi/decorators.py", line 110, in _check
return view_func(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/Djblets-0.8.5-py2.7.egg/djblets/webapi/decorators.py", line 117, in _call
return view_func(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/Djblets-0.8.5-py2.7.egg/djblets/webapi/decorators.py", line 138, in _checklogin
return view_func(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/Djblets-0.8.5-py2.7.egg/djblets/webapi/decorators.py", line 117, in _call
return view_func(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/Djblets-0.8.5-py2.7.egg/djblets/webapi/decorators.py", line 117, in _call
return view_func(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/Djblets-0.8.5-py2.7.egg/djblets/webapi/decorators.py", line 287, in _validate
return view_func(*args, **new_kwargs)
File "/usr/local/lib/python2.7/dist-packages/ReviewBoard-2.0.2-py2.7.egg/reviewboard/webapi/resources/validate_diff.py", line 135, in create
save=False)
File "/usr/local/lib/python2.7/dist-packages/ReviewBoard-2.0.2-py2.7.egg/reviewboard/diffviewer/managers.py", line 156, in create_from_upload
save=save)
File "/usr/local/lib/python2.7/dist-packages/ReviewBoard-2.0.2-py2.7.egg/reviewboard/diffviewer/managers.py", line 182, in create_from_data
check_existence=(not parent_diff_file_contents)))
File "/usr/local/lib/python2.7/dist-packages/ReviewBoard-2.0.2-py2.7.egg/reviewboard/diffviewer/managers.py", line 300, in _process_files
request=request))):
File "/usr/local/lib/python2.7/dist-packages/ReviewBoard-2.0.2-py2.7.egg/reviewboard/scmtools/models.py", line 239, in get_file_exists
base_commit_id, request)
File "/usr/local/lib/python2.7/dist-packages/ReviewBoard-2.0.2-py2.7.egg/reviewboard/scmtools/models.py", line 434, in _get_file_exists_uncached
exists = self.get_scmtool().file_exists(path, revision)
File "/usr/local/lib/python2.7/dist-packages/ReviewBoard-2.0.2-py2.7.egg/reviewboard/scmtools/core.py", line 156, in file_exists
self.get_file(path, revision)
File "/usr/local/lib/python2.7/dist-packages/ReviewBoard-2.0.2-py2.7.egg/reviewboard/scmtools/svn/__init__.py", line 117, in get_file
return self.client.get_file(path, revision)
File "/usr/local/lib/python2.7/dist-packages/ReviewBoard-2.0.2-py2.7.egg/reviewboard/scmtools/svn/pysvn.py", line 106, in get_file
return self._do_on_path(self._get_file_data, path, revision)
File "/usr/local/lib/python2.7/dist-packages/ReviewBoard-2.0.2-py2.7.egg/reviewboard/scmtools/svn/pysvn.py", line 72, in _do_on_path
return cb(normpath, normrev)
File "/usr/local/lib/python2.7/dist-packages/ReviewBoard-2.0.2-py2.7.egg/reviewboard/scmtools/svn/pysvn.py", line 100, in _get_file_data
data = self.collapse_keywords(data, keywords[normpath])
File "/usr/local/lib/python2.7/dist-packages/ReviewBoard-2.0.2-py2.7.egg/reviewboard/scmtools/svn/base.py", line 118, in collapse_keywords
repl, data)
File "/usr/lib/python2.7/re.py", line 151, in sub
return _compile(pattern, flags).sub(repl, string, count)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 2154: ordinal not in range(128)
Please let me know if this is not what you meant. As for the API Error, it's on the original post:
One or more fields had errors (HTTP 400, API Error 105)
path: 'ascii' codec can't decode byte 0xe2 in position 2154: ordinal not in range(128)
Your review request still exists, but the diff is not attached.
Thanks for the follow up :) I'll pass this info along.