<commit_before>import boto
import copy
import json
import logging

from json import JSONEncoder
from json import JSONDecoder
from boto.ec2 import EC2Connection
from boto.ec2.ec2object import EC2Object
from boto.regioninfo import RegionInfo
from boto.ec2.blockdevicemapping import BlockDeviceType
from boto.ec2.image import ImageAttribute
from boto.ec2.instance import ConsoleOutput
from boto.ec2.instance import Group
from boto.ec2.securitygroup import GroupOrCIDR
from boto.ec2.securitygroup import IPPermissions
from boto.ec2.volume import AttachmentSet
from .response import ClcError
from .response import Response
from esapi.codecs.html_entity import HTMLEntityCodec

class BotoJsonEncoder(JSONEncoder):
    # use this codec directly vs using factory which messes with logging config
    codec = HTMLEntityCodec()
    IMMUNE_HTML = ',.-_ '
    IMMUNE_HTMLATTR = ',.-_'

    # these are system generated values that aren't a risk for XSS attacks
    FIELD_WHITELIST = [
        'id',
        'image_id',
        'kernel_id',
        'ramdisk_id',
        'reservation_id',
        'owner_id',
        'root_device_type',
        'state',
        'state_reason',
        'state_code',
        'monitored',
        'platform',
        'volume_id',
        'snapshot_id',
        'launch_time',
        'attach_time',
        'create_time',
        'start_time',
        'instance_type',
        'zone',
        'progress',
        'ip_protocol',
        'fingerprint',
    ];
    
    def __sanitize_and_copy__(self, dict):
        try:
            ret = copy.copy(dict)
            for key in ret.keys():
                if key in self.FIELD_WHITELIST:
                    continue
                if isinstance(ret[key], basestring):
                    ret[key] = self.codec.encode(self.IMMUNE_HTML, ret[key])
            return ret
        except Exception, e:
            logging.error(e)

    def default(self, obj):
        if issubclass(obj.__class__, EC2Object):
            values = self.__sanitize_and_copy__(obj.__dict__)
            values['__obj_name__'] = obj.__class__.__name__
            return (values)
        elif isinstance(obj, RegionInfo):
            values = self.__sanitize_and_copy__(obj.__dict__)
            values['__obj_name__'] = 'RegionInfo'
            return (values)
        elif isinstance(obj, ClcError):
            return obj.__dict__
        elif isinstance(obj, Response):
            return obj.__dict__
        elif isinstance(obj, EC2Connection):
            return []
        elif isinstance(obj, Group):
            values = self.__sanitize_and_copy__(obj.__dict__)
            values['__obj_name__'] = 'Group'
            return (values)
        elif isinstance(obj, ConsoleOutput):
            values = self.__sanitize_and_copy__(obj.__dict__)
            values['__obj_name__'] = 'ConsoleOutput'
            return (values)
        elif isinstance(obj, ImageAttribute):
            values = self.__sanitize_and_copy__(obj.__dict__)
            values['__obj_name__'] = 'ImageAttribute'
            return (values)
        elif isinstance(obj, AttachmentSet):
            values = self.__sanitize_and_copy__(obj.__dict__)
            values['__obj_name__'] = 'AttachmentSet'
            return (values)
        elif isinstance(obj, IPPermissions):
            values = self.__sanitize_and_copy__(obj.__dict__)
            # this is because I found a "parent" property set to self - dak
            values['parent'] = None
            values['__obj_name__'] = 'IPPermissions'
            return (values)
        elif isinstance(obj, GroupOrCIDR):
            values = self.__sanitize_and_copy__(obj.__dict__)
            values['__obj_name__'] = 'GroupOrCIDR'
            return (values)
        elif isinstance(obj, BlockDeviceType):
            values = self.__sanitize_and_copy__(obj.__dict__)
            values['connection'] = None
            values['__obj_name__'] = 'BlockDeviceType'
            return (values)
        return super(BotoJsonEncoder, self).default(obj)

class BotoJsonDecoder(JSONDecoder):
    # if we need to map classes to specific boto objects, we'd do that here
    # it seems like we can get away with generic objects for now.
    # regioninfo isn't used, so we just show this for an example
    def default(self, obj):
        if obj['__obj_name__'] == 'RegionInfo':
            ret = RegionInfo()
<commit_msg>EUCA-3686 addressed by escaping error response.<commit_after>import boto
import copy
import json
import logging

from json import JSONEncoder
from json import JSONDecoder
from boto.ec2 import EC2Connection
from boto.ec2.ec2object import EC2Object
from boto.regioninfo import RegionInfo
from boto.ec2.blockdevicemapping import BlockDeviceType
from boto.ec2.image import ImageAttribute
from boto.ec2.instance import ConsoleOutput
from boto.ec2.instance import Group
from boto.ec2.securitygroup import GroupOrCIDR
from boto.ec2.securitygroup import IPPermissions
from boto.ec2.volume import AttachmentSet
from .response import ClcError
from .response import Response
from esapi.codecs.html_entity import HTMLEntityCodec

class BotoJsonEncoder(JSONEncoder):
    # use this codec directly vs using factory which messes with logging config
    codec = HTMLEntityCodec()
    IMMUNE_HTML = ',.-_ '
    IMMUNE_HTMLATTR = ',.-_'

    # these are system generated values that aren't a risk for XSS attacks
    FIELD_WHITELIST = [
        'id',
        'image_id',
        'kernel_id',
        'ramdisk_id',
        'reservation_id',
        'owner_id',
        'root_device_type',
        'state',
        'state_reason',
        'state_code',
        'monitored',
        'platform',
        'volume_id',
        'snapshot_id',
        'launch_time',
        'attach_time',
        'create_time',
        'start_time',
        'instance_type',
        'zone',
        'progress',
        'ip_protocol',
        'fingerprint',
    ];
    
    def __sanitize_and_copy__(self, dict):
        try:
            ret = copy.copy(dict)
            for key in ret.keys():
                if key in self.FIELD_WHITELIST:
                    continue
                if isinstance(ret[key], basestring):
                    ret[key] = self.codec.encode(self.IMMUNE_HTML, ret[key])
            return ret
        except Exception, e:
            logging.error(e)

    def default(self, obj):
        if issubclass(obj.__class__, EC2Object):
            values = self.__sanitize_and_copy__(obj.__dict__)
            values['__obj_name__'] = obj.__class__.__name__
            return (values)
        elif isinstance(obj, RegionInfo):
            values = self.__sanitize_and_copy__(obj.__dict__)
            values['__obj_name__'] = 'RegionInfo'
            return (values)
        elif isinstance(obj, ClcError):
            return self.__sanitize_and_copy__(obj.__dict__)
        elif isinstance(obj, Response):
            return obj.__dict__
        elif isinstance(obj, EC2Connection):
            return []
        elif isinstance(obj, Group):
            values = self.__sanitize_and_copy__(obj.__dict__)
            values['__obj_name__'] = 'Group'
            return (values)
        elif isinstance(obj, ConsoleOutput):
            values = self.__sanitize_and_copy__(obj.__dict__)
            values['__obj_name__'] = 'ConsoleOutput'
            return (values)
        elif isinstance(obj, ImageAttribute):
            values = self.__sanitize_and_copy__(obj.__dict__)
            values['__obj_name__'] = 'ImageAttribute'
            return (values)
        elif isinstance(obj, AttachmentSet):
            values = self.__sanitize_and_copy__(obj.__dict__)
            values['__obj_name__'] = 'AttachmentSet'
            return (values)
        elif isinstance(obj, IPPermissions):
            values = self.__sanitize_and_copy__(obj.__dict__)
            # this is because I found a "parent" property set to self - dak
            values['parent'] = None
            values['__obj_name__'] = 'IPPermissions'
            return (values)
        elif isinstance(obj, GroupOrCIDR):
            values = self.__sanitize_and_copy__(obj.__dict__)
            values['__obj_name__'] = 'GroupOrCIDR'
            return (values)
        elif isinstance(obj, BlockDeviceType):
            values = self.__sanitize_and_copy__(obj.__dict__)
            values['connection'] = None
            values['__obj_name__'] = 'BlockDeviceType'
            return (values)
        return super(BotoJsonEncoder, self).default(obj)

class BotoJsonDecoder(JSONDecoder):
    # if we need to map classes to specific boto objects, we'd do that here
    # it seems like we can get away with generic objects for now.
    # regioninfo isn't used, so we just show this for an example
    def default(self, obj):
        if obj['__obj_name__'] == 'RegionInfo':
            ret = RegionInfo()

{'fraction_non_alphanumeric': 0.08787604614340647, 'fraction_numerical': 0.0036190907034607555, 'mean_word_length': 2.3508904888215234, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3679634', 'n_tokens_mistral': 2471, 'n_tokens_neox': 2487, 'n_words': 631}