diff --git a/Tests/images/xmp_no_prefix.jpg b/Tests/images/xmp_no_prefix.jpg new file mode 100644 index 00000000000..bcd78c7ed23 Binary files /dev/null and b/Tests/images/xmp_no_prefix.jpg differ diff --git a/Tests/images/xmp_padded.jpg b/Tests/images/xmp_padded.jpg new file mode 100644 index 00000000000..9ecfb3efebe Binary files /dev/null and b/Tests/images/xmp_padded.jpg differ diff --git a/Tests/test_file_jpeg.py b/Tests/test_file_jpeg.py index b6213261355..769d7ed969a 100644 --- a/Tests/test_file_jpeg.py +++ b/Tests/test_file_jpeg.py @@ -882,7 +882,10 @@ def read(n=-1): def test_getxmp(self): with Image.open("Tests/images/xmp_test.jpg") as im: if ElementTree is None: - with pytest.warns(UserWarning): + with pytest.warns( + UserWarning, + match="XMP data cannot be read without defusedxml dependency", + ): assert im.getxmp() == {} else: xmp = im.getxmp() @@ -905,6 +908,28 @@ def test_getxmp(self): with Image.open("Tests/images/hopper.jpg") as im: assert im.getxmp() == {} + def test_getxmp_no_prefix(self): + with Image.open("Tests/images/xmp_no_prefix.jpg") as im: + if ElementTree is None: + with pytest.warns( + UserWarning, + match="XMP data cannot be read without defusedxml dependency", + ): + assert im.getxmp() == {} + else: + assert im.getxmp() == {"xmpmeta": {"key": "value"}} + + def test_getxmp_padded(self): + with Image.open("Tests/images/xmp_padded.jpg") as im: + if ElementTree is None: + with pytest.warns( + UserWarning, + match="XMP data cannot be read without defusedxml dependency", + ): + assert im.getxmp() == {} + else: + assert im.getxmp() == {"xmpmeta": None} + @pytest.mark.timeout(timeout=1) def test_eof(self): # Even though this decoder never says that it is finished diff --git a/Tests/test_file_png.py b/Tests/test_file_png.py index eea9f73d866..40fc595ad52 100644 --- a/Tests/test_file_png.py +++ b/Tests/test_file_png.py @@ -665,7 +665,10 @@ def test_plte_length(self, tmp_path): def test_getxmp(self): with Image.open("Tests/images/color_snakes.png") as im: if ElementTree is None: - with pytest.warns(UserWarning): + with pytest.warns( + UserWarning, + match="XMP data cannot be read without defusedxml dependency", + ): assert im.getxmp() == {} else: xmp = im.getxmp() diff --git a/Tests/test_file_tiff.py b/Tests/test_file_tiff.py index f13436ce868..7362c93cac8 100644 --- a/Tests/test_file_tiff.py +++ b/Tests/test_file_tiff.py @@ -734,7 +734,10 @@ def test_discard_icc_profile(self, tmp_path): def test_getxmp(self): with Image.open("Tests/images/lab.tif") as im: if ElementTree is None: - with pytest.warns(UserWarning): + with pytest.warns( + UserWarning, + match="XMP data cannot be read without defusedxml dependency", + ): assert im.getxmp() == {} else: xmp = im.getxmp() diff --git a/Tests/test_file_webp_metadata.py b/Tests/test_file_webp_metadata.py index 037479f9fbb..dd47be8b21b 100644 --- a/Tests/test_file_webp_metadata.py +++ b/Tests/test_file_webp_metadata.py @@ -118,7 +118,10 @@ def test_getxmp(): with Image.open("Tests/images/flower2.webp") as im: if ElementTree is None: - with pytest.warns(UserWarning): + with pytest.warns( + UserWarning, + match="XMP data cannot be read without defusedxml dependency", + ): assert im.getxmp() == {} else: assert ( diff --git a/src/PIL/Image.py b/src/PIL/Image.py index 69c7c506b11..a79666d7afe 100644 --- a/src/PIL/Image.py +++ b/src/PIL/Image.py @@ -1385,7 +1385,7 @@ def getextrema(self): def _getxmp(self, xmp_tags): def get_name(tag): - return tag.split("}")[1] + return re.sub("^{[^}]+}", "", tag) def get_value(element): value = {get_name(k): v for k, v in element.attrib.items()} diff --git a/src/PIL/JpegImagePlugin.py b/src/PIL/JpegImagePlugin.py index 74130854fbc..2bb10e1f695 100644 --- a/src/PIL/JpegImagePlugin.py +++ b/src/PIL/JpegImagePlugin.py @@ -496,7 +496,7 @@ def getxmp(self): for segment, content in self.applist: if segment == "APP1": - marker, xmp_tags = content.rsplit(b"\x00", 1) + marker, xmp_tags = content.split(b"\x00")[:2] if marker == b"http://ns.adobe.com/xap/1.0/": return self._getxmp(xmp_tags) return {}