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}