Pickle non-str objects to survive connection return (#63110)

* Fail more helpfully when data is not str

* Pickle arbitrary objects to return from connection
This commit is contained in:
Nathaniel Case 2019-10-14 11:34:37 -04:00 committed by GitHub
parent 11dc3a972f
commit ffe8f45ddd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 14 additions and 3 deletions

View file

@ -155,7 +155,7 @@ class Connection(object):
try:
response = json.loads(out)
except ValueError:
params = list(args) + ['{0}={1}'.format(k, v) for k, v in iteritems(kwargs)]
params = [repr(arg) for arg in args] + ['{0}={1!r}'.format(k, v) for k, v in iteritems(kwargs)]
params = ', '.join(params)
raise ConnectionError(
"Unable to decode JSON from response to {0}({1}). Received '{2}'.".format(name, params, out)
@ -163,6 +163,8 @@ class Connection(object):
if response['id'] != reqid:
raise ConnectionError('invalid json-rpc id received')
if "result_type" in response:
response["result"] = cPickle.loads(to_bytes(response["result"]))
return response

View file

@ -9,7 +9,8 @@ import traceback
from ansible.module_utils._text import to_text
from ansible.module_utils.connection import ConnectionError
from ansible.module_utils.six import binary_type
from ansible.module_utils.six import binary_type, text_type
from ansible.module_utils.six.moves import cPickle
from ansible.utils.display import Display
display = Display()
@ -60,7 +61,12 @@ class JsonRpcServer(object):
else:
response = self.response(result)
response = json.dumps(response)
try:
response = json.dumps(response)
except Exception as exc:
display.vvv(traceback.format_exc())
error = self.internal_error(data=to_text(exc, errors='surrogate_then_replace'))
response = json.dumps(error)
delattr(self, '_identifier')
@ -76,6 +82,9 @@ class JsonRpcServer(object):
response = self.header()
if isinstance(result, binary_type):
result = to_text(result)
if not isinstance(result, text_type):
response["result_type"] = "pickle"
result = to_text(cPickle.dumps(result, protocol=0))
response['result'] = result
return response