Merge lp:~cjwatson/lazr.restful/no-json-binary into lp:lazr.restful

Proposed by Colin Watson
Status: Merged
Merged at revision: 286
Proposed branch: lp:~cjwatson/lazr.restful/no-json-binary
Merge into: lp:lazr.restful
Diff against target: 79 lines (+19/-12)
3 files modified
NEWS.rst (+4/-0)
src/lazr/restful/docs/webservice-marshallers.rst (+4/-7)
src/lazr/restful/marshallers.py (+11/-5)
To merge this branch: bzr merge lp:~cjwatson/lazr.restful/no-json-binary
Reviewer Review Type Date Requested Status
Ioana Lasc (community) Approve
Review via email: mp+396458@code.launchpad.net

Commit message

Don't attempt to JSON-decode Bytes fields read from a request.

Description of the change

Binary data can't be marshalled via JSON without additional encoding that we don't do, and lazr.restfulclient doesn't JSON-encode binary fields.

To post a comment you must log in.
Revision history for this message
Ioana Lasc (ilasc) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'NEWS.rst'
--- NEWS.rst 2021-01-04 11:24:14 +0000
+++ NEWS.rst 2021-01-18 23:15:39 +0000
@@ -11,6 +11,10 @@
11allowing robust use of binary arguments on both Python 2 and 311allowing robust use of binary arguments on both Python 2 and 3
12(bug 1116954).12(bug 1116954).
1313
14Don't attempt to JSON-decode ``Bytes`` fields read from a request, since
15binary data can't be marshalled via JSON without additional encoding that we
16don't do, and ``lazr.restfulclient`` doesn't JSON-encode binary fields.
17
140.23.0 (2020-09-28)180.23.0 (2020-09-28)
15===================19===================
1620
1721
=== modified file 'src/lazr/restful/docs/webservice-marshallers.rst'
--- src/lazr/restful/docs/webservice-marshallers.rst 2020-09-07 09:30:30 +0000
+++ src/lazr/restful/docs/webservice-marshallers.rst 2021-01-18 23:15:39 +0000
@@ -478,19 +478,16 @@
478 None478 None
479479
480When coming over the request, the value is also converted into a UTF-8480When coming over the request, the value is also converted into a UTF-8
481encoded string.481encoded string, with no JSON decoding.
482482
483 >>> pprint_value(marshaller.marshall_from_request(u"Test"))483 >>> pprint_value(marshaller.marshall_from_request(u"Test"))
484 b'Test'484 b'Test'
485 >>> pprint_value(marshaller.marshall_from_request(u'int\xe9ressant'))485 >>> pprint_value(marshaller.marshall_from_request(u'int\xe9ressant'))
486 b'int\xc3\xa9ressant'486 b'int\xc3\xa9ressant'
487 >>> pprint_value(marshaller.marshall_from_request('1.0'))487 >>> pprint_value(marshaller.marshall_from_request(b'1.0'))
488 b'1.0'488 b'1.0'
489489 >>> pprint_value(marshaller.marshall_from_request(b'"not JSON"'))
490But again, None is returned as is.490 b'"not JSON"'
491
492 >>> print(marshaller.marshall_from_request('null'))
493 None
494491
495Since multipart/form-data can be used to upload data, file-like objects492Since multipart/form-data can be used to upload data, file-like objects
496are read.493are read.
497494
=== modified file 'src/lazr/restful/marshallers.py'
--- src/lazr/restful/marshallers.py 2020-09-01 13:20:54 +0000
+++ src/lazr/restful/marshallers.py 2021-01-18 23:15:39 +0000
@@ -290,21 +290,27 @@
290 return "%s/%s" % (absoluteURL(entry.context, self.request),290 return "%s/%s" % (absoluteURL(entry.context, self.request),
291 self.field.__name__)291 self.field.__name__)
292292
293 def _marshall_from_request(self, value):293 def marshall_from_request(self, value):
294 """See `SimpleFieldMarshaller`.294 """See `IFieldMarshaller`.
295295
296 Reads the data from file-like object, and converts non-strings into296 Reads the data from file-like object, and converts non-strings into
297 one.297 one. This overrides `marshall_from_request` rather than
298 implementing the `_marshall_from_request` hook method because we
299 need to suppress the default JSON-decoding behaviour: binary data
300 can't be marshalled via JSON without additional encoding that we
301 don't do, and lazr.restfulclient doesn't JSON-encode binary fields.
298 """302 """
303 if value is None:
304 return None
299 if safe_hasattr(value, 'seek'):305 if safe_hasattr(value, 'seek'):
300 value.seek(0)306 value.seek(0)
301 value = value.read()307 value = value.read()
302 elif not isinstance(value, (bytes, six.text_type)):308 elif not isinstance(value, (bytes, six.text_type)):
303 value = bytes(value)309 value = str(value).encode('UTF-8')
304 else:310 else:
305 # Leave string conversion to _marshall_from_json_data.311 # Leave string conversion to _marshall_from_json_data.
306 pass312 pass
307 return super(BytesFieldMarshaller, self)._marshall_from_request(value)313 return self._marshall_from_json_data(value)
308314
309 def _marshall_from_json_data(self, value):315 def _marshall_from_json_data(self, value):
310 """See `SimpleFieldMarshaller`.316 """See `SimpleFieldMarshaller`.

Subscribers

People subscribed via source and target branches