Skip to content

Commit a62d365

Browse files
committed
fix: invalid field breaks compression
- a new field content for the adjustmentSimpleDataEnc field `johuAQAAAAAKXQAA` is breaking the decompression - adds a failsafe function to prevent any further problems while decompressing the field
1 parent 1b384da commit a62d365

2 files changed

Lines changed: 44 additions & 7 deletions

File tree

src/icloudpd/xmp_sidecar.py

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,11 @@ def build_metadata(asset_record: dict[str, Any]) -> XMPMetadata:
104104
is_not_bplist = not_(startswith("YnBsaXN0MD"))
105105

106106
if is_not_crdt(data_value) and is_not_bplist(data_value): # not "crdt" and not "bplist00"
107-
adjustments = json.loads(
108-
zlib.decompress(
109-
base64.b64decode(asset_record["fields"]["adjustmentSimpleDataEnc"]["value"]),
110-
-zlib.MAX_WBITS,
111-
)
107+
adjustments = try_decompress_json(data_value)
108+
109+
orientation = (
110+
adjustments.get("metadata", {}).get("orientation") if adjustments else None
112111
)
113-
if "metadata" in adjustments and "orientation" in adjustments["metadata"]:
114-
orientation = adjustments["metadata"]["orientation"]
115112

116113
make, digital_source_type = None, None
117114
if (
@@ -190,6 +187,25 @@ def build_metadata(asset_record: dict[str, Any]) -> XMPMetadata:
190187
)
191188

192189

190+
def try_decompress_json(data_value: str) -> dict[str, Any] | None:
191+
"""
192+
Attempts to decode base64-encoded, zlib-compressed JSON data.
193+
194+
Args:
195+
data_value: Base64-encoded string
196+
197+
Returns:
198+
Decoded JSON dictionary or None on error
199+
"""
200+
try:
201+
decoded = base64.b64decode(data_value)
202+
decompressed = zlib.decompress(decoded, -zlib.MAX_WBITS)
203+
data: dict[str, Any] = json.loads(decompressed)
204+
return data
205+
except (zlib.error, json.JSONDecodeError, Exception):
206+
return None
207+
208+
193209
def generate_xml(metadata: XMPMetadata) -> ElementTree.Element:
194210
# Create the root element
195211
xml_doc = ElementTree.Element(

tests/test_xmp_sidecar.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,27 @@ def test_build_metadata(self) -> None:
7474
metadata = build_metadata(assetRecordStub)
7575
assert metadata.Orientation is None
7676

77+
# - a zlib compressed JSON without "metadata" key (lines 101-113 coverage)
78+
assetRecordStub["fields"]["adjustmentSimpleDataEnc"]["value"] = (
79+
"q1Yqzs9N9S/JSC3yTq1UslJQKkvMKU1VqgUA"
80+
)
81+
metadata = build_metadata(assetRecordStub)
82+
assert metadata.Orientation is None
83+
84+
# - a zlib compressed JSON with "metadata" key but no "orientation" key (lines 101-113 coverage)
85+
assetRecordStub["fields"]["adjustmentSimpleDataEnc"]["value"] = (
86+
"q1bKTS1JTEksSVSyUqhWKs7PTfUvyUgt8k6tBAoolSXmlKYq1dYCAA=="
87+
)
88+
metadata = build_metadata(assetRecordStub)
89+
assert metadata.Orientation is None
90+
91+
# - invalid data that fails decompression (lines 101-113 coverage)
92+
assetRecordStub["fields"]["adjustmentSimpleDataEnc"]["value"] = (
93+
"aW52YWxpZCBkYXRhIHRoYXQgd2lsbCBmYWlsIGRlY29tcHJlc3Npb24="
94+
)
95+
metadata = build_metadata(assetRecordStub)
96+
assert metadata.Orientation is None
97+
7798
# Test Screenshot Tagging
7899
assetRecordStub["fields"]["assetSubtypeV2"]["value"] = 3
79100
metadata = build_metadata(assetRecordStub)

0 commit comments

Comments
 (0)