Replaced xml.etree.ElementTree with defusedxml.ElementTree

This commit is contained in:
Andrew Murray 2021-06-30 11:28:00 +10:00
parent 41b58f4b16
commit d9d811ff21
11 changed files with 68 additions and 36 deletions

View File

@ -24,6 +24,7 @@ sudo apt-get -qq install libfreetype6-dev liblcms2-dev python3-tk\
python3 -m pip install --upgrade pip python3 -m pip install --upgrade pip
PYTHONOPTIMIZE=0 python3 -m pip install cffi PYTHONOPTIMIZE=0 python3 -m pip install cffi
python3 -m pip install coverage python3 -m pip install coverage
python3 -m pip install defusedxml
python3 -m pip install olefile python3 -m pip install olefile
python3 -m pip install -U pytest python3 -m pip install -U pytest
python3 -m pip install -U pytest-cov python3 -m pip install -U pytest-cov

View File

@ -6,6 +6,7 @@ brew install libtiff libjpeg openjpeg libimagequant webp little-cms2 freetype op
PYTHONOPTIMIZE=0 python3 -m pip install cffi PYTHONOPTIMIZE=0 python3 -m pip install cffi
python3 -m pip install coverage python3 -m pip install coverage
python3 -m pip install defusedxml
python3 -m pip install olefile python3 -m pip install olefile
python3 -m pip install -U pytest python3 -m pip install -U pytest
python3 -m pip install -U pytest-cov python3 -m pip install -U pytest-cov

View File

@ -51,8 +51,8 @@ jobs:
- name: Print build system information - name: Print build system information
run: python .github/workflows/system-info.py run: python .github/workflows/system-info.py
- name: python -m pip install wheel pytest pytest-cov pytest-timeout - name: python -m pip install wheel pytest pytest-cov pytest-timeout defusedxml
run: python -m pip install wheel pytest pytest-cov pytest-timeout run: python -m pip install wheel pytest pytest-cov pytest-timeout defusedxml
- name: Install dependencies - name: Install dependencies
id: install id: install

View File

@ -28,6 +28,11 @@ from .helper import (
skip_unless_feature, skip_unless_feature,
) )
try:
import defusedxml.ElementTree as ElementTree
except ImportError:
ElementTree = None
TEST_FILE = "Tests/images/hopper.jpg" TEST_FILE = "Tests/images/hopper.jpg"
@ -825,10 +830,11 @@ class TestFileJpeg:
def test_getxmp(self): def test_getxmp(self):
with Image.open("Tests/images/xmp_test.jpg") as im: with Image.open("Tests/images/xmp_test.jpg") as im:
if ElementTree is None:
assert xmp == {}
else:
xmp = im.getxmp() xmp = im.getxmp()
assert isinstance(xmp, dict)
description = xmp["xmpmeta"]["RDF"]["Description"] description = xmp["xmpmeta"]["RDF"]["Description"]
assert description["DerivedFrom"] == { assert description["DerivedFrom"] == {
"documentID": "8367D410E636EA95B7DE7EBA1C43A412", "documentID": "8367D410E636EA95B7DE7EBA1C43A412",
@ -843,6 +849,7 @@ class TestFileJpeg:
# Attribute # Attribute
assert description["Version"] == "10.4" assert description["Version"] == "10.4"
if ElementTree is not None:
with Image.open("Tests/images/hopper.jpg") as im: with Image.open("Tests/images/hopper.jpg") as im:
assert im.getxmp() == {} assert im.getxmp() == {}

View File

@ -19,6 +19,11 @@ from .helper import (
skip_unless_feature, skip_unless_feature,
) )
try:
import defusedxml.ElementTree as ElementTree
except ImportError:
ElementTree = None
# sample png stream # sample png stream
TEST_PNG_FILE = "Tests/images/hopper.png" TEST_PNG_FILE = "Tests/images/hopper.png"
@ -651,12 +656,13 @@ class TestFilePng:
with Image.open(out) as reloaded: with Image.open(out) as reloaded:
assert len(reloaded.png.im_palette[1]) == 3 assert len(reloaded.png.im_palette[1]) == 3
def test_xmp(self): def test_getxmp(self):
with Image.open("Tests/images/color_snakes.png") as im: with Image.open("Tests/images/color_snakes.png") as im:
if ElementTree is None:
assert im.getxmp() == {}
else:
xmp = im.getxmp() xmp = im.getxmp()
assert isinstance(xmp, dict)
description = xmp["xmpmeta"]["RDF"]["Description"] description = xmp["xmpmeta"]["RDF"]["Description"]
assert description["PixelXDimension"] == "10" assert description["PixelXDimension"] == "10"
assert description["subject"]["Seq"] is None assert description["subject"]["Seq"] is None

View File

@ -16,6 +16,11 @@ from .helper import (
is_win32, is_win32,
) )
try:
import defusedxml.ElementTree as ElementTree
except ImportError:
ElementTree = None
class TestFileTiff: class TestFileTiff:
def test_sanity(self, tmp_path): def test_sanity(self, tmp_path):
@ -643,12 +648,13 @@ class TestFileTiff:
with Image.open(outfile) as reloaded: with Image.open(outfile) as reloaded:
assert "icc_profile" not in reloaded.info assert "icc_profile" not in reloaded.info
def test_xmp(self): def test_getxmp(self):
with Image.open("Tests/images/lab.tif") as im: with Image.open("Tests/images/lab.tif") as im:
if ElementTree is None:
assert im.getxmp() == {}
else:
xmp = im.getxmp() xmp = im.getxmp()
assert isinstance(xmp, dict)
description = xmp["xmpmeta"]["RDF"]["Description"] description = xmp["xmpmeta"]["RDF"]["Description"]
assert description[0]["format"] == "image/tiff" assert description[0]["format"] == "image/tiff"
assert description[3]["BitsPerSample"]["Seq"]["li"] == ["8", "8", "8"] assert description[3]["BitsPerSample"]["Seq"]["li"] == ["8", "8", "8"]

View File

@ -2,6 +2,7 @@
black black
check-manifest check-manifest
coverage coverage
defusedxml
markdown2 markdown2
olefile olefile
packaging packaging

View File

@ -36,10 +36,14 @@ import struct
import sys import sys
import tempfile import tempfile
import warnings import warnings
import xml.etree.ElementTree
from collections.abc import Callable, MutableMapping from collections.abc import Callable, MutableMapping
from pathlib import Path from pathlib import Path
try:
import defusedxml.ElementTree as ElementTree
except ImportError:
ElementTree = None
# VERSION was removed in Pillow 6.0.0. # VERSION was removed in Pillow 6.0.0.
# PILLOW_VERSION is deprecated and will be removed in a future release. # PILLOW_VERSION is deprecated and will be removed in a future release.
# Use __version__ instead. # Use __version__ instead.
@ -1359,7 +1363,10 @@ class Image:
return element.text return element.text
return value return value
root = xml.etree.ElementTree.fromstring(xmp_tags) if ElementTree is None:
return {}
else:
root = ElementTree.fromstring(xmp_tags)
return {get_name(root.tag): get_value(root)} return {get_name(root.tag): get_value(root)}
def getexif(self): def getexif(self):

View File

@ -480,6 +480,7 @@ class JpegImageFile(ImageFile.ImageFile):
def getxmp(self): def getxmp(self):
""" """
Returns a dictionary containing the XMP tags. Returns a dictionary containing the XMP tags.
Requires defusedxml to be installed.
:returns: XMP tags in a dictionary. :returns: XMP tags in a dictionary.
""" """

View File

@ -981,6 +981,7 @@ class PngImageFile(ImageFile.ImageFile):
def getxmp(self): def getxmp(self):
""" """
Returns a dictionary containing the XMP tags. Returns a dictionary containing the XMP tags.
Requires defusedxml to be installed.
:returns: XMP tags in a dictionary. :returns: XMP tags in a dictionary.
""" """
return ( return (

View File

@ -1112,6 +1112,7 @@ class TiffImageFile(ImageFile.ImageFile):
def getxmp(self): def getxmp(self):
""" """
Returns a dictionary containing the XMP tags. Returns a dictionary containing the XMP tags.
Requires defusedxml to be installed.
:returns: XMP tags in a dictionary. :returns: XMP tags in a dictionary.
""" """
return self._getxmp(self.tag_v2[700]) if 700 in self.tag_v2 else {} return self._getxmp(self.tag_v2[700]) if 700 in self.tag_v2 else {}