goscript 0.2.4 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -8
- package/cmd/go_js_wasm_exec/main.go +1 -1
- package/cmd/go_js_wasm_exec/main_test.go +1 -1
- package/cmd/goscript/cmd-compile.go +9 -1
- package/cmd/goscript/cmd-test.go +1 -1
- package/cmd/goscript/cmd_compile_test.go +44 -0
- package/cmd/goscript/deps.go +1 -1
- package/cmd/goscript-wasm/main.go +2 -2
- package/compiler/compile-request.go +19 -0
- package/compiler/compile_bench_test.go +121 -0
- package/compiler/compliance_test.go +17 -1
- package/compiler/config.go +2 -0
- package/compiler/gotest/result.go +1 -1
- package/compiler/gotest/runner.go +2 -2
- package/compiler/gotest/runner_test.go +4 -7
- package/compiler/index.test.ts +28 -0
- package/compiler/index.ts +32 -16
- package/compiler/lowering.go +1238 -194
- package/compiler/lowering_bench_test.go +4 -0
- package/compiler/override-facts.go +1 -1
- package/compiler/package-graph.go +92 -0
- package/compiler/package-graph_test.go +113 -0
- package/compiler/runtime-contract.go +1 -1
- package/compiler/semantic-model.go +32 -0
- package/compiler/skeleton_test.go +241 -15
- package/compiler/wasm/compile.go +1 -1
- package/compiler/wasm/compile_test.go +1 -1
- package/dist/compiler/index.d.ts +4 -0
- package/dist/compiler/index.js +26 -15
- package/dist/compiler/index.js.map +1 -1
- package/dist/gs/database/sql/driver/index.d.ts +165 -0
- package/dist/gs/database/sql/driver/index.js +432 -0
- package/dist/gs/database/sql/driver/index.js.map +1 -0
- package/dist/gs/encoding/binary/index.d.ts +71 -0
- package/dist/gs/encoding/binary/index.js +778 -0
- package/dist/gs/encoding/binary/index.js.map +1 -0
- package/dist/gs/fmt/fmt.js +156 -57
- package/dist/gs/fmt/fmt.js.map +1 -1
- package/dist/gs/github.com/klauspost/cpuid/v2/index.d.ts +11 -0
- package/dist/gs/github.com/klauspost/cpuid/v2/index.js +28 -0
- package/dist/gs/github.com/klauspost/cpuid/v2/index.js.map +1 -0
- package/dist/gs/github.com/pkg/errors/errors.d.ts +0 -2
- package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
- package/dist/gs/github.com/pkg/errors/index.d.ts +2 -1
- package/dist/gs/github.com/pkg/errors/index.js +1 -1
- package/dist/gs/github.com/pkg/errors/index.js.map +1 -1
- package/dist/gs/github.com/pkg/errors/stack.d.ts +8 -19
- package/dist/gs/github.com/pkg/errors/stack.js +26 -61
- package/dist/gs/github.com/pkg/errors/stack.js.map +1 -1
- package/dist/gs/golang.org/x/crypto/cryptobyte/asn1/index.d.ts +19 -0
- package/dist/gs/golang.org/x/crypto/cryptobyte/asn1/index.js +25 -0
- package/dist/gs/golang.org/x/crypto/cryptobyte/asn1/index.js.map +1 -0
- package/dist/gs/golang.org/x/crypto/cryptobyte/index.d.ts +104 -0
- package/dist/gs/golang.org/x/crypto/cryptobyte/index.js +1107 -0
- package/dist/gs/golang.org/x/crypto/cryptobyte/index.js.map +1 -0
- package/dist/gs/golang.org/x/crypto/internal/alias/index.d.ts +3 -0
- package/dist/gs/golang.org/x/crypto/internal/alias/index.js +39 -0
- package/dist/gs/golang.org/x/crypto/internal/alias/index.js.map +1 -0
- package/dist/gs/runtime/runtime.d.ts +6 -1
- package/dist/gs/runtime/runtime.js +15 -8
- package/dist/gs/runtime/runtime.js.map +1 -1
- package/dist/gs/runtime/trace/index.d.ts +8 -5
- package/dist/gs/runtime/trace/index.js +324 -23
- package/dist/gs/runtime/trace/index.js.map +1 -1
- package/dist/gs/slices/slices.d.ts +2 -1
- package/dist/gs/slices/slices.js +9 -3
- package/dist/gs/slices/slices.js.map +1 -1
- package/dist/gs/sort/search.gs.d.ts +3 -1
- package/dist/gs/sort/search.gs.js +18 -53
- package/dist/gs/sort/search.gs.js.map +1 -1
- package/dist/gs/sync/sync.d.ts +1 -1
- package/dist/gs/sync/sync.js +3 -0
- package/dist/gs/sync/sync.js.map +1 -1
- package/dist/gs/time/time.d.ts +22 -29
- package/dist/gs/time/time.js +111 -32
- package/dist/gs/time/time.js.map +1 -1
- package/dist/gs/unsafe/unsafe.d.ts +3 -2
- package/dist/gs/unsafe/unsafe.js.map +1 -1
- package/go.mod +7 -5
- package/go.sum +12 -26
- package/gs/database/sql/driver/index.test.ts +88 -0
- package/gs/database/sql/driver/index.ts +675 -0
- package/gs/database/sql/driver/meta.json +3 -0
- package/gs/database/sql/driver/parity.json +144 -0
- package/gs/encoding/binary/index.test.ts +239 -0
- package/gs/encoding/binary/index.ts +999 -0
- package/gs/encoding/binary/meta.json +9 -0
- package/gs/encoding/binary/parity.json +72 -0
- package/gs/fmt/fmt.test.ts +28 -0
- package/gs/fmt/fmt.ts +198 -61
- package/gs/fmt/meta.json +2 -1
- package/gs/github.com/klauspost/cpuid/v2/index.ts +38 -0
- package/gs/github.com/klauspost/cpuid/v2/meta.json +3 -0
- package/gs/github.com/pkg/errors/errors.ts +1 -2
- package/gs/github.com/pkg/errors/index.ts +2 -1
- package/gs/github.com/pkg/errors/stack.ts +34 -62
- package/gs/golang.org/x/crypto/cryptobyte/asn1/index.test.ts +19 -0
- package/gs/golang.org/x/crypto/cryptobyte/asn1/index.ts +29 -0
- package/gs/golang.org/x/crypto/cryptobyte/index.test.ts +255 -0
- package/gs/golang.org/x/crypto/cryptobyte/index.ts +1441 -0
- package/gs/golang.org/x/crypto/cryptobyte/meta.json +3 -0
- package/gs/golang.org/x/crypto/internal/alias/index.test.ts +40 -0
- package/gs/golang.org/x/crypto/internal/alias/index.ts +40 -0
- package/gs/runtime/runtime.test.ts +16 -0
- package/gs/runtime/runtime.ts +17 -9
- package/gs/runtime/trace/index.test.ts +113 -14
- package/gs/runtime/trace/index.ts +384 -34
- package/gs/runtime/trace/meta.json +1 -0
- package/gs/slices/slices.test.ts +24 -1
- package/gs/slices/slices.ts +14 -4
- package/gs/sort/meta.json +1 -0
- package/gs/sort/search.gs.ts +20 -5
- package/gs/sync/sync.ts +4 -1
- package/gs/time/time.test.ts +79 -2
- package/gs/time/time.ts +133 -33
- package/gs/unsafe/unsafe.ts +4 -2
- package/package.json +2 -2
|
@@ -0,0 +1,1107 @@
|
|
|
1
|
+
import * as $ from '@goscript/builtin/index.js';
|
|
2
|
+
import * as asn1 from '@goscript/golang.org/x/crypto/cryptobyte/asn1/index.js';
|
|
3
|
+
import * as time from '@goscript/time/index.js';
|
|
4
|
+
const maxUint64 = (1n << 64n) - 1n;
|
|
5
|
+
const maxInt64 = (1n << 63n) - 1n;
|
|
6
|
+
const minInt64 = -(1n << 63n);
|
|
7
|
+
function byte(value) {
|
|
8
|
+
if (typeof value === 'bigint') {
|
|
9
|
+
return Number(BigInt.asUintN(8, value));
|
|
10
|
+
}
|
|
11
|
+
return Number(value) & 0xff;
|
|
12
|
+
}
|
|
13
|
+
function bytesArray(bytes) {
|
|
14
|
+
if (bytes == null) {
|
|
15
|
+
return [];
|
|
16
|
+
}
|
|
17
|
+
if (typeof bytes === 'string') {
|
|
18
|
+
return Array.from(bytes, (ch) => ch.charCodeAt(0) & 0xff);
|
|
19
|
+
}
|
|
20
|
+
return Array.from($.bytesToUint8Array(bytes));
|
|
21
|
+
}
|
|
22
|
+
function bytesFromArray(bytes) {
|
|
23
|
+
return new Uint8Array(bytes.map(byte));
|
|
24
|
+
}
|
|
25
|
+
function bytesFromString(value) {
|
|
26
|
+
return new Uint8Array(Array.from(value, (ch) => ch.charCodeAt(0) & 0xff));
|
|
27
|
+
}
|
|
28
|
+
function bytesToAscii(bytes) {
|
|
29
|
+
return globalThis.String.fromCharCode(...bytesArray(bytes));
|
|
30
|
+
}
|
|
31
|
+
function stringValue(s) {
|
|
32
|
+
if (s == null) {
|
|
33
|
+
throw new Error('runtime error: invalid memory address or nil pointer dereference');
|
|
34
|
+
}
|
|
35
|
+
return s.value;
|
|
36
|
+
}
|
|
37
|
+
function read(s, n) {
|
|
38
|
+
const data = stringValue(s);
|
|
39
|
+
if ($.len(data) < n) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
const out = $.goSlice(data, 0, n);
|
|
43
|
+
s.value = $.goSlice(data, n);
|
|
44
|
+
return out;
|
|
45
|
+
}
|
|
46
|
+
function readUint(bytes) {
|
|
47
|
+
let out = 0;
|
|
48
|
+
for (const b of bytesArray(bytes)) {
|
|
49
|
+
out = out * 256 + b;
|
|
50
|
+
}
|
|
51
|
+
return out;
|
|
52
|
+
}
|
|
53
|
+
function readUint64Value(bytes) {
|
|
54
|
+
let out = 0n;
|
|
55
|
+
for (const b of bytesArray(bytes)) {
|
|
56
|
+
out = (out << 8n) | BigInt(b);
|
|
57
|
+
}
|
|
58
|
+
return $.uint(out, 64);
|
|
59
|
+
}
|
|
60
|
+
function writeRef(out, value) {
|
|
61
|
+
if (out == null) {
|
|
62
|
+
throw new Error('runtime error: invalid memory address or nil pointer dereference');
|
|
63
|
+
}
|
|
64
|
+
out.value = value;
|
|
65
|
+
}
|
|
66
|
+
export function String_Skip(s, n) {
|
|
67
|
+
return read(s, n) !== null;
|
|
68
|
+
}
|
|
69
|
+
export function String_ReadUint8(s, out) {
|
|
70
|
+
const v = read(s, 1);
|
|
71
|
+
if (v == null) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
writeRef(out, bytesArray(v)[0]);
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
export function String_ReadUint16(s, out) {
|
|
78
|
+
const v = read(s, 2);
|
|
79
|
+
if (v == null) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
writeRef(out, readUint(v));
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
export function String_ReadUint24(s, out) {
|
|
86
|
+
const v = read(s, 3);
|
|
87
|
+
if (v == null) {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
writeRef(out, readUint(v));
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
export function String_ReadUint32(s, out) {
|
|
94
|
+
const v = read(s, 4);
|
|
95
|
+
if (v == null) {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
writeRef(out, $.uint(readUint(v), 32));
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
export function String_ReadUint48(s, out) {
|
|
102
|
+
const v = read(s, 6);
|
|
103
|
+
if (v == null) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
writeRef(out, readUint(v));
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
export function String_ReadUint64(s, out) {
|
|
110
|
+
const v = read(s, 8);
|
|
111
|
+
if (v == null) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
writeRef(out, readUint64Value(v));
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
function readLengthPrefixed(s, lenLen, out) {
|
|
118
|
+
const data = stringValue(s);
|
|
119
|
+
if ($.len(data) < lenLen) {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
const length = readUint($.goSlice(data, 0, lenLen));
|
|
123
|
+
if ($.len(data) < lenLen + length) {
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
writeRef(out, $.goSlice(data, lenLen, lenLen + length));
|
|
127
|
+
s.value = $.goSlice(data, lenLen + length);
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
export function String_ReadUint8LengthPrefixed(s, out) {
|
|
131
|
+
return readLengthPrefixed(s, 1, out);
|
|
132
|
+
}
|
|
133
|
+
export function String_ReadUint16LengthPrefixed(s, out) {
|
|
134
|
+
return readLengthPrefixed(s, 2, out);
|
|
135
|
+
}
|
|
136
|
+
export function String_ReadUint24LengthPrefixed(s, out) {
|
|
137
|
+
return readLengthPrefixed(s, 3, out);
|
|
138
|
+
}
|
|
139
|
+
export function String_ReadBytes(s, out, n) {
|
|
140
|
+
const v = read(s, n);
|
|
141
|
+
if (v == null) {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
writeRef(out, v);
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
export function String_CopyBytes(s, out) {
|
|
148
|
+
if ($.len(out) > $.len(stringValue(s))) {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
const v = read(s, $.len(out));
|
|
152
|
+
if (v == null) {
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
$.copy(out, v);
|
|
156
|
+
return true;
|
|
157
|
+
}
|
|
158
|
+
export function String_Empty(s) {
|
|
159
|
+
return $.len(s) === 0;
|
|
160
|
+
}
|
|
161
|
+
export class BuildError {
|
|
162
|
+
Err;
|
|
163
|
+
constructor(init) {
|
|
164
|
+
this.Err = init?.Err ?? null;
|
|
165
|
+
}
|
|
166
|
+
Error() {
|
|
167
|
+
return this.Err == null ? '' : this.Err.Error();
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
export class Builder {
|
|
171
|
+
err;
|
|
172
|
+
result;
|
|
173
|
+
fixedSize;
|
|
174
|
+
capacityLimit;
|
|
175
|
+
child;
|
|
176
|
+
offset;
|
|
177
|
+
pendingLenLen;
|
|
178
|
+
pendingIsASN1;
|
|
179
|
+
constructor(init) {
|
|
180
|
+
this.err = init?.err ?? null;
|
|
181
|
+
this.result = init?.resultArray ?? bytesArray(init?.result);
|
|
182
|
+
this.fixedSize = init?.fixedSize ?? false;
|
|
183
|
+
this.capacityLimit =
|
|
184
|
+
init?.capacityLimit ?? (init?.result == null ? this.result.length : $.cap(init.result));
|
|
185
|
+
this.child = null;
|
|
186
|
+
this.offset = 0;
|
|
187
|
+
this.pendingLenLen = 0;
|
|
188
|
+
this.pendingIsASN1 = false;
|
|
189
|
+
}
|
|
190
|
+
SetError(err) {
|
|
191
|
+
if (this.err == null) {
|
|
192
|
+
this.err = err;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
Bytes() {
|
|
196
|
+
this.flushChild();
|
|
197
|
+
if (this.err != null) {
|
|
198
|
+
return [null, this.err];
|
|
199
|
+
}
|
|
200
|
+
if (this.fixedSize && this.result.length !== this.capacityLimit) {
|
|
201
|
+
return [null, $.newError('cryptobyte: Builder is not full')];
|
|
202
|
+
}
|
|
203
|
+
return [bytesFromArray(this.result), null];
|
|
204
|
+
}
|
|
205
|
+
BytesOrPanic() {
|
|
206
|
+
const [bytes, err] = this.Bytes();
|
|
207
|
+
if (err != null) {
|
|
208
|
+
$.panic(new BuildError({ Err: err }));
|
|
209
|
+
}
|
|
210
|
+
return bytes;
|
|
211
|
+
}
|
|
212
|
+
AddUint8(v) {
|
|
213
|
+
this.add(byte(v));
|
|
214
|
+
}
|
|
215
|
+
AddUint16(v) {
|
|
216
|
+
this.add(byte(v >> 8), byte(v));
|
|
217
|
+
}
|
|
218
|
+
AddUint24(v) {
|
|
219
|
+
this.add(byte(v >> 16), byte(v >> 8), byte(v));
|
|
220
|
+
}
|
|
221
|
+
AddUint32(v) {
|
|
222
|
+
this.add(byte(v / 0x1000000), byte(v >> 16), byte(v >> 8), byte(v));
|
|
223
|
+
}
|
|
224
|
+
AddUint48(v) {
|
|
225
|
+
this.add(byte(Math.floor(v / 0x10000000000)), byte(Math.floor(v / 0x100000000)), byte(v >> 24), byte(v >> 16), byte(v >> 8), byte(v));
|
|
226
|
+
}
|
|
227
|
+
AddUint64(v) {
|
|
228
|
+
let value = toUint64BigInt(v);
|
|
229
|
+
const out = new Array(8);
|
|
230
|
+
for (let i = 7; i >= 0; i--) {
|
|
231
|
+
out[i] = byte(value);
|
|
232
|
+
value >>= 8n;
|
|
233
|
+
}
|
|
234
|
+
this.add(...out);
|
|
235
|
+
}
|
|
236
|
+
AddBytes(v) {
|
|
237
|
+
this.add(...bytesArray(v));
|
|
238
|
+
}
|
|
239
|
+
AddUint8LengthPrefixed(f) {
|
|
240
|
+
this.addLengthPrefixed(1, false, f);
|
|
241
|
+
}
|
|
242
|
+
AddUint16LengthPrefixed(f) {
|
|
243
|
+
this.addLengthPrefixed(2, false, f);
|
|
244
|
+
}
|
|
245
|
+
AddUint24LengthPrefixed(f) {
|
|
246
|
+
this.addLengthPrefixed(3, false, f);
|
|
247
|
+
}
|
|
248
|
+
AddUint32LengthPrefixed(f) {
|
|
249
|
+
this.addLengthPrefixed(4, false, f);
|
|
250
|
+
}
|
|
251
|
+
AddValue(v) {
|
|
252
|
+
if (v == null) {
|
|
253
|
+
this.SetError($.newError('cryptobyte: nil MarshalingValue'));
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
this.SetError(v.Marshal(this));
|
|
257
|
+
}
|
|
258
|
+
Unwrite(n) {
|
|
259
|
+
this.flushChild();
|
|
260
|
+
if (this.err != null) {
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
if (n < 0 || n > this.result.length) {
|
|
264
|
+
this.SetError($.newError('cryptobyte: invalid Unwrite'));
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
this.result.length -= n;
|
|
268
|
+
}
|
|
269
|
+
AddASN1Int64(v) {
|
|
270
|
+
this.AddASN1Int64WithTag(v, asn1.INTEGER);
|
|
271
|
+
}
|
|
272
|
+
AddASN1Int64WithTag(v, tag) {
|
|
273
|
+
this.addASN1Signed(BigInt(Math.trunc(v)), tag);
|
|
274
|
+
}
|
|
275
|
+
AddASN1Enum(v) {
|
|
276
|
+
this.addASN1Signed(BigInt(Math.trunc(v)), asn1.ENUM);
|
|
277
|
+
}
|
|
278
|
+
AddASN1Uint64(v) {
|
|
279
|
+
this.AddASN1(asn1.INTEGER, (child) => {
|
|
280
|
+
child.add(...encodeASN1Unsigned(toUint64BigInt(v)));
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
AddASN1BigInt(n) {
|
|
284
|
+
const value = bigIntValue(n);
|
|
285
|
+
this.AddASN1(asn1.INTEGER, (child) => {
|
|
286
|
+
child.add(...encodeASN1Signed(value));
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
AddASN1OctetString(bytes) {
|
|
290
|
+
this.AddASN1(asn1.OCTET_STRING, (child) => {
|
|
291
|
+
child.AddBytes(bytes);
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
AddASN1GeneralizedTime(t) {
|
|
295
|
+
const value = $.pointerValue(t);
|
|
296
|
+
this.AddASN1(asn1.GeneralizedTime, (child) => {
|
|
297
|
+
child.AddBytes(bytesFromString(value.Format('20060102150405Z0700')));
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
AddASN1UTCTime(t) {
|
|
301
|
+
const value = $.pointerValue(t);
|
|
302
|
+
this.AddASN1(asn1.UTCTime, (child) => {
|
|
303
|
+
child.AddBytes(bytesFromString(value.Format('060102150405Z0700')));
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
AddASN1BitString(bitString) {
|
|
307
|
+
const value = pointerValueOrBox(bitString);
|
|
308
|
+
if (value == null) {
|
|
309
|
+
this.SetError($.newError('cryptobyte: nil BitString'));
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
const bytes = value.Bytes ?? null;
|
|
313
|
+
const bitLength = Math.trunc(value.BitLength ?? 0);
|
|
314
|
+
const paddingBits = (8 - (bitLength % 8)) % 8;
|
|
315
|
+
if ((bytes == null && bitLength !== 0) ||
|
|
316
|
+
$.len(bytes) * 8 - paddingBits !== bitLength) {
|
|
317
|
+
this.SetError($.newError('cryptobyte: invalid BitString'));
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
this.AddASN1(asn1.BIT_STRING, (child) => {
|
|
321
|
+
child.AddUint8(paddingBits);
|
|
322
|
+
child.AddBytes(bytes ?? new Uint8Array(0));
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
AddASN1ObjectIdentifier(oid) {
|
|
326
|
+
if (oid == null || $.len(oid) < 2) {
|
|
327
|
+
this.SetError($.newError('cryptobyte: invalid OID'));
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
const first = Number(oid[0]);
|
|
331
|
+
const second = Number(oid[1]);
|
|
332
|
+
if (first > 2 || second >= 40 && first < 2) {
|
|
333
|
+
this.SetError($.newError('cryptobyte: invalid OID'));
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
this.AddASN1(asn1.OBJECT_IDENTIFIER, (child) => {
|
|
337
|
+
child.addBase128Int(first * 40 + second);
|
|
338
|
+
for (let i = 2; i < $.len(oid); i++) {
|
|
339
|
+
child.addBase128Int(Number(oid[i]));
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
AddASN1Boolean(v) {
|
|
344
|
+
this.AddASN1(asn1.BOOLEAN, (child) => {
|
|
345
|
+
child.AddUint8(v ? 0xff : 0);
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
AddASN1NULL() {
|
|
349
|
+
this.add(asn1.NULL, 0);
|
|
350
|
+
}
|
|
351
|
+
MarshalASN1(_v) {
|
|
352
|
+
this.SetError($.newError('cryptobyte: MarshalASN1 is not supported in the js build'));
|
|
353
|
+
}
|
|
354
|
+
AddASN1(tag, f) {
|
|
355
|
+
this.add(byte(tag));
|
|
356
|
+
this.addLengthPrefixed(1, true, f);
|
|
357
|
+
}
|
|
358
|
+
addASN1Signed(v, tag) {
|
|
359
|
+
this.AddASN1(tag, (child) => {
|
|
360
|
+
child.add(...encodeASN1Signed(v));
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
addBase128Int(v) {
|
|
364
|
+
if (v < 0) {
|
|
365
|
+
this.SetError($.newError('cryptobyte: negative OID component'));
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
const out = [byte(v)];
|
|
369
|
+
v = Math.floor(v / 128);
|
|
370
|
+
while (v > 0) {
|
|
371
|
+
out.unshift(byte(v) | 0x80);
|
|
372
|
+
v = Math.floor(v / 128);
|
|
373
|
+
}
|
|
374
|
+
this.add(...out);
|
|
375
|
+
}
|
|
376
|
+
addLengthPrefixed(lenLen, isASN1, f) {
|
|
377
|
+
this.flushChild();
|
|
378
|
+
if (this.err != null) {
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
this.offset = this.result.length;
|
|
382
|
+
this.pendingLenLen = lenLen;
|
|
383
|
+
this.pendingIsASN1 = isASN1;
|
|
384
|
+
this.add(...new Array(lenLen).fill(0));
|
|
385
|
+
const child = new Builder({
|
|
386
|
+
err: this.err,
|
|
387
|
+
resultArray: this.result,
|
|
388
|
+
fixedSize: this.fixedSize,
|
|
389
|
+
capacityLimit: this.capacityLimit,
|
|
390
|
+
});
|
|
391
|
+
this.child = child;
|
|
392
|
+
try {
|
|
393
|
+
f?.(child);
|
|
394
|
+
}
|
|
395
|
+
catch (err) {
|
|
396
|
+
const value = $.panicValue(err);
|
|
397
|
+
if (value instanceof BuildError) {
|
|
398
|
+
this.SetError(value.Err);
|
|
399
|
+
}
|
|
400
|
+
else {
|
|
401
|
+
throw err;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
if (this.child === child) {
|
|
405
|
+
this.flushChild();
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
flushChild() {
|
|
409
|
+
if (this.child == null) {
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
if (this.err == null && this.child.err != null) {
|
|
413
|
+
this.err = this.child.err;
|
|
414
|
+
}
|
|
415
|
+
const offset = this.offset;
|
|
416
|
+
const lenLen = this.pendingLenLen;
|
|
417
|
+
const childStart = offset + lenLen;
|
|
418
|
+
const length = this.result.length - childStart;
|
|
419
|
+
if (this.err == null) {
|
|
420
|
+
if (this.pendingIsASN1) {
|
|
421
|
+
this.flushASN1Length(offset, length);
|
|
422
|
+
}
|
|
423
|
+
else {
|
|
424
|
+
const max = 1n << BigInt(lenLen * 8);
|
|
425
|
+
if (BigInt(length) >= max) {
|
|
426
|
+
this.SetError($.newError('cryptobyte: length prefix overflow'));
|
|
427
|
+
}
|
|
428
|
+
else {
|
|
429
|
+
for (let i = lenLen - 1, value = length; i >= 0; i--) {
|
|
430
|
+
this.result[offset + i] = byte(value);
|
|
431
|
+
value = Math.floor(value / 256);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
this.child = null;
|
|
437
|
+
}
|
|
438
|
+
flushASN1Length(offset, length) {
|
|
439
|
+
if (length <= 127) {
|
|
440
|
+
this.result[offset] = length;
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
const encoded = encodeASN1Length(length);
|
|
444
|
+
const extra = encoded.length - 1;
|
|
445
|
+
this.result.push(...new Array(extra).fill(0));
|
|
446
|
+
for (let i = this.result.length - extra - 1; i > offset; i--) {
|
|
447
|
+
this.result[i + extra] = this.result[i];
|
|
448
|
+
}
|
|
449
|
+
for (let i = 0; i < encoded.length; i++) {
|
|
450
|
+
this.result[offset + i] = encoded[i];
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
add(...bytes) {
|
|
454
|
+
this.flushChild();
|
|
455
|
+
if (this.err != null) {
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
if (this.fixedSize && this.result.length + bytes.length > this.capacityLimit) {
|
|
459
|
+
this.SetError($.newError('cryptobyte: Builder is exceeding its fixed-size buffer'));
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
this.result.push(...bytes.map(byte));
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
export function NewBuilder(buffer) {
|
|
466
|
+
return new Builder({ result: buffer ?? new Uint8Array(0), fixedSize: false });
|
|
467
|
+
}
|
|
468
|
+
export function NewFixedBuilder(buffer) {
|
|
469
|
+
return new Builder({
|
|
470
|
+
result: new Uint8Array(0),
|
|
471
|
+
fixedSize: true,
|
|
472
|
+
capacityLimit: $.cap(buffer),
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
function encodeASN1Length(length) {
|
|
476
|
+
if (length <= 127) {
|
|
477
|
+
return [length];
|
|
478
|
+
}
|
|
479
|
+
const out = [];
|
|
480
|
+
let value = length;
|
|
481
|
+
while (value > 0) {
|
|
482
|
+
out.unshift(byte(value));
|
|
483
|
+
value = Math.floor(value / 256);
|
|
484
|
+
}
|
|
485
|
+
return [0x80 | out.length, ...out];
|
|
486
|
+
}
|
|
487
|
+
function encodeASN1Unsigned(value) {
|
|
488
|
+
if (value < 0n || value > maxUint64) {
|
|
489
|
+
return [];
|
|
490
|
+
}
|
|
491
|
+
const out = unsignedBytes(value);
|
|
492
|
+
if (out.length === 0) {
|
|
493
|
+
return [0];
|
|
494
|
+
}
|
|
495
|
+
if ((out[0] & 0x80) !== 0) {
|
|
496
|
+
out.unshift(0);
|
|
497
|
+
}
|
|
498
|
+
return out;
|
|
499
|
+
}
|
|
500
|
+
function encodeASN1Signed(value) {
|
|
501
|
+
if (value >= 0n) {
|
|
502
|
+
const out = unsignedBytes(value);
|
|
503
|
+
if (out.length === 0) {
|
|
504
|
+
return [0];
|
|
505
|
+
}
|
|
506
|
+
if ((out[0] & 0x80) !== 0) {
|
|
507
|
+
out.unshift(0);
|
|
508
|
+
}
|
|
509
|
+
return out;
|
|
510
|
+
}
|
|
511
|
+
let byteLen = 1;
|
|
512
|
+
while (value < -(1n << BigInt(byteLen * 8 - 1))) {
|
|
513
|
+
byteLen++;
|
|
514
|
+
}
|
|
515
|
+
const mod = 1n << BigInt(byteLen * 8);
|
|
516
|
+
return fixedUnsignedBytes(mod + value, byteLen);
|
|
517
|
+
}
|
|
518
|
+
function unsignedBytes(value) {
|
|
519
|
+
if (value === 0n) {
|
|
520
|
+
return [];
|
|
521
|
+
}
|
|
522
|
+
const out = [];
|
|
523
|
+
while (value > 0n) {
|
|
524
|
+
out.unshift(byte(value));
|
|
525
|
+
value >>= 8n;
|
|
526
|
+
}
|
|
527
|
+
return out;
|
|
528
|
+
}
|
|
529
|
+
function fixedUnsignedBytes(value, byteLen) {
|
|
530
|
+
const out = new Array(byteLen);
|
|
531
|
+
for (let i = byteLen - 1; i >= 0; i--) {
|
|
532
|
+
out[i] = byte(value);
|
|
533
|
+
value >>= 8n;
|
|
534
|
+
}
|
|
535
|
+
return out;
|
|
536
|
+
}
|
|
537
|
+
function toUint64BigInt(value) {
|
|
538
|
+
if (typeof value === 'bigint') {
|
|
539
|
+
return BigInt.asUintN(64, value);
|
|
540
|
+
}
|
|
541
|
+
if (Number.isSafeInteger(value) && value >= 0) {
|
|
542
|
+
return BigInt(value);
|
|
543
|
+
}
|
|
544
|
+
return BigInt.asUintN(64, BigInt(Math.trunc(value)));
|
|
545
|
+
}
|
|
546
|
+
function signedBigInt(bytes) {
|
|
547
|
+
const arr = bytesArray(bytes);
|
|
548
|
+
let value = 0n;
|
|
549
|
+
for (const b of arr) {
|
|
550
|
+
value = (value << 8n) | BigInt(b);
|
|
551
|
+
}
|
|
552
|
+
if (arr.length > 0 && (arr[0] & 0x80) !== 0) {
|
|
553
|
+
value -= 1n << BigInt(arr.length * 8);
|
|
554
|
+
}
|
|
555
|
+
return value;
|
|
556
|
+
}
|
|
557
|
+
function unsignedBigInt(bytes) {
|
|
558
|
+
let value = 0n;
|
|
559
|
+
for (const b of bytesArray(bytes)) {
|
|
560
|
+
value = (value << 8n) | BigInt(b);
|
|
561
|
+
}
|
|
562
|
+
return value;
|
|
563
|
+
}
|
|
564
|
+
function checkASN1Integer(bytes) {
|
|
565
|
+
const arr = bytesArray(bytes);
|
|
566
|
+
if (arr.length === 0) {
|
|
567
|
+
return false;
|
|
568
|
+
}
|
|
569
|
+
if (arr.length === 1) {
|
|
570
|
+
return true;
|
|
571
|
+
}
|
|
572
|
+
if (arr[0] === 0 && (arr[1] & 0x80) === 0) {
|
|
573
|
+
return false;
|
|
574
|
+
}
|
|
575
|
+
if (arr[0] === 0xff && (arr[1] & 0x80) === 0x80) {
|
|
576
|
+
return false;
|
|
577
|
+
}
|
|
578
|
+
return true;
|
|
579
|
+
}
|
|
580
|
+
function boxedTypeName(value) {
|
|
581
|
+
if (value !== null && typeof value === 'object' && '__goType' in value) {
|
|
582
|
+
return globalThis.String(value.__goType ?? '');
|
|
583
|
+
}
|
|
584
|
+
return '';
|
|
585
|
+
}
|
|
586
|
+
function boxedValue(value) {
|
|
587
|
+
if (value !== null && typeof value === 'object' && '__goValue' in value) {
|
|
588
|
+
return value.__goValue;
|
|
589
|
+
}
|
|
590
|
+
return value;
|
|
591
|
+
}
|
|
592
|
+
function writeTarget(out) {
|
|
593
|
+
const typeName = boxedTypeName(out);
|
|
594
|
+
const value = boxedValue(out);
|
|
595
|
+
if ($.isVarRef(value)) {
|
|
596
|
+
return { typeName, ref: value, value: value.value };
|
|
597
|
+
}
|
|
598
|
+
if ($.isVarRef(out)) {
|
|
599
|
+
return { typeName, ref: out, value: out.value };
|
|
600
|
+
}
|
|
601
|
+
return { typeName, ref: null, value };
|
|
602
|
+
}
|
|
603
|
+
function pointerValueOrBox(value) {
|
|
604
|
+
const raw = boxedValue(value);
|
|
605
|
+
if ($.isVarRef(raw)) {
|
|
606
|
+
return raw.value;
|
|
607
|
+
}
|
|
608
|
+
return raw;
|
|
609
|
+
}
|
|
610
|
+
function isBigIntType(target) {
|
|
611
|
+
const typeName = target.typeName.replace(/^\*/, '');
|
|
612
|
+
const value = pointerValueOrBox(target.value);
|
|
613
|
+
return (typeName === 'big.Int' ||
|
|
614
|
+
typeName === 'math/big.Int' ||
|
|
615
|
+
(value !== null &&
|
|
616
|
+
typeof value === 'object' &&
|
|
617
|
+
typeof value.SetBytes === 'function' &&
|
|
618
|
+
typeof value.Sign === 'function'));
|
|
619
|
+
}
|
|
620
|
+
function integerKind(typeName) {
|
|
621
|
+
return typeName.replace(/^\*/, '');
|
|
622
|
+
}
|
|
623
|
+
function writeInteger(target, value) {
|
|
624
|
+
const kind = integerKind(target.typeName);
|
|
625
|
+
if (isBigIntType(target)) {
|
|
626
|
+
setBigIntObject(pointerValueOrBox(target.value), value);
|
|
627
|
+
return;
|
|
628
|
+
}
|
|
629
|
+
if (target.ref == null) {
|
|
630
|
+
$.panic('out does not point to an integer type');
|
|
631
|
+
}
|
|
632
|
+
switch (kind) {
|
|
633
|
+
case '':
|
|
634
|
+
case 'int':
|
|
635
|
+
case 'int64':
|
|
636
|
+
if (value < minInt64 || value > maxInt64) {
|
|
637
|
+
throw $.newError('cryptobyte: integer overflow');
|
|
638
|
+
}
|
|
639
|
+
target.ref.value = $.int(value, 64);
|
|
640
|
+
return;
|
|
641
|
+
case 'int8':
|
|
642
|
+
if (value < -128n || value > 127n) {
|
|
643
|
+
throw $.newError('cryptobyte: integer overflow');
|
|
644
|
+
}
|
|
645
|
+
target.ref.value = $.int(value, 8);
|
|
646
|
+
return;
|
|
647
|
+
case 'int16':
|
|
648
|
+
if (value < -32768n || value > 32767n) {
|
|
649
|
+
throw $.newError('cryptobyte: integer overflow');
|
|
650
|
+
}
|
|
651
|
+
target.ref.value = $.int(value, 16);
|
|
652
|
+
return;
|
|
653
|
+
case 'int32':
|
|
654
|
+
if (value < -2147483648n || value > 2147483647n) {
|
|
655
|
+
throw $.newError('cryptobyte: integer overflow');
|
|
656
|
+
}
|
|
657
|
+
target.ref.value = $.int(value, 32);
|
|
658
|
+
return;
|
|
659
|
+
case 'uint':
|
|
660
|
+
case 'uint64':
|
|
661
|
+
case 'uintptr':
|
|
662
|
+
if (value < 0n || value > maxUint64) {
|
|
663
|
+
throw $.newError('cryptobyte: integer overflow');
|
|
664
|
+
}
|
|
665
|
+
target.ref.value = $.uint(value, 64);
|
|
666
|
+
return;
|
|
667
|
+
case 'uint8':
|
|
668
|
+
case 'byte':
|
|
669
|
+
if (value < 0n || value > 255n) {
|
|
670
|
+
throw $.newError('cryptobyte: integer overflow');
|
|
671
|
+
}
|
|
672
|
+
target.ref.value = $.uint(value, 8);
|
|
673
|
+
return;
|
|
674
|
+
case 'uint16':
|
|
675
|
+
if (value < 0n || value > 65535n) {
|
|
676
|
+
throw $.newError('cryptobyte: integer overflow');
|
|
677
|
+
}
|
|
678
|
+
target.ref.value = $.uint(value, 16);
|
|
679
|
+
return;
|
|
680
|
+
case 'uint32':
|
|
681
|
+
if (value < 0n || value > 4294967295n) {
|
|
682
|
+
throw $.newError('cryptobyte: integer overflow');
|
|
683
|
+
}
|
|
684
|
+
target.ref.value = $.uint(value, 32);
|
|
685
|
+
return;
|
|
686
|
+
default:
|
|
687
|
+
throw $.newError('cryptobyte: ReadASN1Integer of a named integer type is not supported in the js build');
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
function integerDefaultValue(defaultValue) {
|
|
691
|
+
const raw = boxedValue(defaultValue);
|
|
692
|
+
if (typeof raw === 'bigint') {
|
|
693
|
+
return raw;
|
|
694
|
+
}
|
|
695
|
+
if (typeof raw === 'number' && Number.isFinite(raw)) {
|
|
696
|
+
return BigInt(Math.trunc(raw));
|
|
697
|
+
}
|
|
698
|
+
if (raw !== null && typeof raw === 'object') {
|
|
699
|
+
return bigIntValue(raw);
|
|
700
|
+
}
|
|
701
|
+
throw $.newError('cryptobyte: ReadOptionalASN1Integer default of a named integer type is not supported in the js build');
|
|
702
|
+
}
|
|
703
|
+
function setBigIntObject(target, value) {
|
|
704
|
+
if (target == null || typeof target !== 'object') {
|
|
705
|
+
$.panic('out does not point to an integer type');
|
|
706
|
+
}
|
|
707
|
+
const big = target;
|
|
708
|
+
if ('value' in big) {
|
|
709
|
+
big.value = value;
|
|
710
|
+
return;
|
|
711
|
+
}
|
|
712
|
+
const magnitude = bytesFromArray(unsignedBytes(value < 0n ? -value : value));
|
|
713
|
+
if (typeof big.SetBytes === 'function') {
|
|
714
|
+
big.SetBytes(magnitude);
|
|
715
|
+
if (value < 0n) {
|
|
716
|
+
if (typeof big.Neg !== 'function') {
|
|
717
|
+
throw $.newError('cryptobyte: big.Int negative assignment is not supported in the js build');
|
|
718
|
+
}
|
|
719
|
+
big.Neg(big);
|
|
720
|
+
}
|
|
721
|
+
return;
|
|
722
|
+
}
|
|
723
|
+
if (typeof big.SetInt64 === 'function') {
|
|
724
|
+
big.SetInt64(Number(value));
|
|
725
|
+
return;
|
|
726
|
+
}
|
|
727
|
+
throw $.newError('cryptobyte: unsupported big.Int representation');
|
|
728
|
+
}
|
|
729
|
+
function bigIntValue(value) {
|
|
730
|
+
const raw = pointerValueOrBox(value);
|
|
731
|
+
if (typeof raw === 'bigint') {
|
|
732
|
+
return raw;
|
|
733
|
+
}
|
|
734
|
+
if (typeof raw === 'number') {
|
|
735
|
+
return BigInt(Math.trunc(raw));
|
|
736
|
+
}
|
|
737
|
+
if (raw !== null && typeof raw === 'object') {
|
|
738
|
+
const big = raw;
|
|
739
|
+
if (typeof big.value === 'bigint') {
|
|
740
|
+
return big.value;
|
|
741
|
+
}
|
|
742
|
+
if (typeof big.value === 'number') {
|
|
743
|
+
return BigInt(Math.trunc(big.value));
|
|
744
|
+
}
|
|
745
|
+
if (typeof big.Sign === 'function' && typeof big.Bytes === 'function') {
|
|
746
|
+
const sign = big.Sign();
|
|
747
|
+
const mag = unsignedBigInt(big.Bytes());
|
|
748
|
+
return sign < 0 ? -mag : mag;
|
|
749
|
+
}
|
|
750
|
+
if (typeof big.String === 'function') {
|
|
751
|
+
return BigInt(big.String());
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
throw $.newError('cryptobyte: unsupported big.Int representation');
|
|
755
|
+
}
|
|
756
|
+
function readASN1Bytes(s, tag) {
|
|
757
|
+
const bytes = $.varRef(new Uint8Array(0));
|
|
758
|
+
if (!String_ReadASN1(s, bytes, tag)) {
|
|
759
|
+
return null;
|
|
760
|
+
}
|
|
761
|
+
return bytes.value;
|
|
762
|
+
}
|
|
763
|
+
function readASN1SignedInteger(s, tag) {
|
|
764
|
+
const bytes = readASN1Bytes(s, tag);
|
|
765
|
+
if (bytes == null || !checkASN1Integer(bytes)) {
|
|
766
|
+
return null;
|
|
767
|
+
}
|
|
768
|
+
return signedBigInt(bytes);
|
|
769
|
+
}
|
|
770
|
+
export function String_ReadASN1Boolean(s, out) {
|
|
771
|
+
const bytes = readASN1Bytes(s, asn1.BOOLEAN);
|
|
772
|
+
const arr = bytesArray(bytes);
|
|
773
|
+
if (bytes == null || arr.length !== 1 || (arr[0] !== 0 && arr[0] !== 0xff)) {
|
|
774
|
+
return false;
|
|
775
|
+
}
|
|
776
|
+
writeRef(out, arr[0] === 0xff);
|
|
777
|
+
return true;
|
|
778
|
+
}
|
|
779
|
+
export function String_ReadASN1Integer(s, out) {
|
|
780
|
+
const target = writeTarget(out);
|
|
781
|
+
const bytes = readASN1Bytes(s, asn1.INTEGER);
|
|
782
|
+
if (bytes == null || !checkASN1Integer(bytes)) {
|
|
783
|
+
return false;
|
|
784
|
+
}
|
|
785
|
+
const value = signedBigInt(bytes);
|
|
786
|
+
writeInteger(target, value);
|
|
787
|
+
return true;
|
|
788
|
+
}
|
|
789
|
+
export function String_ReadASN1Int64WithTag(s, out, tag) {
|
|
790
|
+
const value = readASN1SignedInteger(s, tag);
|
|
791
|
+
if (value == null || value < minInt64 || value > maxInt64) {
|
|
792
|
+
return false;
|
|
793
|
+
}
|
|
794
|
+
writeRef(out, $.int(value, 64));
|
|
795
|
+
return true;
|
|
796
|
+
}
|
|
797
|
+
export function String_ReadASN1Enum(s, out) {
|
|
798
|
+
const value = readASN1SignedInteger(s, asn1.ENUM);
|
|
799
|
+
if (value == null || value < minInt64 || value > maxInt64) {
|
|
800
|
+
return false;
|
|
801
|
+
}
|
|
802
|
+
writeRef(out, $.int(value, 64));
|
|
803
|
+
return true;
|
|
804
|
+
}
|
|
805
|
+
export function String_ReadASN1ObjectIdentifier(s, out) {
|
|
806
|
+
const bytes = readASN1Bytes(s, asn1.OBJECT_IDENTIFIER);
|
|
807
|
+
const arr = bytesArray(bytes);
|
|
808
|
+
if (bytes == null || arr.length === 0) {
|
|
809
|
+
return false;
|
|
810
|
+
}
|
|
811
|
+
const oid = [];
|
|
812
|
+
let offset = 0;
|
|
813
|
+
const firstRead = readBase128Int(arr, offset);
|
|
814
|
+
if (firstRead == null) {
|
|
815
|
+
return false;
|
|
816
|
+
}
|
|
817
|
+
offset = firstRead.next;
|
|
818
|
+
if (firstRead.value < 80) {
|
|
819
|
+
oid.push(Math.floor(firstRead.value / 40), firstRead.value % 40);
|
|
820
|
+
}
|
|
821
|
+
else {
|
|
822
|
+
oid.push(2, firstRead.value - 80);
|
|
823
|
+
}
|
|
824
|
+
while (offset < arr.length) {
|
|
825
|
+
const part = readBase128Int(arr, offset);
|
|
826
|
+
if (part == null) {
|
|
827
|
+
return false;
|
|
828
|
+
}
|
|
829
|
+
offset = part.next;
|
|
830
|
+
oid.push(part.value);
|
|
831
|
+
}
|
|
832
|
+
writeRef(out, $.arrayToSlice(oid));
|
|
833
|
+
return true;
|
|
834
|
+
}
|
|
835
|
+
export function String_ReadASN1GeneralizedTime(s, out) {
|
|
836
|
+
const bytes = readASN1Bytes(s, asn1.GeneralizedTime);
|
|
837
|
+
if (bytes == null) {
|
|
838
|
+
return false;
|
|
839
|
+
}
|
|
840
|
+
const parsed = parseGeneralizedTime(bytesToAscii(bytes));
|
|
841
|
+
if (parsed == null) {
|
|
842
|
+
return false;
|
|
843
|
+
}
|
|
844
|
+
writeRef(out, parsed);
|
|
845
|
+
return true;
|
|
846
|
+
}
|
|
847
|
+
export function String_ReadASN1UTCTime(s, out) {
|
|
848
|
+
const bytes = readASN1Bytes(s, asn1.UTCTime);
|
|
849
|
+
if (bytes == null) {
|
|
850
|
+
return false;
|
|
851
|
+
}
|
|
852
|
+
const parsed = parseUTCTime(bytesToAscii(bytes));
|
|
853
|
+
if (parsed == null) {
|
|
854
|
+
return false;
|
|
855
|
+
}
|
|
856
|
+
writeRef(out, parsed);
|
|
857
|
+
return true;
|
|
858
|
+
}
|
|
859
|
+
export function String_ReadASN1BitString(s, out) {
|
|
860
|
+
const bytes = readASN1Bytes(s, asn1.BIT_STRING);
|
|
861
|
+
const parsed = parseBitString(bytes);
|
|
862
|
+
if (parsed == null) {
|
|
863
|
+
return false;
|
|
864
|
+
}
|
|
865
|
+
const target = pointerValueOrBox(out);
|
|
866
|
+
if (target == null) {
|
|
867
|
+
throw new Error('runtime error: invalid memory address or nil pointer dereference');
|
|
868
|
+
}
|
|
869
|
+
target.Bytes = parsed.bytes;
|
|
870
|
+
target.BitLength = parsed.bitLength;
|
|
871
|
+
return true;
|
|
872
|
+
}
|
|
873
|
+
export function String_ReadASN1BitStringAsBytes(s, out, paddingBits) {
|
|
874
|
+
const bytes = readASN1Bytes(s, asn1.BIT_STRING);
|
|
875
|
+
const parsed = parseBitString(bytes);
|
|
876
|
+
if (parsed == null) {
|
|
877
|
+
return false;
|
|
878
|
+
}
|
|
879
|
+
writeRef(out, parsed.bytes);
|
|
880
|
+
writeRef(paddingBits, parsed.paddingBits);
|
|
881
|
+
return true;
|
|
882
|
+
}
|
|
883
|
+
export function String_ReadASN1Bytes(s, out, tag) {
|
|
884
|
+
return String_ReadASN1(s, out, tag);
|
|
885
|
+
}
|
|
886
|
+
export function String_ReadASN1(s, out, tag) {
|
|
887
|
+
return readASN1(s, out, null, tag, true);
|
|
888
|
+
}
|
|
889
|
+
export function String_ReadASN1Element(s, out, tag) {
|
|
890
|
+
return readASN1(s, out, null, tag, false);
|
|
891
|
+
}
|
|
892
|
+
export function String_ReadAnyASN1(s, out, outTag) {
|
|
893
|
+
return readASN1(s, out, outTag, null, true);
|
|
894
|
+
}
|
|
895
|
+
export function String_ReadAnyASN1Element(s, out, outTag) {
|
|
896
|
+
return readASN1(s, out, outTag, null, false);
|
|
897
|
+
}
|
|
898
|
+
export function String_PeekASN1Tag(s, tag) {
|
|
899
|
+
const parsed = parseASN1(s);
|
|
900
|
+
return parsed !== null && parsed.tag === tag;
|
|
901
|
+
}
|
|
902
|
+
export function String_SkipASN1(s, tag) {
|
|
903
|
+
const out = $.varRef(new Uint8Array(0));
|
|
904
|
+
return String_ReadASN1Element(s, out, tag);
|
|
905
|
+
}
|
|
906
|
+
export function String_ReadOptionalASN1(s, out, tag, defaultValue) {
|
|
907
|
+
if (!String_PeekASN1Tag(stringValue(s), tag)) {
|
|
908
|
+
writeRef(out, defaultValue);
|
|
909
|
+
return true;
|
|
910
|
+
}
|
|
911
|
+
return String_ReadASN1(s, out, tag);
|
|
912
|
+
}
|
|
913
|
+
export function String_SkipOptionalASN1(s, tag) {
|
|
914
|
+
if (!String_PeekASN1Tag(stringValue(s), tag)) {
|
|
915
|
+
return true;
|
|
916
|
+
}
|
|
917
|
+
return String_SkipASN1(s, tag);
|
|
918
|
+
}
|
|
919
|
+
export function String_ReadOptionalASN1Integer(s, out, tag, defaultValue) {
|
|
920
|
+
if (!String_PeekASN1Tag(stringValue(s), tag)) {
|
|
921
|
+
writeInteger(writeTarget(out), integerDefaultValue(defaultValue));
|
|
922
|
+
return true;
|
|
923
|
+
}
|
|
924
|
+
return String_ReadASN1Integer(s, out);
|
|
925
|
+
}
|
|
926
|
+
export function String_ReadOptionalASN1OctetString(s, out, tag, defaultValue) {
|
|
927
|
+
if (!String_PeekASN1Tag(stringValue(s), tag)) {
|
|
928
|
+
writeRef(out, defaultValue);
|
|
929
|
+
return true;
|
|
930
|
+
}
|
|
931
|
+
return String_ReadASN1Bytes(s, out, tag);
|
|
932
|
+
}
|
|
933
|
+
export function String_ReadOptionalASN1Boolean(s, out, tag, defaultValue) {
|
|
934
|
+
if (!String_PeekASN1Tag(stringValue(s), tag)) {
|
|
935
|
+
writeRef(out, defaultValue);
|
|
936
|
+
return true;
|
|
937
|
+
}
|
|
938
|
+
return String_ReadASN1Boolean(s, out);
|
|
939
|
+
}
|
|
940
|
+
function parseASN1(data) {
|
|
941
|
+
const arr = bytesArray(data);
|
|
942
|
+
if (arr.length < 2 || (arr[0] & 0x1f) === 0x1f) {
|
|
943
|
+
return null;
|
|
944
|
+
}
|
|
945
|
+
const tag = arr[0];
|
|
946
|
+
let headerLen = 2;
|
|
947
|
+
let length = arr[1];
|
|
948
|
+
if ((length & 0x80) !== 0) {
|
|
949
|
+
const lenLen = length & 0x7f;
|
|
950
|
+
if (lenLen === 0 || lenLen > 4 || arr.length < 2 + lenLen) {
|
|
951
|
+
return null;
|
|
952
|
+
}
|
|
953
|
+
if (arr[2] === 0) {
|
|
954
|
+
return null;
|
|
955
|
+
}
|
|
956
|
+
length = 0;
|
|
957
|
+
for (let i = 0; i < lenLen; i++) {
|
|
958
|
+
length = length * 256 + arr[2 + i];
|
|
959
|
+
}
|
|
960
|
+
if (length < 128) {
|
|
961
|
+
return null;
|
|
962
|
+
}
|
|
963
|
+
headerLen += lenLen;
|
|
964
|
+
}
|
|
965
|
+
const totalLen = headerLen + length;
|
|
966
|
+
if (arr.length < totalLen) {
|
|
967
|
+
return null;
|
|
968
|
+
}
|
|
969
|
+
return { tag, headerLen, length, totalLen };
|
|
970
|
+
}
|
|
971
|
+
function readASN1(s, out, outTag, expectedTag, skipHeader) {
|
|
972
|
+
const data = stringValue(s);
|
|
973
|
+
const parsed = parseASN1(data);
|
|
974
|
+
if (parsed == null || (expectedTag !== null && parsed.tag !== expectedTag)) {
|
|
975
|
+
return false;
|
|
976
|
+
}
|
|
977
|
+
if (outTag != null) {
|
|
978
|
+
outTag.value = parsed.tag;
|
|
979
|
+
}
|
|
980
|
+
if (out != null) {
|
|
981
|
+
out.value = skipHeader
|
|
982
|
+
? $.goSlice(data, parsed.headerLen, parsed.totalLen)
|
|
983
|
+
: $.goSlice(data, 0, parsed.totalLen);
|
|
984
|
+
}
|
|
985
|
+
s.value = $.goSlice(data, parsed.totalLen);
|
|
986
|
+
return true;
|
|
987
|
+
}
|
|
988
|
+
function parseBitString(bytes) {
|
|
989
|
+
const arr = bytesArray(bytes);
|
|
990
|
+
if (bytes == null || arr.length === 0) {
|
|
991
|
+
return null;
|
|
992
|
+
}
|
|
993
|
+
const paddingBits = arr[0];
|
|
994
|
+
if (paddingBits > 7 || (arr.length === 1 && paddingBits !== 0)) {
|
|
995
|
+
return null;
|
|
996
|
+
}
|
|
997
|
+
if (arr.length > 1 &&
|
|
998
|
+
paddingBits > 0 &&
|
|
999
|
+
(arr[arr.length - 1] & ((1 << paddingBits) - 1)) !== 0) {
|
|
1000
|
+
return null;
|
|
1001
|
+
}
|
|
1002
|
+
const content = bytesFromArray(arr.slice(1));
|
|
1003
|
+
return {
|
|
1004
|
+
bytes: content,
|
|
1005
|
+
paddingBits,
|
|
1006
|
+
bitLength: $.len(content) * 8 - paddingBits,
|
|
1007
|
+
};
|
|
1008
|
+
}
|
|
1009
|
+
function readBase128Int(bytes, offset) {
|
|
1010
|
+
let ret = 0;
|
|
1011
|
+
for (let i = offset; i < bytes.length; i++) {
|
|
1012
|
+
const b = bytes[i];
|
|
1013
|
+
if (ret === 0 && b === 0x80) {
|
|
1014
|
+
return null;
|
|
1015
|
+
}
|
|
1016
|
+
ret = ret * 128 + (b & 0x7f);
|
|
1017
|
+
if (ret > Number.MAX_SAFE_INTEGER) {
|
|
1018
|
+
return null;
|
|
1019
|
+
}
|
|
1020
|
+
if ((b & 0x80) === 0) {
|
|
1021
|
+
return { value: ret, next: i + 1 };
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
return null;
|
|
1025
|
+
}
|
|
1026
|
+
function parseFixedDigits(value, offset, width) {
|
|
1027
|
+
const text = value.slice(offset, offset + width);
|
|
1028
|
+
if (!new RegExp(`^[0-9]{${width}}$`).test(text)) {
|
|
1029
|
+
return null;
|
|
1030
|
+
}
|
|
1031
|
+
return Number(text);
|
|
1032
|
+
}
|
|
1033
|
+
function parseZone(value, offset) {
|
|
1034
|
+
if (value[offset] === 'Z' && offset + 1 === value.length) {
|
|
1035
|
+
return { offsetMinutes: 0 };
|
|
1036
|
+
}
|
|
1037
|
+
const sign = value[offset];
|
|
1038
|
+
if ((sign !== '+' && sign !== '-') || offset + 5 !== value.length) {
|
|
1039
|
+
return null;
|
|
1040
|
+
}
|
|
1041
|
+
const hour = parseFixedDigits(value, offset + 1, 2);
|
|
1042
|
+
const minute = parseFixedDigits(value, offset + 3, 2);
|
|
1043
|
+
if (hour == null || minute == null || hour > 23 || minute > 59) {
|
|
1044
|
+
return null;
|
|
1045
|
+
}
|
|
1046
|
+
const offsetMinutes = hour * 60 + minute;
|
|
1047
|
+
return { offsetMinutes: sign === '+' ? offsetMinutes : -offsetMinutes };
|
|
1048
|
+
}
|
|
1049
|
+
function makeTime(year, month, day, hour, minute, second, offsetMinutes) {
|
|
1050
|
+
const millis = globalThis.Date.UTC(year, month - 1, day, hour, minute, second) -
|
|
1051
|
+
offsetMinutes * 60 * 1000;
|
|
1052
|
+
return time.Unix(Math.floor(millis / 1000), 0);
|
|
1053
|
+
}
|
|
1054
|
+
function parseGeneralizedTime(value) {
|
|
1055
|
+
if (value.length < 15) {
|
|
1056
|
+
return null;
|
|
1057
|
+
}
|
|
1058
|
+
const year = parseFixedDigits(value, 0, 4);
|
|
1059
|
+
const month = parseFixedDigits(value, 4, 2);
|
|
1060
|
+
const day = parseFixedDigits(value, 6, 2);
|
|
1061
|
+
const hour = parseFixedDigits(value, 8, 2);
|
|
1062
|
+
const minute = parseFixedDigits(value, 10, 2);
|
|
1063
|
+
const second = parseFixedDigits(value, 12, 2);
|
|
1064
|
+
const zone = parseZone(value, 14);
|
|
1065
|
+
if (year == null ||
|
|
1066
|
+
month == null ||
|
|
1067
|
+
day == null ||
|
|
1068
|
+
hour == null ||
|
|
1069
|
+
minute == null ||
|
|
1070
|
+
second == null ||
|
|
1071
|
+
zone == null) {
|
|
1072
|
+
return null;
|
|
1073
|
+
}
|
|
1074
|
+
return makeTime(year, month, day, hour, minute, second, zone.offsetMinutes);
|
|
1075
|
+
}
|
|
1076
|
+
function parseUTCTime(value) {
|
|
1077
|
+
if (value.length !== 11 && value.length !== 13 && value.length !== 15 && value.length !== 17) {
|
|
1078
|
+
return null;
|
|
1079
|
+
}
|
|
1080
|
+
const yearPart = parseFixedDigits(value, 0, 2);
|
|
1081
|
+
const month = parseFixedDigits(value, 2, 2);
|
|
1082
|
+
const day = parseFixedDigits(value, 4, 2);
|
|
1083
|
+
const hour = parseFixedDigits(value, 6, 2);
|
|
1084
|
+
const minute = parseFixedDigits(value, 8, 2);
|
|
1085
|
+
let second = 0;
|
|
1086
|
+
let zoneOffset = 10;
|
|
1087
|
+
if (value.length === 13 || value.length === 17) {
|
|
1088
|
+
const parsedSecond = parseFixedDigits(value, 10, 2);
|
|
1089
|
+
if (parsedSecond == null) {
|
|
1090
|
+
return null;
|
|
1091
|
+
}
|
|
1092
|
+
second = parsedSecond;
|
|
1093
|
+
zoneOffset = 12;
|
|
1094
|
+
}
|
|
1095
|
+
const zone = parseZone(value, zoneOffset);
|
|
1096
|
+
if (yearPart == null ||
|
|
1097
|
+
month == null ||
|
|
1098
|
+
day == null ||
|
|
1099
|
+
hour == null ||
|
|
1100
|
+
minute == null ||
|
|
1101
|
+
zone == null) {
|
|
1102
|
+
return null;
|
|
1103
|
+
}
|
|
1104
|
+
const year = yearPart >= 50 ? 1900 + yearPart : 2000 + yearPart;
|
|
1105
|
+
return makeTime(year, month, day, hour, minute, second, zone.offsetMinutes);
|
|
1106
|
+
}
|
|
1107
|
+
//# sourceMappingURL=index.js.map
|