fix(content-type): decode dollar sign in Story Block JSON on read (#35782)#36346
fix(content-type): decode dollar sign in Story Block JSON on read (#35782)#36346dsilvam wants to merge 1 commit into
Conversation
…5782) The $ character was persisted in contentlet_as_json as its decimal HTML entity $ and survived into the editor because the read-time decoder only reversed : and ,; extend escapeHTMLCodeFromJSON to also decode $ so the Block Editor and all API consumers receive a literal $. Refs: #35782 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Claude finished @dsilvam's task in 2m 37s —— View job dotCMS Backend Review Pipeline
Review posted at #36346 (comment) Summary of findings:
|
🤖 dotBot Review (Bedrock)Reviewed 2 file(s); 1 candidate(s) → 0 confirmed, 0 uncertain (unverified, kept for review). ✅ No issues found after verification. us.deepseek.r1-v1:0 · Run: #28371278901 · tokens: in: 5870 · out: 1868 · total: 7738 · calls: 3 · est. ~$0.018 |
🔍 dotCMS Backend Review[🟠 High]
public static String escapeHTMLCodeFromJSON(String json) {
json = json.replace(":",":") // parameter reassigned; method actually decodes💡 Consider renaming to [🟡 Medium]
public static String escapeHTMLCodeFromJSON(String json) {
json = json.replace(":",":") // NPE if json is null💡 Add [🟡 Medium]
// Only happy-path tested; null input not covered
final String encoded = "{\"text\":\"The application fee is $50, see http://x.com\"}";💡 Add Next steps
|
Proposed Changes
UtilMethods.escapeHTMLCodeFromJSON(...)now also decodes the decimal HTML numeric entity$back to a literal$, alongside the existing:→:and,→,decoding.UtilMethodsTestlocking in$decoding (plus the existing:/,behavior).Additional Info
A
$typed into a Block Editor (Story Block) field was persisted incontentlet_as_jsonas its decimal HTML numeric entity$(same family as the:/,case from #25903 / #28020). On every content read,ContentletTransformer.transform()passes the whole JSON throughescapeHTMLCodeFromJSON, which only reversed:and,— so$survived into the value handed to the editor.The symptom was editor-only: the browser HTML parser renders
$as$(front-end output looked correct), but the ProseMirror/TipTap editor displays the raw text node$50literally on reopen. The shared read path (ContentletTransformer→StoryBlockViewStrategy) is why both the legacy and new editors were affected.Fixing at this universal read boundary is what the issue investigation recommended ("fix at the read/transform boundary so all API consumers — not just the editor — receive the correct
$"), and it self-heals content that was already saved with$— no DB migration required.Checklist
🤖 Generated with Claude Code
This PR fixes: #35782