summaryrefslogtreecommitdiffstats
path: root/ipapython/ipautil.py
diff options
context:
space:
mode:
authorMartin Basti <mbasti@redhat.com>2017-01-12 16:20:43 +0100
committerMartin Basti <mbasti@redhat.com>2017-01-24 13:25:47 +0100
commit18337bf7f7c31a47fe0c7280f82fca043b548bd5 (patch)
tree4878fdfa1a49582d93249bcc8ce157dd9bba1ac2 /ipapython/ipautil.py
parent0eb5a0e0ec2d232d2921ae5f9e8d0885146a5610 (diff)
downloadfreeipa-18337bf7f7c31a47fe0c7280f82fca043b548bd5.tar.gz
freeipa-18337bf7f7c31a47fe0c7280f82fca043b548bd5.tar.xz
freeipa-18337bf7f7c31a47fe0c7280f82fca043b548bd5.zip
py3: decode bytes for json.loads()
In py 3.5 json.loads requires to have string as input, all bytes must be decoded. Note: python 3.6 supports bytes for json.loads() https://fedorahosted.org/freeipa/ticket/4985 Reviewed-By: Christian Heimes <cheimes@redhat.com> Reviewed-By: Jan Cholasta <jcholast@redhat.com>
Diffstat (limited to 'ipapython/ipautil.py')
-rw-r--r--ipapython/ipautil.py50
1 files changed, 50 insertions, 0 deletions
diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
index f2b3d7419..c8f87ef5b 100644
--- a/ipapython/ipautil.py
+++ b/ipapython/ipautil.py
@@ -19,6 +19,7 @@
from __future__ import print_function
+import codecs
import string
import tempfile
import subprocess
@@ -1361,6 +1362,55 @@ def escape_seq(seq, *args):
return tuple(a.replace(seq, u'\\{}'.format(seq)) for a in args)
+def decode_json(data):
+ """Decode JSON bytes to string with proper encoding
+
+ Only for supporting Py 3.5
+
+ Py 3.6 supports bytes as parameter for json.load, we can drop this when
+ there is no need for python 3.5 anymore
+
+ Code from:
+ https://bugs.python.org/file43513/json_detect_encoding_3.patch
+
+ :param data: JSON bytes
+ :return: return JSON string
+ """
+
+ def detect_encoding(b):
+ bstartswith = b.startswith
+ if bstartswith((codecs.BOM_UTF32_BE, codecs.BOM_UTF32_LE)):
+ return 'utf-32'
+ if bstartswith((codecs.BOM_UTF16_BE, codecs.BOM_UTF16_LE)):
+ return 'utf-16'
+ if bstartswith(codecs.BOM_UTF8):
+ return 'utf-8-sig'
+
+ if len(b) >= 4:
+ if not b[0]:
+ # 00 00 -- -- - utf-32-be
+ # 00 XX -- -- - utf-16-be
+ return 'utf-16-be' if b[1] else 'utf-32-be'
+ if not b[1]:
+ # XX 00 00 00 - utf-32-le
+ # XX 00 XX XX - utf-16-le
+ return 'utf-16-le' if b[2] or b[3] else 'utf-32-le'
+ elif len(b) == 2:
+ if not b[0]:
+ # 00 XX - utf-16-be
+ return 'utf-16-be'
+ if not b[1]:
+ # XX 00 - utf-16-le
+ return 'utf-16-le'
+ # default
+ return 'utf-8'
+
+ if isinstance(data, six.text_type):
+ return data
+
+ return data.decode(detect_encoding(data), 'surrogatepass')
+
+
class APIVersion(tuple):
"""API version parser and handler