From 33e2c059eda92453bc15b3465392ddd1bac25a68 Mon Sep 17 00:00:00 2001 From: Ryan Petrello Date: Mon, 17 Aug 2020 14:35:40 -0400 Subject: [PATCH] make event stdout encoding more resilient to UTF-16 surrogate pairs see: https://en.wikipedia.org/wiki/Universal_Character_Set_characters#Surrogates --- CHANGELOG.md | 1 + awx/api/renderers.py | 18 ++++++++++++++++++ awx/settings/defaults.py | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b316f49d55..54573a057f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ This is a list of high-level changes for each release of AWX. A full list of com - Upgraded git-python to fix a bug that caused workflows to sometimes fail - https://github.com/ansible/awx/issues/6119 - Fixed a bug in the AWX CLI that prevented Workflow nodes from importing properly - https://github.com/ansible/awx/issues/7793 - Fixed a bug in the awx.awx collection release process that templated the wrong version - https://github.com/ansible/awx/issues/7870 +- Fixed a bug that caused errors rendering stdout that contained UTF-16 surrogate pairs - https://github.com/ansible/awx/pull/7918 ## 14.0.0 (Aug 6, 2020) - As part of our commitment to inclusivity in open source, we recently took some time to audit AWX's source code and user interface and replace certain terminology with more inclusive language. Strictly speaking, this isn't a bug or a feature, but we think it's important and worth calling attention to: diff --git a/awx/api/renderers.py b/awx/api/renderers.py index bd4136a76a..92d59e2c7b 100644 --- a/awx/api/renderers.py +++ b/awx/api/renderers.py @@ -7,6 +7,24 @@ from prometheus_client.parser import text_string_to_metric_families # Django REST Framework from rest_framework import renderers from rest_framework.request import override_method +from rest_framework.utils import encoders + + +class SurrogateEncoder(encoders.JSONEncoder): + + def encode(self, obj): + ret = super(SurrogateEncoder, self).encode(obj) + try: + ret.encode() + except UnicodeEncodeError as e: + if 'surrogates not allowed' in e.reason: + ret = ret.encode('utf-8', 'replace').decode() + return ret + + +class DefaultJSONRenderer(renderers.JSONRenderer): + + encoder_class = SurrogateEncoder class BrowsableAPIRenderer(renderers.BrowsableAPIRenderer): diff --git a/awx/settings/defaults.py b/awx/settings/defaults.py index fe7c8c0ba3..355d247f62 100644 --- a/awx/settings/defaults.py +++ b/awx/settings/defaults.py @@ -310,7 +310,7 @@ REST_FRAMEWORK = { 'awx.api.parsers.JSONParser', ), 'DEFAULT_RENDERER_CLASSES': ( - 'rest_framework.renderers.JSONRenderer', + 'awx.api.renderers.DefaultJSONRenderer', 'awx.api.renderers.BrowsableAPIRenderer', ), 'DEFAULT_METADATA_CLASS': 'awx.api.metadata.Metadata',