code wiki / _hdl_build / nx_cms_render.nx

nx_cms_render.nx source

↩ module page · 67 lines · 2795 B

1// nx_cms_render.nx -- CMS ladder step 10b: RENDER-FROM-DATA. The template (structure/design tokens, 2// the team's) is HTML with {{key}} markers; the content store (the legal team's data) fills them. 3// Defense in depth (spec law): keys ending in _html were allowlist-SANITIZED at write and insert raw; 4// every other key is entity-ESCAPED here at render. Unknown {{key}} renders as nothing (and never 5// leaks the marker). Composes nx_cms_store + nx_html_sanitize. license_tier: ORIGINAL 6import "nx_cms_store.nx" 7import "nx_html_sanitize.nx" 8const K_MAGIC_262144: i64 = 262144 9const K_MAGIC_262143: i64 = 262143 10 11// does key (kl bytes) end in "_html"? 12func crd_is_html(key: *u8, kl: i64) -> i64 { 13 if kl < 5 { return 0 } 14 if (key[kl-5] as i64) != 95 { return 0 } // _ 15 if (key[kl-4] as i64) != 104 { return 0 } // h 16 if (key[kl-3] as i64) != 116 { return 0 } // t 17 if (key[kl-2] as i64) != 109 { return 0 } // m 18 if (key[kl-1] as i64) != 108 { return 0 } // l 19 return 1 20} 21 22// render template tpl[0..tn) against store sbuf[0..sn) into out (cap). returns output length. 23func crd_render(tpl: *u8, tn: i64, sbuf: *u8, sn: i64, out: *u8, cap: i64) -> i64 { 24 let key: *u8 = sys_mmap(128) 25 let val: *u8 = sys_mmap(K_MAGIC_262144) 26 var i: i64 = 0 27 var o: i64 = 0 28 while i < tn { 29 var marker: i64 = 0 30 if i + 1 < tn { if (tpl[i] as i64) == 123 { if (tpl[i+1] as i64) == 123 { marker = 1 } } } 31 if marker == 0 { 32 if o < cap { out[o] = tpl[i]; o = o + 1 } 33 i = i + 1 34 } 35 if marker == 1 { 36 // gather key up to }} 37 var j: i64 = i + 2 38 var kl: i64 = 0 39 var closed: i64 = 0 40 while j + 1 < tn { 41 if (tpl[j] as i64) == 125 { if (tpl[j+1] as i64) == 125 { closed = 1; j = tn } } 42 if j < tn { if closed == 0 { if kl < 127 { key[kl] = tpl[j]; kl = kl + 1 } j = j + 1 } } 43 } 44 if closed == 0 { 45 // no closing braces: emit the raw byte, move on 46 if o < cap { out[o] = tpl[i]; o = o + 1 } 47 i = i + 1 48 } 49 if closed == 1 { 50 key[kl] = 0 as u8 51 let vl: i64 = cst_get(sbuf, sn, key, val, K_MAGIC_262143) 52 if vl >= 0 { 53 if crd_is_html(key, kl) == 1 { 54 var m: i64 = 0 55 while m < vl { if o < cap { out[o] = val[m]; o = o + 1 } m = m + 1 } 56 } 57 if crd_is_html(key, kl) == 0 { 58 o = o + hs_escape(val, vl, out + o, cap - o) 59 } 60 } 61 // skip past {{key}} 62 i = i + 2 + kl + 2 63 } 64 } 65 } 66 return o 67}