def save(self, *args, **kwargs): if self.pk is None and self.image and verify_svg(self.image.file): self.image.file.seek(0) ET.register_namespace("", self.SVG_NAMESPACE) tree = ET.parse(self.image.file) root = tree.getroot() # strip malicious tags elements_to_strip = [] for tag_name in self.MALICIOUS_SVG_TAGS: elements_to_strip.extend( root.findall('{{{ns}}}{tag}'.format(ns=self.SVG_NAMESPACE, tag=tag_name)) ) for e in elements_to_strip: root.remove(e) # strip malicious attributes for el in tree.iter(): for attrib_name in self.MALICIOUS_SVG_ATTRIBUTES: if attrib_name in el.attrib: del el.attrib[attrib_name] # write out scrubbed svg buf = StringIO.StringIO() tree.write(buf) self.image = InMemoryUploadedFile(buf, 'image', self.image.name, 'image/svg+xml', buf.len, 'utf8') return super(ScrubUploadedSvgImage, self).save(*args, **kwargs)
def handle_png_preview_post_save(sender, instance, **kwargs): if not getattr(settings, 'SVG_HTTP_CONVERSION_ENABLED', False): return # If instance doesn't have an image preview and its image is an SVG, generate PNG image_preview copy. if not instance.image_preview and instance.image and verify_svg(instance.image): generate_png_preview_image.delay(entity_id=instance.id, entity_type=type(instance).__name__)
def generate_png_preview_image(self, entity_id, entity_type): # Get instance of entity we are creating PNG preview for if entity_type == BadgeClass.__name__: entity = BadgeClass.objects.get(id=entity_id) elif entity_type == Issuer.__name__: entity = Issuer.objects.get(id=entity_id) else: return { 'success': False, 'message': 'Unknown entity type.', 'entity_type': entity_type, 'entity_id': entity_id, } # Check if a preview image already exists if entity.image_preview: return { 'success': True, 'message': 'Image preview already exists on entity.', 'entity_type': entity_type, 'entity_id': entity_id, } # Verify that this entity's image is an SVG if not verify_svg(entity.image): return { 'success': False, 'message': 'Image on entity is not an SVG.', 'entity_type': entity_type, 'entity_id': entity_id, } max_square = getattr(settings, 'IMAGE_FIELD_MAX_PX', 400) # Do the conversion call png_bytes = convert_svg_to_png(entity.image.read(), max_square, max_square) if not png_bytes: return { 'success': False, 'message': 'Error converting SVG to PNG', 'entity_type': entity_type, 'entity_id': entity_id, } png_preview_name = '%s.png' % os.path.splitext(entity.image.name)[0] entity.image_preview = InMemoryUploadedFile(png_bytes, None, png_preview_name, 'image/png', png_bytes.tell(), None) entity.save() return { 'success': True, 'message': 'PNG preview created from SVG', 'entity_type': entity_type, 'entity_id': entity_id, }
def _validate_image(self, image): img_name, img_ext = os.path.splitext(image.name) image.name = 'issuer_logo_' + str(uuid.uuid4()) + img_ext image = resize_image(image) app = BadgrApp.objects.get_current(self.context.get('request', None)) if app.is_demo_environment: image = add_watermark(image) if verify_svg(image): image = scrub_svg_image(image) return image
def save(self, *args, **kwargs): if self.image and verify_svg(self.image.file): self.image.file.seek(0) tree = safe_parse(self.image.file) scrubSvgElementTree(tree.getroot()) buf = io.BytesIO() tree.write(buf) self.image = InMemoryUploadedFile(buf, 'image', self.image.name, 'image/svg+xml', buf.tell(), 'utf8') return super(ScrubUploadedSvgImage, self).save(*args, **kwargs)
def __call__(self, image): if image: try: from PIL import Image img = Image.open(image) img.verify() except Exception as e: if not verify_svg(image): raise ValidationError('Invalid image.') else: if img.format != "PNG": raise ValidationError('Invalid PNG')
def test_svg_verify(self): with open(self.get_test_svg_image_path(), 'rb') as svg_badge_image: self.assertTrue(verify_svg(svg_badge_image))