fix(classic): minimise payload source escaping before the CDATA wrap - #311
Merged
Merged
Conversation
The update path re-serialises the plist for UUID injection via howett.net/plist, whose encoding/xml backend escapes quotes, apostrophes, and value newlines/tabs as numeric references. Verbatim-stored payload types preserve the wire representation with zero decodes (PI-827), so those avoidable references surfaced as literal text in stored values — a TCC CodeRequirement updated through the CLI came back as identifier "com..." and tripped the post-write verification. normalizeClassicProfilePayloadsForSend now decodes every character reference except those encoding "&" and "<" before guarding and escaping (both representations parse to identical values; only the wire form changes). Side benefit: the unavoidable verbatim-storage corruption shrinks to genuine "&"/"<" characters — entity-form ">", quotes, and apostrophes in user files now store value-correct everywhere. Wire-verified: an entity-free TCC profile now survives create + update byte-exact with zero verification warnings; quotes in CodeRequirement stay literal through the howett re-serialisation. Mirrors jamfplatform-go-sdk#45 (same fix in PayloadsXMLText). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
neilmartin83
enabled auto-merge
July 30, 2026 16:31
grahampugh
approved these changes
Jul 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #310, mirroring Jamf-Concepts/jamfplatform-go-sdk#45.
Problem
The update path re-serialises the plist for UUID injection via
howett.net/plist, whoseencoding/xmlbackend escapes quotes, apostrophes, and value newlines/tabs as numeric references (",',
). Verbatim-stored payload types preserve the wire representation with zero decodes (PI-827), so those avoidable references surfaced as literal text in stored values — a TCCCodeRequirementupdated through the CLI came back asidentifier "com..."(breaking the signing requirement) and tripped the post-write verification warning.Fix
normalizeClassicProfilePayloadsForSendnow minimises source escaping before guarding and escaping: every character/entity reference except those encoding&and<is decoded to its literal character. Both representations parse to identical values — only the wire form changes — but the wire form is what verbatim storage preserves. Ordering is load-bearing: the]]>guard runs after minimising (decoding>can resurrect the terminator).Side benefit: the unavoidable verbatim-storage corruption shrinks to genuine
&/<characters — entity-form>, quotes, and apostrophes in user mobileconfigs now store value-correct on the mobile endpoint and in verbatim macOS payload types, not just in MCX-family payloads.Verification
Wire-verified live: an entity-free TCC profile survives create and update byte-exact with zero verification warnings — quotes in
CodeRequirementstay literal through the howett re-serialisation (previously corrupted on every update). Unit tests cover the minimisation table (decoded vs must-preserve references, unknown entities, bare ampersands, terminator resurrection); full suite green, lint clean.🤖 Generated with Claude Code