diff --git a/pyproject.toml b/pyproject.toml index a5c45630f..2dafddbb9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,6 +24,7 @@ dependencies = [ "qtpy>=2.4.3,<2.5.0", "lark>=1.2.2,<1.3.0", "docutils>=0.21", + "bleach>=6.2.0", ] description = "Python interface to Ansys Dynamic Reporting" readme = "README.rst" diff --git a/src/ansys/dynamicreporting/core/utils/report_objects.py b/src/ansys/dynamicreporting/core/utils/report_objects.py index a68fa5ebb..b1d9f83be 100755 --- a/src/ansys/dynamicreporting/core/utils/report_objects.py +++ b/src/ansys/dynamicreporting/core/utils/report_objects.py @@ -16,6 +16,7 @@ import uuid import weakref +import bleach import dateutil import dateutil.parser import pytz @@ -1080,7 +1081,8 @@ def set_payload_none(self): self.type = ItemREST.type_none self._payloaddata = "" - def validate_string(self, input_string, description): + @staticmethod + def validate_string(input_string, description, sanitize_html=False): if not isinstance(input_string, str): raise TypeError("Payload must be a string.") @@ -1092,6 +1094,12 @@ def validate_string(self, input_string, description): except UnicodeEncodeError: raise ValueError(f"Payload {description} must be a valid UTF-8 string.") + if os.getenv("ADR_VALIDATION_BETAFLAG_ANSYS") == "1": + if sanitize_html: + cleaned_string = bleach.clean(input_string, strip=True) + if cleaned_string != input_string: + raise ValueError(f"Payload {description} contains HTML content.") + def set_payload_string(self, s): self.validate_string(s, "string") self.type = ItemREST.type_str @@ -1125,6 +1133,8 @@ def validate_tree_value(value): else: if type_ not in [float, int, datetime.datetime, str, bool, uuid.UUID, type(None)]: raise ValueError(f"{str(type_)} is not a valid Tree payload 'value' type") + if isinstance(value, str): + ItemREST.validate_string(value, "Tree node value", sanitize_html=True) @staticmethod def validate_tree(t): @@ -1233,6 +1243,12 @@ def validate_and_clean_table(self, value): if kind not in ("S", "f"): raise ValueError("Table array must be a bytes or float type.") + if kind == "S": # Check if the array contains strings + for i in range(array.shape[0]): + for j in range(array.shape[1]): + if isinstance(array[i, j], str): + self.validate_string(array[i, j], "Table array element", sanitize_html=True) + shape = array.shape size = array.size @@ -1256,7 +1272,6 @@ def validate_and_clean_table(self, value): array.shape = shape elif len(shape) != 2: raise ValueError("Table array must be 2D.") - if rowlbls and not isinstance(rowlbls, (str, list)): raise TypeError("Row labels must be a string or a list.") if collbls and not isinstance(collbls, (str, list)):