From acf7e11114eaabdd243950128eebe9538231c2b2 Mon Sep 17 00:00:00 2001
From: QiuSW <105186638@qq.com>
Date: Tue, 4 Aug 2026 14:04:49 +0800
Subject: [PATCH] fix(client): bind T-103 XML coordinates
---
.../device/sku_evidence_sanitizer.py | 4 +-
.../device/test_sku_evidence_sanitizer.py | 50 +++++++++----------
2 files changed, 27 insertions(+), 27 deletions(-)
diff --git a/client/src/cmbuyer_client/device/sku_evidence_sanitizer.py b/client/src/cmbuyer_client/device/sku_evidence_sanitizer.py
index b71e73c..0eef776 100644
--- a/client/src/cmbuyer_client/device/sku_evidence_sanitizer.py
+++ b/client/src/cmbuyer_client/device/sku_evidence_sanitizer.py
@@ -21,7 +21,7 @@ from ..pdd.product_url import ProductUrl, ProductUrlError, parse_product_url
from ..pdd.sku_panel_state import HUMAN_DECLARED_STATES
-SANITIZER_VERSION = "t103-privacy-v2"
+SANITIZER_VERSION = "t103-privacy-v3"
EXPECTED_GOODS_ID = "937122477375"
EXPECTED_PDD_VERSION = "8.17.0"
EXPECTED_DEVICE_MODEL = "PKG110"
@@ -29,7 +29,7 @@ EXPECTED_ANDROID_VERSION = "16"
EXPECTED_SCREENSHOT_WIDTH = 1080
EXPECTED_SCREENSHOT_HEIGHT = 2376
EXPECTED_XML_WIDTH = 1080
-EXPECTED_XML_HEIGHT = 2400
+EXPECTED_XML_HEIGHT = 2376
_ARTIFACT_FILES = ("screenshot.png", "hierarchy.xml")
_SHA256_RE = re.compile(r"[0-9a-f]{64}\Z")
_BOUNDS_RE = re.compile(r"\[(-?\d+),(-?\d+)\]\[(-?\d+),(-?\d+)\]\Z")
diff --git a/client/tests/device/test_sku_evidence_sanitizer.py b/client/tests/device/test_sku_evidence_sanitizer.py
index 90fa7f4..d729928 100644
--- a/client/tests/device/test_sku_evidence_sanitizer.py
+++ b/client/tests/device/test_sku_evidence_sanitizer.py
@@ -48,7 +48,7 @@ def _default_xml() -> str:
return (
""
f""
- f""
+ f""
""
)
@@ -117,17 +117,17 @@ class SkuEvidenceSanitizerTests(unittest.TestCase):
self.assertNotIn(MASKED_PHONE, derived_xml)
self.assertIn(f'"human_declared_state": "{state}"', manifest)
self.assertIn('"privacy_tier": "SANITIZED"', manifest)
- self.assertIn('"sanitizer_version": "t103-privacy-v2"', manifest)
+ self.assertIn('"sanitizer_version": "t103-privacy-v3"', manifest)
self.assertIn('"screenshot_space": {', manifest)
self.assertIn('"xml_coordinate_space": {', manifest)
self.assertIn('"height": 2376', manifest)
- self.assertIn('"height": 2400', manifest)
+ self.assertIn('"height": 2376', manifest)
self.assertIn('"privacy_mask_rectangle": [', manifest)
self.assertIn('"removed_nodes": 1', manifest)
self.assertIn('"cleared_crossing_nodes": 0', manifest)
self.assertIn('"retained_below_nodes": 1', manifest)
self.assertIn('"max_right": 1080', manifest)
- self.assertIn('"max_bottom": 2400', manifest)
+ self.assertIn('"max_bottom": 2376', manifest)
self.assertNotIn("canonical_url", manifest)
self.assertNotIn(TEST_SERIAL, manifest)
self.assertNotIn("serial", manifest)
@@ -138,9 +138,9 @@ class SkuEvidenceSanitizerTests(unittest.TestCase):
def test_crossing_container_keeps_lower_children_but_clears_its_text(self) -> None:
xml = (
""
- f""
+ f""
f""
- f""
+ f""
""
)
with TemporaryDirectory() as temporary:
@@ -151,7 +151,7 @@ class SkuEvidenceSanitizerTests(unittest.TestCase):
self.assertIsNotNone(crossing)
assert crossing is not None
- self.assertEqual(crossing.attrib, {"bounds": "[0,0][1080,2400]"})
+ self.assertEqual(crossing.attrib, {"bounds": "[0,0][1080,2376]"})
self.assertEqual(len(list(crossing)), 1)
self.assertEqual(list(crossing)[0].get("text"), SAFE_TEXT)
manifest = json.loads(result.manifest_path.read_text(encoding="utf-8"))
@@ -162,7 +162,7 @@ class SkuEvidenceSanitizerTests(unittest.TestCase):
"cleared_crossing_nodes": 1,
"retained_below_nodes": 1,
"max_right": 1080,
- "max_bottom": 2400,
+ "max_bottom": 2376,
},
)
@@ -195,9 +195,9 @@ class SkuEvidenceSanitizerTests(unittest.TestCase):
manifest["xml_coordinate_space"],
{
"width": 1080,
- "height": 2400,
+ "height": 2376,
"privacy_mask_rectangle": [0, 0, 1080, 540],
- "observed_max": {"right": 1080, "bottom": 2400},
+ "observed_max": {"right": 1080, "bottom": 2376},
},
)
@@ -243,10 +243,10 @@ class SkuEvidenceSanitizerTests(unittest.TestCase):
("bounds", ""),
(
"private-parent-with-lower-child",
- "",
+ "",
),
- ("full-phone-below", f""),
- ("masked-phone-below", f""),
+ ("full-phone-below", f""),
+ ("masked-phone-below", f""),
)
for kind, xml in malformed:
with self.subTest(kind=kind), TemporaryDirectory() as temporary:
@@ -281,7 +281,7 @@ class SkuEvidenceSanitizerTests(unittest.TestCase):
xml = (
""
""
- f""
+ f""
""
)
with self.subTest(value=value), TemporaryDirectory() as temporary:
@@ -294,7 +294,7 @@ class SkuEvidenceSanitizerTests(unittest.TestCase):
""
""
""
- ""
+ ""
""
)
with TemporaryDirectory() as temporary:
@@ -305,7 +305,7 @@ class SkuEvidenceSanitizerTests(unittest.TestCase):
def test_privacy_geometry_requires_removed_and_retained_nodes(self) -> None:
scenarios = (
- ("no-private", f""),
+ ("no-private", f""),
("no-below", ""),
)
for name, xml in scenarios:
@@ -321,26 +321,26 @@ class SkuEvidenceSanitizerTests(unittest.TestCase):
(
"short-width",
""
- "",
- "1079x2400",
+ "",
+ "1079x2376",
),
(
"short-height",
""
- "",
- "1080x2376",
+ "",
+ "1080x2375",
),
(
"wide-width",
""
- "",
- "1081x2400",
+ "",
+ "1081x2376",
),
(
- "tall-height",
+ "old-v2-xml-height",
""
- "",
- "1080x2401",
+ "",
+ "1080x2400",
),
)
for name, xml, observed in scenarios: