← back to Designer Wallcoverings
patcher: make .value regex non-backtracking ((?!\\w)) so re-runs are truly idempotent
005ffea3870051050d8cda9b6dc5a5dcd5f2ecde · 2026-06-24 15:42:24 -0700 · Steve
Prevents silent .valueX corruption if the patcher is ever run on an
already-fixed snippet (the old lookahead let the key backtrack to a truncated
form). Unit-tested: no-op on fixed text, correct on bare text, double-run safe.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Files touched
M shopify/push-spec-metafield-value-fix.sh
Diff
commit 005ffea3870051050d8cda9b6dc5a5dcd5f2ecde
Author: Steve <steve@designerwallcoverings.com>
Date: Wed Jun 24 15:42:24 2026 -0700
patcher: make .value regex non-backtracking ((?!\\w)) so re-runs are truly idempotent
Prevents silent .valueX corruption if the patcher is ever run on an
already-fixed snippet (the old lookahead let the key backtrack to a truncated
form). Unit-tested: no-op on fixed text, correct on bare text, double-run safe.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
shopify/push-spec-metafield-value-fix.sh | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/shopify/push-spec-metafield-value-fix.sh b/shopify/push-spec-metafield-value-fix.sh
index ceac50b0..4adff5e6 100755
--- a/shopify/push-spec-metafield-value-fix.sh
+++ b/shopify/push-spec-metafield-value-fix.sh
@@ -58,8 +58,11 @@ stamp = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
bk = f"{bkdir}/product-description-meta.{label}.{tid}.{stamp}.bak"
open(bk, "w").write(cur); print(f"backup: {bk} ({len(cur)} bytes)")
-# idempotent: append .value to bare metafield refs (dotted + bracket keys)
-pat = re.compile(r"(product\.metafields\.\w+(?:\.\w+|\['[^']*'\]))(?!\.value)")
+# idempotent: append .value to bare metafield refs (dotted + bracket keys).
+# (?!\w) anchors the key to its full length so the match can't backtrack to a
+# truncated key on already-fixed text (e.g. custom.width.value) — making re-runs
+# safe (true idempotency, no .valueX corruption).
+pat = re.compile(r"(product\.metafields\.\w+(?:\.\w+|\['[^']*'\]))(?!\w)(?!\.value)")
before = len(pat.findall(cur))
src = pat.sub(r"\1.value", cur)
after_bare = len(pat.findall(src))
← 75e798ac Add reusable Shopify theme duplication script (asset-copy +
·
back to Designer Wallcoverings
·
Fix double-encoded metafield leak: unwrap {type,value} blobs b25933f1 →