code wiki / (root) / nx_html_extract_imgs_test.nx

nx_html_extract_imgs_test.nx source

↩ module page · 94 lines · 4467 B

1// nx_html_extract_imgs_test.nx -- exercise nx_html_extract_imgs 2// against a synthetic HTML document containing: 3// - mixed absolute / scheme-relative / path-relative img URLs 4// - <script> body containing literal "<img src='trap.png'>" that 5// must NOT be extracted (proves Arc B1 raw-text mode integration) 6// - case-variant <IMG> tag name 7// 8// expect_exit: 0 9// license_tier: ORIGINAL 10 11import "nx_syscalls.nx" 12import "nx_html_extract_imgs.nx" 13 14func _fail(n: i64) -> i64 { 15 let b: *u8 = sys_mmap(16) 16 b[0]=0x46; b[1]=0x41; b[2]=0x49; b[3]=0x4C; b[4]=0x3D 17 sys_write(2, b, 5) 18 var x: i64 = n 19 if x < 0 { let m: *u8 = sys_mmap(4); m[0]=0x2D; sys_write(2, m, 1); x = 0 - x } 20 if x == 0 { let z: *u8 = sys_mmap(4); z[0]=0x30; sys_write(2, z, 1) } 21 else { 22 let buf: *u8 = sys_mmap(16) 23 var pos: i64 = 0 24 while x > 0 { buf[pos] = (0x30 + (x % 10)) as u8; x = x / 10; pos = pos + 1 } 25 let out: *u8 = sys_mmap(16) 26 var i: i64 = 0 27 while i < pos { out[i] = buf[pos - 1 - i]; i = i + 1 } 28 sys_write(2, out, pos) 29 } 30 let nl: *u8 = sys_mmap(4); nl[0]=0x0A; sys_write(2, nl, 1) 31 return 0 32} 33 34func _bytes_eq_lit(buf: *u8, off: i64, n: i64, lit: *u8) -> i64 { 35 var i: i64 = 0 36 while i < n { 37 if buf[off + i] != lit[i] { return 0 } 38 i = i + 1 39 } 40 if lit[n] != 0 { return 0 } 41 return 1 42} 43 44func main() -> i64 { 45 let html: *u8 = "<html><head><script>var s='<img src=\"trap.png\">';</script></head><body><img src=\"hero.png\"><p>x</p><IMG src='/static/logo.png'><img src=\"https://cdn.com/a.png\"><img src=\"//other.com/b.png\"></body></html>" 46 var hlen: i64 = 0 47 while html[hlen] != 0 { hlen = hlen + 1 } 48 49 let base: *u8 = "https://www.example.com/page/index.html" 50 var blen: i64 = 0 51 while base[blen] != 0 { blen = blen + 1 } 52 53 let url_buf: *u8 = sys_mmap(2048) 54 let offsets: *i64 = sys_mmap(256) as *i64 55 let lengths: *i64 = sys_mmap(256) as *i64 56 57 let n: i64 = nx_html_extract_imgs(html, hlen, base, blen, 58 url_buf, 2048, offsets, lengths, 32) 59 if n != 4 { _fail(1); return 1 } // 4 real imgs, NOT the script trap 60 61 // 0: hero.png -> https://www.example.com/page/hero.png 62 if _bytes_eq_lit(url_buf, offsets[0], lengths[0], "https://www.example.com/page/hero.png" as *u8) != 1 { _fail(2); return 2 } 63 64 // 1: /static/logo.png -> https://www.example.com/static/logo.png (case-insensitive IMG) 65 if _bytes_eq_lit(url_buf, offsets[1], lengths[1], "https://www.example.com/static/logo.png" as *u8) != 1 { _fail(3); return 3 } 66 67 // 2: absolute https://cdn.com/a.png -> verbatim 68 if _bytes_eq_lit(url_buf, offsets[2], lengths[2], "https://cdn.com/a.png" as *u8) != 1 { _fail(4); return 4 } 69 70 // 3: scheme-relative //other.com/b.png -> https://other.com/b.png 71 if _bytes_eq_lit(url_buf, offsets[3], lengths[3], "https://other.com/b.png" as *u8) != 1 { _fail(5); return 5 } 72 73 // ---- entity decoding (the media-ledger defect, by its real shape) ---- 74 // A Commons thumbnail url is authored with `&amp;` because that is CORRECT html. Copying the 75 // attribute verbatim produced a url whose 2nd and 3rd params were literally named `amp;utm_...`, 76 // which is a different resource -- and 37 of 438 rows in media_ledger.tsv are in that state. 77 let h2: *u8 = "<img src=\"https://upload.wikimedia.org/x.jpg?utm_source=en.wikipedia.org&amp;utm_campaign=parser&amp;utm_content=thumbnail\"><img src=\"clean.png\">" 78 var h2len: i64 = 0 79 while h2[h2len] != 0 { h2len = h2len + 1 } 80 let ub2: *u8 = sys_mmap(2048) 81 let of2: *i64 = sys_mmap(256) as *i64 82 let ln2: *i64 = sys_mmap(256) as *i64 83 let n2: i64 = nx_html_extract_imgs(h2, h2len, base, blen, ub2, 2048, of2, ln2, 32) 84 if n2 != 2 { _fail(6); return 6 } 85 if _bytes_eq_lit(ub2, of2[0], ln2[0], "https://upload.wikimedia.org/x.jpg?utm_source=en.wikipedia.org&utm_campaign=parser&utm_content=thumbnail" as *u8) != 1 { _fail(7); return 7 } 86 // NEGATIVE CONTROL: a url with nothing to decode must come through BYTE-IDENTICAL. Without this, 87 // a canonicaliser that mangled ordinary urls would still pass the tooth above. 88 if _bytes_eq_lit(ub2, of2[1], ln2[1], "https://www.example.com/page/clean.png" as *u8) != 1 { _fail(8); return 8 } 89 90 let pass: *u8 = sys_mmap(16) 91 pass[0]=0x50; pass[1]=0x41; pass[2]=0x53; pass[3]=0x53; pass[4]=0x0A 92 sys_write(1, pass, 5) 93 return 0 94}