nx_compare_openapi_gate.nx source
↩ module page · 139 lines · 9334 B
1import "nx_compare_openapi.nx"
2import "nx_gate_verdict.nx"
3
4func cgot_has(b: *u8, n: i64, s: *u8) -> i64 {
5 let sn: i64 = cg_slen(s)
6 var i: i64 = 0
7 while i <= n - sn {
8 var j: i64 = 0
9 var equal: i64 = 1
10 while j < sn { if b[i+j] != s[j] { equal = 0 } j = j + 1 }
11 if equal == 1 { return 1 }
12 i = i + 1
13 }
14 return 0
15}
16
17func cgot_case(label: *u8, counts: *i64, src: *u8, level: i64, expected: i64, must: *u8, absent: *u8, small_identity: i64) -> i64 {
18 let n: i64 = cg_slen(src)
19 let out: *u8 = sys_mmap(n+1)
20 let name: *u8 = sys_mmap(n+1)
21 let dom: *u8 = sys_mmap(n+1)
22 let conf: *u8 = "default|public\ndomain|synthroom|operator\n" as *u8
23 var dcap: i64 = n+1
24 if small_identity > 0 { dcap = small_identity }
25 let result: i64 = cgo_project(src, n, level, conf, cg_slen(conf), out, n, name, n+1, dom, dcap)
26 var failure: i64 = 0
27 if expected == 0 { if result >= 0 { failure = 1 } }
28 else {
29 if result < 0 { failure = 1 }
30 else {
31 if cg_slen(must) > 0 { if cgot_has(out, result, must) == 0 { failure = 1 } }
32 if cg_slen(absent) > 0 { if cgot_has(out, result, absent) == 1 { failure = 1 } }
33 }
34 }
35 sys_munmap(out, n+1); sys_munmap(name, n+1); sys_munmap(dom, n+1)
36 if failure != 0 { sys_write(1, src, n); sys_write(1, "\n" as *u8, 1) }
37 return cgot_report(label, failure, counts)
38}
39
40func cgot_token(label: *u8, counts: *i64, src: *u8, kind: i64) -> i64 {
41 let n: i64 = cg_slen(src)
42 let t: *NxJsonTok = nx_json_new(src, n)
43 if (t as i64) <= 0 { return cgot_report(label, 1, counts) }
44 var failed: i64 = 0
45 if nx_json_next(t) != kind { failed = 1 }
46 if kind != NX_JSON_ERROR {
47 if t.tok_off != 0 { failed = 1 }
48 if t.tok_len != n { failed = 1 }
49 if nx_json_next(t) != NX_JSON_EOF { failed = 1 }
50 }
51 sys_munmap(t as *u8, NX_JSONTOK_BYTES)
52 if failed != 0 { sys_write(1, src, n); sys_write(1, "\n" as *u8, 1) }
53 return cgot_report(label, failed, counts)
54}
55
56func cgot_report(label: *u8, failed: i64, counts: *i64) -> i64 {
57 var passed: i64 = 0
58 if failed == 0 { passed = 1 }
59 gv_check(label, passed, counts)
60 return failed
61}
62// Optional integration mode uses the same live access file as the gateway.
63// Grammar fits the existing four-argument native process invocation.
64func cgot_project_file(argc: i64, argv: *i64) -> i64 {
65 if argc != 5 { return 2 }
66 let levelarg: *u8 = argv[4] as *u8
67 if cg_slen(levelarg) != 1 { return 2 }
68 let level: i64 = (levelarg[0] as i64) - 48
69 if level < CG_LVL_PUBLIC { return 2 }
70 if level > CG_LVL_OPERATOR { return 2 }
71 let lengths: *i64 = sys_mmap(16) as *i64
72 let source: *u8 = sys_read_file(argv[2] as *u8, lengths)
73 if (source as i64) <= 0 { return 1 }
74 let n: i64 = lengths[0]
75 if n <= 0 { return 1 }
76 let conf: *u8 = sys_read_file("knowledge/compare/access.conf" as *u8, lengths)
77 var cn: i64 = 0
78 if (conf as i64) > 0 { cn = lengths[0] }
79 let out: *u8 = sys_mmap(n+1)
80 let name: *u8 = sys_mmap(n+1)
81 let dom: *u8 = sys_mmap(n+1)
82 if (out as i64) <= 0 { return 1 }
83 if (name as i64) <= 0 { return 1 }
84 if (dom as i64) <= 0 { return 1 }
85 let result: i64 = cgo_project(source, n, level, conf, cn, out, n, name, n+1, dom, n+1)
86 if result < 0 { return 1 }
87 // Integration fixtures are private operator evidence; POSIX 0600, not a policy threshold.
88 let fd: i64 = sys_openat_wr(argv[3] as *u8, 384)
89 if fd < 0 { return 1 }
90 let written: i64 = sys_write(fd, out, result)
91 sys_close(fd)
92 if written != result { return 1 }
93 let msg: *u8 = "COMPARE-OPENAPI-FILE-PROJECTED\n" as *u8
94 sys_write(1, msg, cg_slen(msg))
95 return 0
96}
97
98func main(argc: i64, argv: *i64) -> i64 {
99 if argc > 1 {
100 if cg_streq(argv[1] as *u8, "project" as *u8) != 1 { sys_exit(2); return 2 }
101 let rc: i64 = cgot_project_file(argc, argv)
102 sys_exit(rc); return rc
103 }
104 let counts: *i64 = gv_ctr()
105 gv_head("COMPARE-OPENAPI-PROJECTION" as *u8)
106 var failures: i64 = 0
107 failures = failures + cgot_token("token-true" as *u8, counts, "true" as *u8, NX_JSON_TRUE)
108 failures = failures + cgot_token("token-false" as *u8, counts, "false" as *u8, NX_JSON_FALSE)
109 failures = failures + cgot_token("token-null" as *u8, counts, "null" as *u8, NX_JSON_NULL)
110 failures = failures + cgot_token("token-zero" as *u8, counts, "0" as *u8, NX_JSON_NUMBER)
111 failures = failures + cgot_token("token-negative-zero" as *u8, counts, "-0" as *u8, NX_JSON_NUMBER)
112 failures = failures + cgot_token("token-uppercase-exponent-precision" as *u8, counts, "1.234567890123456789E+7" as *u8, NX_JSON_NUMBER)
113 failures = failures + cgot_token("token-lowercase-exponent-precision" as *u8, counts, "-0.00001e-9" as *u8, NX_JSON_NUMBER)
114 failures = failures + cgot_token("token-beyond-i64-raw" as *u8, counts, "92233720368547758080000" as *u8, NX_JSON_NUMBER)
115 failures = failures + cgot_token("token-escaped-string" as *u8, counts, "\"a\\\"b\\n\\u0041\"" as *u8, NX_JSON_STRING)
116 failures = failures + cgot_token("token-leading-zero-refused" as *u8, counts, "01" as *u8, NX_JSON_ERROR)
117 failures = failures + cgot_token("token-empty-fraction-refused" as *u8, counts, "1." as *u8, NX_JSON_ERROR)
118 failures = failures + cgot_token("token-empty-exponent-refused" as *u8, counts, "1e+" as *u8, NX_JSON_ERROR)
119 let valid: *u8 = "{\"openapi\":\"3.1.0\",\"x-available-domains\":[\"visible\",\"synthroom\"],\"paths\":{\"/compare/{domain}/api.json\":{},\"/compare/visible/api.json\":{},\"/compare/synthroom/api.json\":{}},\"x-extra\":{\"precision\":1.234567890123456789E+7,\"flags\":[true,false,null],\"escaped\":\"a\\n\\u0041\"}}" as *u8
120 failures = failures + cgot_case("public-hidden-inventory-and-route" as *u8, counts, valid, 0, 1, "1.234567890123456789E+7" as *u8, "synthroom" as *u8, 0)
121 failures = failures + cgot_case("generic-domain-route-preserved" as *u8, counts, valid, 0, 1, "/compare/{domain}/api.json" as *u8, "synthroom" as *u8, 0)
122 failures = failures + cgot_case("owner-hidden-route-visible" as *u8, counts, valid, 3, 1, "/compare/synthroom/api.json" as *u8, "" as *u8, 0)
123 failures = failures + cgot_case("identity-truncation-refused" as *u8, counts, valid, 0, 0, "" as *u8, "" as *u8, 4)
124 failures = failures + cgot_case("empty-inventory-and-paths" as *u8, counts, "{\"openapi\":\"3.1.0\",\"x-available-domains\":[],\"paths\":{}}" as *u8, 0, 1, "\"paths\":{}" as *u8, "" as *u8, 0)
125 failures = failures + cgot_case("all-hidden-projects-empty" as *u8, counts, "{\"openapi\":\"3.1.0\",\"x-available-domains\":[\"synthroom\"],\"paths\":{\"/compare/synthroom/api.json\":{}}}" as *u8, 0, 1, "\"x-available-domains\":[]" as *u8, "synthroom" as *u8, 0)
126 failures = failures + cgot_case("array-trailing-comma-refused" as *u8, counts, "{\"openapi\":\"3.1.0\",\"x-available-domains\":[],\"paths\":{},\"bad\":[1,]}" as *u8, 0, 0, "" as *u8, "" as *u8, 0)
127 failures = failures + cgot_case("object-trailing-comma-refused" as *u8, counts, "{\"openapi\":\"3.1.0\",\"x-available-domains\":[],\"paths\":{},\"bad\":{\"a\":1,}}" as *u8, 0, 0, "" as *u8, "" as *u8, 0)
128 failures = failures + cgot_case("leading-zero-document-refused" as *u8, counts, "{\"openapi\":\"3.1.0\",\"x-available-domains\":[],\"paths\":{},\"bad\":01}" as *u8, 0, 0, "" as *u8, "" as *u8, 0)
129 failures = failures + cgot_case("empty-fraction-document-refused" as *u8, counts, "{\"openapi\":\"3.1.0\",\"x-available-domains\":[],\"paths\":{},\"bad\":1.}" as *u8, 0, 0, "" as *u8, "" as *u8, 0)
130 failures = failures + cgot_case("empty-exponent-document-refused" as *u8, counts, "{\"openapi\":\"3.1.0\",\"x-available-domains\":[],\"paths\":{},\"bad\":1E+}" as *u8, 0, 0, "" as *u8, "" as *u8, 0)
131 failures = failures + cgot_case("invalid-escape-refused" as *u8, counts, "{\"openapi\":\"3.1.0\",\"x-available-domains\":[],\"paths\":{},\"bad\":\"\\q\"}" as *u8, 0, 0, "" as *u8, "" as *u8, 0)
132 failures = failures + cgot_case("trailing-content-refused" as *u8, counts, "{\"openapi\":\"3.1.0\",\"x-available-domains\":[],\"paths\":{}} false" as *u8, 0, 0, "" as *u8, "" as *u8, 0)
133 failures = failures + cgot_case("duplicate-inventory-key-refused" as *u8, counts, "{\"openapi\":\"3.1.0\",\"x-available-domains\":[],\"x-available-domains\":[\"synthroom\"],\"paths\":{}}" as *u8, 0, 0, "" as *u8, "" as *u8, 0)
134 failures = failures + cgot_case("escaped-domain-identity-refused" as *u8, counts, "{\"openapi\":\"3.1.0\",\"x-available-domains\":[\"synth\\u0072oom\"],\"paths\":{}}" as *u8, 0, 0, "" as *u8, "" as *u8, 0)
135 failures = failures + cgot_case("escaped-route-identity-refused" as *u8, counts, "{\"openapi\":\"3.1.0\",\"x-available-domains\":[],\"paths\":{\"/compare/synth\\u0072oom/api.json\":{}}}" as *u8, 0, 0, "" as *u8, "" as *u8, 0)
136 failures = failures + cgot_case("unknown-nested-field-precision-preserved" as *u8, counts, "{\"openapi\":\"3.1.0\",\"x-available-domains\":[],\"paths\":{},\"unknown\":{\"nested\":[{\"p\":-0.00001e-9}]}}" as *u8, 0, 1, "-0.00001e-9" as *u8, "" as *u8, 0)
137 let rc: i64 = gv_verdict("COMPARE-OPENAPI-PROJECTION" as *u8, counts, "authorized domain and route projection preserves contracts and refuses malformed input" as *u8)
138 sys_exit(rc); return rc
139}