nx_acquire_license_gate.nx source
↩ module page · 98 lines · 6482 B
1// nx_acquire_license_gate.nx -- GATE for nx_acquire_license_lib.
2//
3// The subject is pure (a URL in, a URL out), so this gate needs NO fixture on disk and cannot go
4// vacuous through a missing one. Every expected string below is written out in full rather than
5// rebuilt by the same concatenation the subject uses -- a test that assembles its expectation with
6// the code under test passes for any consistent bug, which is the tautological-oracle defect.
7// license_tier: ORIGINAL
8import "nx_syscalls.nx"
9import "nx_gate_verdict.nx"
10import "nx_acquire_license_lib.nx"
11
12func alg_is(url: *u8, cand: i64, want: *u8) -> i64 {
13 let out: *u8 = sys_mmap(AL_URLCAP)
14 let n: i64 = aq_license_url(url, cand, out, AL_URLCAP)
15 if n < 0 { return 0 }
16 return al_streq(out, want)
17}
18
19func alg_refuses(url: *u8, cand: i64) -> i64 {
20 let out: *u8 = sys_mmap(AL_URLCAP)
21 let n: i64 = aq_license_url(url, cand, out, AL_URLCAP)
22 if n < 0 { return 1 }
23 return 0
24}
25
26func main(argc: i64, argv: *i64) -> i64 {
27 let ctr: *i64 = gv_ctr()
28 gv_head("=== nx_acquire_license_gate: where to read an external work's licence ===" as *u8)
29
30 // ---- github, the 19-of-26 case in acquire_sources.conf ----
31 gv_check("github-plain-repo-derives-LICENSE" as *u8,
32 alg_is("https://github.com/naver/anny" as *u8, 0, "https://raw.githubusercontent.com/naver/anny/HEAD/LICENSE" as *u8), ctr)
33 gv_check("github-candidate-1-derives-LICENSE-md" as *u8,
34 alg_is("https://github.com/naver/anny" as *u8, 1, "https://raw.githubusercontent.com/naver/anny/HEAD/LICENSE.md" as *u8), ctr)
35 gv_check("github-candidate-3-derives-COPYING" as *u8,
36 alg_is("https://github.com/naver/anny" as *u8, 3, "https://raw.githubusercontent.com/naver/anny/HEAD/COPYING" as *u8), ctr)
37 // A TRAILING SLASH IS A REAL ROW: acquire_sources.conf carries github.com/naver/goal-co/ verbatim
38 // from the upstream listing. If the segment scan mishandled it the repo name would carry a slash.
39 gv_check("github-trailing-slash-url-still-yields-owner-and-repo" as *u8,
40 alg_is("https://github.com/naver/goal-co/" as *u8, 0, "https://raw.githubusercontent.com/naver/goal-co/HEAD/LICENSE" as *u8), ctr)
41 // A DEEP URL IS ALSO A REAL ROW: the mRAG entry links a file inside the repo, not the repo root.
42 // The licence belongs to the repository, so everything past owner/repo must be discarded.
43 gv_check("github-deep-blob-url-truncates-to-the-repository" as *u8,
44 alg_is("https://github.com/naver/bergen/blob/main/documentation/multilingual.md" as *u8, 0, "https://raw.githubusercontent.com/naver/bergen/HEAD/LICENSE" as *u8), ctr)
45
46 // ---- huggingface: licence lives in README.md YAML frontmatter, not a LICENSE file ----
47 gv_check("huggingface-model-derives-its-README" as *u8,
48 alg_is("https://huggingface.co/naver/oscar-qwen2-7B" as *u8, 0, "https://huggingface.co/naver/oscar-qwen2-7B/raw/main/README.md" as *u8), ctr)
49 // THE ORDERING TOOTH. The dataset prefix EXTENDS the model prefix, so a classifier that tests the
50 // shorter one first sends every dataset to a model path. That 404 would read as "this dataset has
51 // no licence" -- a false negative produced by rule order, invisible in any single-case test.
52 gv_check("huggingface-DATASET-derives-the-dataset-path-not-the-model-path" as *u8,
53 alg_is("https://huggingface.co/datasets/FBK-MT/Speech-MASSIVE" as *u8, 0, "https://huggingface.co/datasets/FBK-MT/Speech-MASSIVE/raw/main/README.md" as *u8), ctr)
54 gv_check("huggingface-dataset-classified-as-dataset-not-as-model" as *u8,
55 (al_host("https://huggingface.co/datasets/FBK-MT/Speech-MASSIVE" as *u8) == AL_HOST_HF_DATASET) as i64, ctr)
56 gv_check("huggingface-model-classified-as-model-not-as-dataset" as *u8,
57 (al_host("https://huggingface.co/naver/oscar-qwen2-7B" as *u8) == AL_HOST_HF) as i64, ctr)
58
59 // ---- refusals: every one of these must fail CLOSED ----
60 // The NAVER listing itself, and the LPOSS row which ships no link at all.
61 gv_check("unknown-host-refuses-rather-than-guessing" as *u8,
62 alg_refuses("https://europe.naverlabs.com/research/code/" as *u8, 0), ctr)
63 gv_check("github-owner-without-repo-refuses" as *u8,
64 alg_refuses("https://github.com/naver" as *u8, 0), ctr)
65 gv_check("candidate-index-above-the-list-refuses" as *u8,
66 alg_refuses("https://github.com/naver/anny" as *u8, 4), ctr)
67 gv_check("negative-candidate-index-refuses" as *u8,
68 alg_refuses("https://github.com/naver/anny" as *u8, 0 - 1), ctr)
69 gv_check("empty-url-refuses" as *u8, alg_refuses("" as *u8, 0), ctr)
70 // A LOOK-ALIKE HOST MUST NOT MATCH. A prefix test that forgot its scheme would accept an attacker
71 // domain that merely contains the string github.com.
72 gv_check("lookalike-host-github-com-evil-example-refuses" as *u8,
73 alg_refuses("https://github.com.evil.example/naver/anny" as *u8, 0), ctr)
74
75 // ================= BITE-PROVEN NEGATIVE CONTROLS =================
76 // B1: is the dataset-before-model ordering actually doing work?
77 var b1_bad: i64 = 0
78 var b1_good: i64 = 0
79 if al_host("https://huggingface.co/datasets/FBK-MT/Speech-MASSIVE" as *u8) == AL_HOST_HF_DATASET { b1_bad = 1 }
80 if al_host("https://huggingface.co/naver/oscar-qwen2-7B" as *u8) == AL_HOST_HF_DATASET { b1_good = 1 }
81 gv_bite("neg-control-dataset-url-classifies-as-dataset-and-a-model-url-does-not" as *u8, b1_bad, b1_good, ctr)
82
83 // B2: does the unknown-host refusal fire, and stay silent on a host we do know?
84 var b2_bad: i64 = 0
85 var b2_good: i64 = 0
86 if alg_refuses("https://gitlab.example/naver/anny" as *u8, 0) == 1 { b2_bad = 1 }
87 if alg_refuses("https://github.com/naver/anny" as *u8, 0) == 1 { b2_good = 1 }
88 gv_bite("neg-control-unestablished-host-REFUSES-and-an-established-one-does-not" as *u8, b2_bad, b2_good, ctr)
89
90 // B3: does the owner-and-repo requirement fire on a short URL and stay silent on a complete one?
91 var b3_bad: i64 = 0
92 var b3_good: i64 = 0
93 if alg_refuses("https://github.com/naver" as *u8, 0) == 1 { b3_bad = 1 }
94 if alg_refuses("https://github.com/naver/anny" as *u8, 0) == 1 { b3_good = 1 }
95 gv_bite("neg-control-missing-repo-segment-REFUSES-and-a-complete-pair-does-not" as *u8, b3_bad, b3_good, ctr)
96
97 return gv_verdict("ACQUIRE-LICENCE-GATE" as *u8, ctr, "licence locations are derived for established hosts only and every other shape fails closed" as *u8)
98}