mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-11-10 19:56:47 +03:00
Remove zero-byte end padding when parsing any XMP data
This commit is contained in:
parent
a90a9d5ea5
commit
fd3f6c1a92
|
@ -8,6 +8,7 @@ import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import warnings
|
import warnings
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from types import ModuleType
|
||||||
from typing import IO, Any
|
from typing import IO, Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -35,6 +36,12 @@ from .helper import (
|
||||||
skip_unless_feature,
|
skip_unless_feature,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ElementTree: ModuleType | None
|
||||||
|
try:
|
||||||
|
from defusedxml import ElementTree
|
||||||
|
except ImportError:
|
||||||
|
ElementTree = None
|
||||||
|
|
||||||
|
|
||||||
# Deprecation helper
|
# Deprecation helper
|
||||||
def helper_image_new(mode: str, size: tuple[int, int]) -> Image.Image:
|
def helper_image_new(mode: str, size: tuple[int, int]) -> Image.Image:
|
||||||
|
@ -921,6 +928,21 @@ class TestImage:
|
||||||
with Image.open("Tests/images/hopper.gif") as im:
|
with Image.open("Tests/images/hopper.gif") as im:
|
||||||
assert im.getxmp() == {}
|
assert im.getxmp() == {}
|
||||||
|
|
||||||
|
def test_getxmp_padded(self) -> None:
|
||||||
|
im = Image.new("RGB", (1, 1))
|
||||||
|
im.info["xmp"] = (
|
||||||
|
b'<?xpacket begin="\xef\xbb\xbf" id="W5M0MpCehiHzreSzNTczkc9d"?>\n'
|
||||||
|
b'<x:xmpmeta xmlns:x="adobe:ns:meta/" />\n<?xpacket end="w"?>\x00\x00'
|
||||||
|
)
|
||||||
|
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.parametrize("size", ((1, 0), (0, 1), (0, 0)))
|
@pytest.mark.parametrize("size", ((1, 0), (0, 1), (0, 0)))
|
||||||
def test_zero_tobytes(self, size: tuple[int, int]) -> None:
|
def test_zero_tobytes(self, size: tuple[int, int]) -> None:
|
||||||
im = Image.new("RGB", size)
|
im = Image.new("RGB", size)
|
||||||
|
|
|
@ -1511,7 +1511,7 @@ class Image:
|
||||||
return {}
|
return {}
|
||||||
if "xmp" not in self.info:
|
if "xmp" not in self.info:
|
||||||
return {}
|
return {}
|
||||||
root = ElementTree.fromstring(self.info["xmp"])
|
root = ElementTree.fromstring(self.info["xmp"].rstrip(b"\x00"))
|
||||||
return {get_name(root.tag): get_value(root)}
|
return {get_name(root.tag): get_value(root)}
|
||||||
|
|
||||||
def getexif(self) -> Exif:
|
def getexif(self) -> Exif:
|
||||||
|
|
|
@ -96,7 +96,7 @@ def APP(self, marker):
|
||||||
self.info["exif"] = s
|
self.info["exif"] = s
|
||||||
self._exif_offset = self.fp.tell() - n + 6
|
self._exif_offset = self.fp.tell() - n + 6
|
||||||
elif marker == 0xFFE1 and s[:29] == b"http://ns.adobe.com/xap/1.0/\x00":
|
elif marker == 0xFFE1 and s[:29] == b"http://ns.adobe.com/xap/1.0/\x00":
|
||||||
self.info["xmp"] = s.split(b"\x00")[1]
|
self.info["xmp"] = s.split(b"\x00", 1)[1]
|
||||||
elif marker == 0xFFE2 and s[:5] == b"FPXR\0":
|
elif marker == 0xFFE2 and s[:5] == b"FPXR\0":
|
||||||
# extract FlashPix information (incomplete)
|
# extract FlashPix information (incomplete)
|
||||||
self.info["flashpix"] = s # FIXME: value will change
|
self.info["flashpix"] = s # FIXME: value will change
|
||||||
|
|
Loading…
Reference in New Issue
Block a user