code wiki / (root) / nx_varfacts_lib.nx

nx_varfacts_lib.nx source

↩ module page · 193 lines · 8509 B

1// nx_varfacts_lib.nx -- VaM .var PACKAGE FACT EXTRACTION CORE (conversion tier, VaM lane). 2// 3// A .var is a ZIP archive. THE WALL THIS LANE LIVES BEHIND (standing policy 1785794796 + 4// measure-dont-ship): VaM is a CAPABILITY TARGET -- asset BYTES (meshes/textures/morph deltas) 5// never enter our products or our published plane. What this core reads is the CENTRAL DIRECTORY 6// (file NAMES + sizes = the package's own manifest) and meta.json (the package's own declared 7// license) -- the package describing itself, never its content. Extracted MEASUREMENTS flow to 8// refcorpus behind the k>=8 admission wall like every other reference corpus. 9// 10// COMPOSES INCUMBENTS: EOCD/central-directory walk = the nx_zip_read shape (that organ is a 11// hardwired PyTorch-.bin test, not a library -- the walk is factored HERE as callables); ZIP 12// method-8 members inflate via nx_deflate_inflate, the SAME raw-DEFLATE core under nx_gzip_wrap 13// and nx_zlib_wrap (capacity-bounded; NOT the retired duplicate nx_inflate, debt 1785854636). 14// 15// ★TAIL-WINDOW CONTRACT: the EOCD + central directory live at the END of a ZIP, so a 519MB .var 16// measures from its last few MB. The caller hands the TAIL bytes + the true file size; if the 17// central directory starts before the window, the probe REFUSES (ok=0) -- a partial census is a 18// plausible undercount, which is worse than absence. 19// 20// Fact slots (flat i64, VF_N_SLOTS): 21// [0] ok [1] entries [2] morphs(.vmi) [3] scenes(Saves/scene/*.json) [4] textures(jpg/png/tif) 22// [5] clothing(/Clothing/) [6] hair(/Hair/) [7] plugins(.cs/.cslist/.dll) [8] appearance(.vap) 23// [9] meta_found [10] meta_lho [11] meta_method [12] meta_csize [13] meta_usize 24// license_tier: ORIGINAL No hw writes (Rule 26). 25import "nx_syscalls.nx" 26import "nx_deflate.nx" 27const VF_MAGIC_1024: i64 = 1024 28const VF_MAGIC_4194304: i64 = 4194304 29 30const VF_N_SLOTS: i64 = 14 31 32func vf_u16(b: *u8, o: i64) -> i64 { return (b[o] as i64 & 0xff) | ((b[o+1] as i64 & 0xff) << 8) } 33func vf_u32(b: *u8, o: i64) -> i64 { return (b[o] as i64 & 0xff) | ((b[o+1] as i64 & 0xff) << 8) | ((b[o+2] as i64 & 0xff) << 16) | ((b[o+3] as i64 & 0xff) << 24) } 34 35// name[0,nl) ends with suffix? 36func vf_ends(name: *u8, nl: i64, suf: *u8) -> i64 { 37 var m: i64 = 0 38 while suf[m] != (0 as u8) { m = m + 1 } 39 if nl < m { return 0 } 40 var i: i64 = 0 41 while i < m { if (name[nl-m+i] as i64) != (suf[i] as i64) { return 0 } i = i + 1 } 42 return 1 43} 44func vf_has(name: *u8, nl: i64, sub: *u8) -> i64 { 45 var m: i64 = 0 46 while sub[m] != (0 as u8) { m = m + 1 } 47 if nl < m { return 0 } 48 var i: i64 = 0 49 while i + m <= nl { 50 var k: i64 = 0 51 while k < m { if (name[i+k] as i64) != (sub[k] as i64) { k = m + 9 } else { k = k + 1 } } 52 if k == m { return 1 } 53 i = i + 1 54 } 55 return 0 56} 57 58// probe the TAIL of a .var: tail holds the last tailn bytes, file_size is the true size. 59func vf_probe(tail: *u8, tailn: i64, file_size: i64, facts: *i64) -> i64 { 60 var i: i64 = 0 61 while i < VF_N_SLOTS { facts[i] = 0 - 1; i = i + 1 } 62 facts[0] = 0 63 if tailn < 22 { return 0 } 64 // EOCD: scan back for PK\5\6 65 var e: i64 = tailn - 22 66 var eocd: i64 = 0 - 1 67 while e >= 0 { 68 if (tail[e] as i64) == 0x50 { if (tail[e+1] as i64) == 0x4b { if (tail[e+2] as i64) == 0x05 { if (tail[e+3] as i64) == 0x06 { 69 eocd = e; e = 0 - 1 70 } } } } 71 if e >= 0 { e = e - 1 } 72 } 73 if eocd < 0 { return 0 } 74 let entries: i64 = vf_u16(tail, eocd + 10) 75 let cd_size: i64 = vf_u32(tail, eocd + 12) 76 let cd_abs: i64 = vf_u32(tail, eocd + 16) 77 if entries == 0xffff { return 0 } // ZIP64: refuse honestly, never undercount 78 let base: i64 = file_size - tailn // absolute offset of tail[0] 79 let cd: i64 = cd_abs - base 80 if cd < 0 { return 0 } // CD starts before the window: REFUSE 81 if cd + cd_size > tailn { return 0 } 82 var morphs: i64 = 0 83 var scenes: i64 = 0 84 var tex: i64 = 0 85 var cloth: i64 = 0 86 var hair: i64 = 0 87 var plug: i64 = 0 88 var vap: i64 = 0 89 var off: i64 = cd 90 var k: i64 = 0 91 while k < entries { 92 if off + 46 > tailn { facts[0] = 0; return 0 } 93 if (tail[off] as i64) != 0x50 { facts[0] = 0; return 0 } 94 if (tail[off+1] as i64) != 0x4b { facts[0] = 0; return 0 } 95 let method: i64 = vf_u16(tail, off + 10) 96 let csize: i64 = vf_u32(tail, off + 20) 97 let usize: i64 = vf_u32(tail, off + 24) 98 let fnl: i64 = vf_u16(tail, off + 28) 99 let exl: i64 = vf_u16(tail, off + 30) 100 let cml: i64 = vf_u16(tail, off + 32) 101 let lho: i64 = vf_u32(tail, off + 42) 102 let nm: *u8 = ((tail as i64) + off + 46) as *u8 103 if vf_ends(nm, fnl, ".vmi" as *u8) == 1 { morphs = morphs + 1 } 104 if vf_has(nm, fnl, "Saves/scene/" as *u8) == 1 { if vf_ends(nm, fnl, ".json" as *u8) == 1 { scenes = scenes + 1 } } 105 if vf_ends(nm, fnl, ".jpg" as *u8) == 1 { tex = tex + 1 } 106 if vf_ends(nm, fnl, ".png" as *u8) == 1 { tex = tex + 1 } 107 if vf_ends(nm, fnl, ".tif" as *u8) == 1 { tex = tex + 1 } 108 if vf_has(nm, fnl, "/Clothing/" as *u8) == 1 { cloth = cloth + 1 } 109 if vf_has(nm, fnl, "/Hair/" as *u8) == 1 { hair = hair + 1 } 110 if vf_ends(nm, fnl, ".cs" as *u8) == 1 { plug = plug + 1 } 111 if vf_ends(nm, fnl, ".cslist" as *u8) == 1 { plug = plug + 1 } 112 if vf_ends(nm, fnl, ".dll" as *u8) == 1 { plug = plug + 1 } 113 if vf_ends(nm, fnl, ".vap" as *u8) == 1 { vap = vap + 1 } 114 if fnl == 9 { if vf_has(nm, fnl, "meta.json" as *u8) == 1 { 115 facts[9] = 1 116 facts[10] = lho 117 facts[11] = method 118 facts[12] = csize 119 facts[13] = usize 120 } } 121 off = off + 46 + fnl + exl + cml 122 k = k + 1 123 } 124 facts[0] = 1 125 facts[1] = entries 126 facts[2] = morphs 127 facts[3] = scenes 128 facts[4] = tex 129 facts[5] = cloth 130 facts[6] = hair 131 facts[7] = plug 132 facts[8] = vap 133 if facts[9] != 1 { facts[9] = 0 } 134 return 0 135} 136 137// extract the declared licenseType from a meta.json BODY (already read from the archive; method 0 138// = as-is, method 8 = raw deflate via the incumbent core). Writes a NUL-terminated label (max 40 139// chars, whitelist alphabet) or "unparsed". The body is the package DESCRIBING itself -- the one 140// member this lane ever opens. 141func vf_license(body: *u8, csize: i64, method: i64, usize: i64, out: *u8) -> i64 { 142 var src: *u8 = body 143 var n: i64 = csize 144 if method == 8 { 145 var cap: i64 = usize + 64 146 if cap < VF_MAGIC_1024 { cap = VF_MAGIC_1024 } 147 if cap > VF_MAGIC_4194304 { out[0] = 0 as u8; return 0 - 1 } 148 let dr: *NxDeflateResult = nx_deflate_inflate(body, csize, cap) 149 if (dr as i64) == 0 { out[0] = 0 as u8; return 0 - 1 } 150 if dr.error_code != 0 { out[0] = 0 as u8; return 0 - 1 } 151 src = dr.output_data 152 n = dr.output_size 153 } else { if method != 0 { out[0] = 0 as u8; return 0 - 1 } } 154 // find "licenseType" then the next quoted string 155 let key: *u8 = "licenseType" as *u8 156 var at: i64 = 0 - 1 157 var i: i64 = 0 158 while i + 11 <= n { 159 var k: i64 = 0 160 while k < 11 { if (src[i+k] as i64) != (key[k] as i64) { k = 20 } else { k = k + 1 } } 161 if k == 11 { at = i + 11; i = n + 1 } else { i = i + 1 } 162 } 163 if at < 0 { out[0] = 0 as u8; return 0 - 1 } 164 // the value: first ':' after the key, then the first '"' after that opens it 165 var colon: i64 = 0 - 1 166 i = at 167 while i < n { if (src[i] as i64) == 58 { colon = i; i = n + 1 } else { i = i + 1 } } 168 if colon < 0 { out[0] = 0 as u8; return 0 - 1 } 169 var vq: i64 = 0 - 1 170 i = colon + 1 171 while i < n { if (src[i] as i64) == 34 { vq = i + 1; i = n + 1 } else { i = i + 1 } } 172 if vq < 0 { out[0] = 0 as u8; return 0 - 1 } 173 var p: i64 = 0 174 i = vq 175 while i < n { 176 let c2: i64 = src[i] as i64 177 if c2 == 34 { out[p] = 0 as u8; return p } 178 var ok: i64 = 0 179 if c2 >= 48 { if c2 <= 57 { ok = 1 } } 180 if c2 >= 65 { if c2 <= 90 { ok = 1 } } 181 if c2 >= 97 { if c2 <= 122 { ok = 1 } } 182 if c2 == 32 { ok = 1 } 183 if c2 == 45 { ok = 1 } 184 if c2 == 46 { ok = 1 } 185 if ok == 0 { out[0] = 0 as u8; return 0 - 1 } 186 if p >= 40 { out[0] = 0 as u8; return 0 - 1 } 187 out[p] = c2 as u8 188 p = p + 1 189 i = i + 1 190 } 191 out[0] = 0 as u8 192 return 0 - 1 193}