code wiki / (root) / nx_yt_basejs.nx

nx_yt_basejs.nx source

↩ module page · 111 lines · 4953 B

1// nx_yt_basejs.nx -- NATIVE (no JS engine) name-finder for YouTube's base.js n-throttle function. This is the 2// fragile arms-race parse yt-dlp needs, done in NishiLang: locate the n-function's NAME from the player code so 3// nx_yt_nsolve can then RUN it (that run is the last-mile JS; THIS locate is native text analysis). Real shape, 4// minified: `...a.get("n"))&&(b=Wma[0](b)...` where the function is referenced through an ARRAY (`Wma[0]`) whose 5// element list is defined elsewhere (`var Wma=[Xdec,Yfoo]`), OR referenced directly (`&&(c=lha(c)`). Layered so 6// a shape change that breaks one pattern still resolves via another -- and a total miss is a LEARN signal for 7// the self-heal table (name-location is itself a learnable pattern). license_tier: ORIGINAL 8import "nx_syscalls.nx" 9import "nx_media_signal.nx" // xt_find (native substring) 10 11// JS identifier char: 0-9 A-Z a-z _ $ 12func bjs_identc(c: i64) -> i64 { 13 if c >= 48 { if c <= 57 { return 1 } } 14 if c >= 65 { if c <= 90 { return 1 } } 15 if c >= 97 { if c <= 122 { return 1 } } 16 if c == 95 { return 1 } 17 if c == 36 { return 1 } 18 return 0 19} 20// read a JS identifier starting at `from`; copy into out (NUL-terminated); return its length (0 if none). 21func bjs_read_ident(js: *u8, jl: i64, from: i64, out: *u8, cap: i64) -> i64 { 22 var i: i64 = from 23 var w: i64 = 0 24 var go: i64 = 1 25 while go == 1 { 26 if i >= jl { go = 0 } 27 else { let c: i64 = js[i] & 0xff 28 if bjs_identc(c) == 1 { if w < (cap - 1) { out[w] = c as u8; w = w + 1 } i = i + 1 } 29 else { go = 0 } } 30 } 31 out[w] = 0 as u8 32 return w 33} 34// resolve `<arrname>[idx]` -> the idx-th comma-separated identifier in `<arrname>=[e0,e1,...]`. Returns len or 0. 35func bjs_resolve_array_elem(js: *u8, jl: i64, arrname: *u8, arrnamelen: i64, idx: i64, out: *u8, cap: i64) -> i64 { 36 let nd: *u8 = sys_mmap(256) 37 var o: i64 = 0 38 while o < arrnamelen { nd[o] = arrname[o]; o = o + 1 } 39 nd[o] = 61 as u8; o = o + 1 // '=' 40 nd[o] = 91 as u8; o = o + 1 // '[' 41 let p: i64 = xt_find(js, jl, nd, o, 0) 42 if p < 0 { return 0 } 43 var i: i64 = p + o // just past "arrname=[" 44 var elem: i64 = 0 45 var go: i64 = 1 46 while go == 1 { 47 if i >= jl { go = 0; out[0] = 0 as u8; return 0 } 48 else { 49 let c: i64 = js[i] & 0xff 50 if c == 93 { go = 0; out[0] = 0 as u8; return 0 } // ']' before reaching idx 51 else { 52 if bjs_identc(c) == 1 { 53 if elem == idx { return bjs_read_ident(js, jl, i, out, cap) } 54 // skip this element's identifier 55 let sk: i64 = bjs_read_ident(js, jl, i, out, cap) 56 i = i + sk 57 } else { 58 if c == 44 { elem = elem + 1 } // ',' -> next element 59 i = i + 1 60 } 61 } 62 } 63 } 64 out[0] = 0 as u8 65 return 0 66} 67// FIND the n-function name in base.js. Returns resolved name length in `out` (0 = not found = a LEARN signal). 68func bjs_find_nfunc_name(js: *u8, jl: i64, out: *u8, cap: i64) -> i64 { 69 // anchor: the n-param read `.get("n")` 70 let p: i64 = xt_find(js, jl, ".get(\"n\")" as *u8, 9, 0) 71 if p < 0 { out[0] = 0 as u8; return 0 } 72 // the near `&&(` that opens the transform assignment (bounded search so we don't grab a distant one) 73 let a: i64 = xt_find(js, jl, "&&(" as *u8, 3, p) 74 if a < 0 { out[0] = 0 as u8; return 0 } 75 if (a - p) > 64 { out[0] = 0 as u8; return 0 } 76 // skip the assignment target `<v>=` 77 var i: i64 = a + 3 78 let tmp: *u8 = sys_mmap(256) 79 let vlen: i64 = bjs_read_ident(js, jl, i, tmp, 256) 80 i = i + vlen 81 if i >= jl { out[0] = 0 as u8; return 0 } 82 if (js[i] & 0xff) != 61 { out[0] = 0 as u8; return 0 } // expect '=' 83 i = i + 1 84 // read the function reference identifier 85 let reflen: i64 = bjs_read_ident(js, jl, i, out, cap) 86 if reflen == 0 { out[0] = 0 as u8; return 0 } 87 i = i + reflen 88 // array-indexed? `<ref>[<digits>]` -> resolve via the array literal 89 if i < jl { if (js[i] & 0xff) == 91 { // '[' 90 var j: i64 = i + 1 91 var idx: i64 = 0 92 var got: i64 = 0 93 var g2: i64 = 1 94 while g2 == 1 { 95 if j >= jl { g2 = 0 } 96 else { let d: i64 = js[j] & 0xff 97 if d >= 48 { if d <= 57 { idx = idx * 10 + (d - 48); got = 1; j = j + 1 } else { g2 = 0 } } 98 if d < 48 { g2 = 0 } 99 if d > 57 { g2 = 0 } } 100 } 101 if got == 1 { 102 let arrname: *u8 = sys_mmap(256) 103 var k: i64 = 0 104 while k < reflen { arrname[k] = out[k]; k = k + 1 } 105 arrname[reflen] = 0 as u8 106 let rl: i64 = bjs_resolve_array_elem(js, jl, arrname, reflen, idx, out, cap) 107 return rl 108 } 109 } } 110 return reflen 111}