@5ive-tech/sdk 1.1.2
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 +279 -0
- package/dist/FiveSDK.d.ts +336 -0
- package/dist/FiveSDK.js +395 -0
- package/dist/accounts/index.d.ts +254 -0
- package/dist/accounts/index.js +543 -0
- package/dist/assets/vm/dummy.file +0 -0
- package/dist/assets/vm/five_vm_wasm.d.ts +762 -0
- package/dist/assets/vm/five_vm_wasm.js +3754 -0
- package/dist/assets/vm/five_vm_wasm_bg.js +3307 -0
- package/dist/assets/vm/five_vm_wasm_bg.wasm +0 -0
- package/dist/assets/vm/five_vm_wasm_bg.wasm.d.ts +247 -0
- package/dist/assets/vm/package.json +11 -0
- package/dist/bin/gen-types.d.ts +2 -0
- package/dist/bin/gen-types.js +35 -0
- package/dist/compiler/BytecodeCompiler.d.ts +83 -0
- package/dist/compiler/BytecodeCompiler.js +379 -0
- package/dist/config/ConfigManager.d.ts +13 -0
- package/dist/config/ConfigManager.js +27 -0
- package/dist/config/ProgramIdResolver.d.ts +62 -0
- package/dist/config/ProgramIdResolver.js +104 -0
- package/dist/crypto/index.d.ts +211 -0
- package/dist/crypto/index.js +451 -0
- package/dist/encoding/ParameterEncoder.d.ts +31 -0
- package/dist/encoding/ParameterEncoder.js +278 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +28 -0
- package/dist/lib/bytecode-encoder.d.ts +62 -0
- package/dist/lib/bytecode-encoder.js +281 -0
- package/dist/logging/index.d.ts +9 -0
- package/dist/logging/index.js +10 -0
- package/dist/metadata/index.d.ts +213 -0
- package/dist/metadata/index.js +296 -0
- package/dist/modules/accounts.d.ts +60 -0
- package/dist/modules/accounts.js +275 -0
- package/dist/modules/deploy.d.ts +90 -0
- package/dist/modules/deploy.js +1118 -0
- package/dist/modules/execute.d.ts +90 -0
- package/dist/modules/execute.js +649 -0
- package/dist/modules/fees.d.ts +14 -0
- package/dist/modules/fees.js +112 -0
- package/dist/modules/namespaces.d.ts +39 -0
- package/dist/modules/namespaces.js +190 -0
- package/dist/modules/state-diff.d.ts +35 -0
- package/dist/modules/state-diff.js +342 -0
- package/dist/modules/vm-state.d.ts +7 -0
- package/dist/modules/vm-state.js +44 -0
- package/dist/program/AccountResolver.d.ts +67 -0
- package/dist/program/AccountResolver.js +134 -0
- package/dist/program/BorshSchemaGenerator.d.ts +8 -0
- package/dist/program/BorshSchemaGenerator.js +57 -0
- package/dist/program/FiveProgram.d.ts +144 -0
- package/dist/program/FiveProgram.js +282 -0
- package/dist/program/FunctionBuilder.d.ts +114 -0
- package/dist/program/FunctionBuilder.js +347 -0
- package/dist/program/ProgramAccount.d.ts +38 -0
- package/dist/program/ProgramAccount.js +170 -0
- package/dist/program/TypeGenerator.d.ts +90 -0
- package/dist/program/TypeGenerator.js +195 -0
- package/dist/program/index.d.ts +24 -0
- package/dist/program/index.js +21 -0
- package/dist/project/config.d.ts +5 -0
- package/dist/project/config.js +33 -0
- package/dist/project/toml.d.ts +6 -0
- package/dist/project/toml.js +43 -0
- package/dist/project/workspace.d.ts +160 -0
- package/dist/project/workspace.js +73 -0
- package/dist/testing/AccountMetaGenerator.d.ts +121 -0
- package/dist/testing/AccountMetaGenerator.js +261 -0
- package/dist/testing/AccountTestFixture.d.ts +211 -0
- package/dist/testing/AccountTestFixture.js +530 -0
- package/dist/testing/OnChainAccountManager.d.ts +81 -0
- package/dist/testing/OnChainAccountManager.js +260 -0
- package/dist/testing/StateSerializer.d.ts +65 -0
- package/dist/testing/StateSerializer.js +330 -0
- package/dist/testing/TestDiscovery.d.ts +79 -0
- package/dist/testing/TestDiscovery.js +274 -0
- package/dist/testing/TestRunner.d.ts +117 -0
- package/dist/testing/TestRunner.js +346 -0
- package/dist/testing/index.d.ts +14 -0
- package/dist/testing/index.js +13 -0
- package/dist/types.d.ts +356 -0
- package/dist/types.js +32 -0
- package/dist/utils/abi.d.ts +31 -0
- package/dist/utils/abi.js +92 -0
- package/dist/utils/transaction.d.ts +5 -0
- package/dist/utils/transaction.js +48 -0
- package/dist/validation/InputValidator.d.ts +142 -0
- package/dist/validation/InputValidator.js +332 -0
- package/dist/validation/index.d.ts +4 -0
- package/dist/validation/index.js +4 -0
- package/dist/wasm/compiler/AbiLogic.d.ts +4 -0
- package/dist/wasm/compiler/AbiLogic.js +37 -0
- package/dist/wasm/compiler/AnalysisLogic.d.ts +6 -0
- package/dist/wasm/compiler/AnalysisLogic.js +61 -0
- package/dist/wasm/compiler/CompilationLogic.d.ts +10 -0
- package/dist/wasm/compiler/CompilationLogic.js +431 -0
- package/dist/wasm/compiler/FiveCompiler.d.ts +48 -0
- package/dist/wasm/compiler/FiveCompiler.js +183 -0
- package/dist/wasm/compiler/InfoLogic.d.ts +6 -0
- package/dist/wasm/compiler/InfoLogic.js +24 -0
- package/dist/wasm/compiler/OptimizationLogic.d.ts +2 -0
- package/dist/wasm/compiler/OptimizationLogic.js +13 -0
- package/dist/wasm/compiler/ValidationLogic.d.ts +7 -0
- package/dist/wasm/compiler/ValidationLogic.js +26 -0
- package/dist/wasm/compiler/index.d.ts +2 -0
- package/dist/wasm/compiler/index.js +2 -0
- package/dist/wasm/compiler/types.d.ts +8 -0
- package/dist/wasm/compiler/types.js +1 -0
- package/dist/wasm/compiler/utils.d.ts +8 -0
- package/dist/wasm/compiler/utils.js +75 -0
- package/dist/wasm/index.d.ts +9 -0
- package/dist/wasm/index.js +12 -0
- package/dist/wasm/instance.d.ts +1 -0
- package/dist/wasm/instance.js +26 -0
- package/dist/wasm/loader.d.ts +7 -0
- package/dist/wasm/loader.js +112 -0
- package/dist/wasm/vm.d.ts +33 -0
- package/dist/wasm/vm.js +250 -0
- package/package.json +59 -0
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Five SDK input validation.
|
|
3
|
+
* Protects against common injection and resource abuse cases.
|
|
4
|
+
*/
|
|
5
|
+
import { FiveSDKError } from '../types.js';
|
|
6
|
+
/**
|
|
7
|
+
* Default validation configuration
|
|
8
|
+
*/
|
|
9
|
+
export const DEFAULT_VALIDATION_CONFIG = {
|
|
10
|
+
maxSourceSize: 1024 * 1024, // 1MB
|
|
11
|
+
maxBytecodeSize: 1024 * 1024, // 1MB
|
|
12
|
+
maxParameters: 256,
|
|
13
|
+
maxParameterSize: 64 * 1024, // 64KB per parameter
|
|
14
|
+
maxPathLength: 1000,
|
|
15
|
+
maxAccounts: 64,
|
|
16
|
+
maxStringLength: 32 * 1024, // 32KB
|
|
17
|
+
maxArrayLength: 10000,
|
|
18
|
+
allowedExtensions: ['.v', '.five', '.bin'],
|
|
19
|
+
allowedPaths: [
|
|
20
|
+
/^[a-zA-Z0-9_\-\.\/]+$/, // Basic safe characters
|
|
21
|
+
/^\.\.?\//, // Relative paths (blocked)
|
|
22
|
+
]
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Validation error types
|
|
26
|
+
*/
|
|
27
|
+
export var ValidationErrorType;
|
|
28
|
+
(function (ValidationErrorType) {
|
|
29
|
+
ValidationErrorType["INVALID_INPUT"] = "INVALID_INPUT";
|
|
30
|
+
ValidationErrorType["SIZE_EXCEEDED"] = "SIZE_EXCEEDED";
|
|
31
|
+
ValidationErrorType["TYPE_MISMATCH"] = "TYPE_MISMATCH";
|
|
32
|
+
ValidationErrorType["UNSAFE_PATH"] = "UNSAFE_PATH";
|
|
33
|
+
ValidationErrorType["RESOURCE_EXHAUSTION"] = "RESOURCE_EXHAUSTION";
|
|
34
|
+
ValidationErrorType["MALICIOUS_CONTENT"] = "MALICIOUS_CONTENT";
|
|
35
|
+
ValidationErrorType["ENCODING_ERROR"] = "ENCODING_ERROR";
|
|
36
|
+
})(ValidationErrorType || (ValidationErrorType = {}));
|
|
37
|
+
/**
|
|
38
|
+
* Input validation error
|
|
39
|
+
*/
|
|
40
|
+
export class ValidationError extends FiveSDKError {
|
|
41
|
+
constructor(message, type, field, value) {
|
|
42
|
+
super(message, 'VALIDATION_ERROR', { type, field, value });
|
|
43
|
+
this.type = type;
|
|
44
|
+
this.field = field;
|
|
45
|
+
this.value = value;
|
|
46
|
+
this.name = 'ValidationError';
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Input validator for Five SDK
|
|
51
|
+
*/
|
|
52
|
+
export class InputValidator {
|
|
53
|
+
constructor(config = DEFAULT_VALIDATION_CONFIG) {
|
|
54
|
+
this.config = config;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Validate source code input
|
|
58
|
+
*/
|
|
59
|
+
validateSourceCode(source, context = 'source') {
|
|
60
|
+
this.validateString(source, context, this.config.maxSourceSize);
|
|
61
|
+
// Validate encoding (must be valid UTF-8)
|
|
62
|
+
try {
|
|
63
|
+
new TextEncoder().encode(source);
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
throw new ValidationError(`Source code contains invalid encoding`, ValidationErrorType.ENCODING_ERROR, context);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Validate bytecode input
|
|
71
|
+
*/
|
|
72
|
+
validateBytecode(bytecode, context = 'bytecode') {
|
|
73
|
+
this.validateBuffer(bytecode, context, this.config.maxBytecodeSize);
|
|
74
|
+
// Basic bytecode structure validation
|
|
75
|
+
if (bytecode.length < 8) {
|
|
76
|
+
throw new ValidationError(`Bytecode too small: ${bytecode.length} bytes (minimum 8)`, ValidationErrorType.SIZE_EXCEEDED, context, bytecode.length);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Validate file path
|
|
81
|
+
*/
|
|
82
|
+
validateFilePath(path, context = 'filePath') {
|
|
83
|
+
this.validateString(path, context, this.config.maxPathLength);
|
|
84
|
+
// Check for path traversal attacks
|
|
85
|
+
if (path.includes('..') || path.includes('~') || path.startsWith('/')) {
|
|
86
|
+
throw new ValidationError(`Unsafe file path: ${path}`, ValidationErrorType.UNSAFE_PATH, context, path);
|
|
87
|
+
}
|
|
88
|
+
// Validate allowed paths
|
|
89
|
+
const isAllowed = this.config.allowedPaths.some(pattern => pattern.test(path));
|
|
90
|
+
if (!isAllowed) {
|
|
91
|
+
throw new ValidationError(`File path not allowed: ${path}`, ValidationErrorType.UNSAFE_PATH, context, path);
|
|
92
|
+
}
|
|
93
|
+
// Validate file extension
|
|
94
|
+
const extension = path.substring(path.lastIndexOf('.'));
|
|
95
|
+
if (extension && !this.config.allowedExtensions.includes(extension)) {
|
|
96
|
+
throw new ValidationError(`File extension not allowed: ${extension}`, ValidationErrorType.UNSAFE_PATH, context, extension);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Validate function parameters
|
|
101
|
+
*/
|
|
102
|
+
validateParameters(parameters, context = 'parameters') {
|
|
103
|
+
if (!Array.isArray(parameters)) {
|
|
104
|
+
throw new ValidationError(`Parameters must be an array`, ValidationErrorType.TYPE_MISMATCH, context, typeof parameters);
|
|
105
|
+
}
|
|
106
|
+
if (parameters.length > this.config.maxParameters) {
|
|
107
|
+
throw new ValidationError(`Too many parameters: ${parameters.length} (max ${this.config.maxParameters})`, ValidationErrorType.SIZE_EXCEEDED, context, parameters.length);
|
|
108
|
+
}
|
|
109
|
+
parameters.forEach((param, index) => {
|
|
110
|
+
this.validateParameter(param, `${context}[${index}]`);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Validate individual parameter
|
|
115
|
+
*/
|
|
116
|
+
validateParameter(parameter, context = 'parameter') {
|
|
117
|
+
if (parameter === null || parameter === undefined) {
|
|
118
|
+
return; // Allow null/undefined parameters
|
|
119
|
+
}
|
|
120
|
+
const type = typeof parameter;
|
|
121
|
+
switch (type) {
|
|
122
|
+
case 'string':
|
|
123
|
+
this.validateString(parameter, context, this.config.maxParameterSize);
|
|
124
|
+
break;
|
|
125
|
+
case 'number':
|
|
126
|
+
this.validateNumberPrivate(parameter, context);
|
|
127
|
+
break;
|
|
128
|
+
case 'boolean':
|
|
129
|
+
// Boolean is always valid
|
|
130
|
+
break;
|
|
131
|
+
case 'object':
|
|
132
|
+
if (Array.isArray(parameter)) {
|
|
133
|
+
this.validateArray(parameter, context);
|
|
134
|
+
}
|
|
135
|
+
else if (parameter instanceof Uint8Array) {
|
|
136
|
+
this.validateBuffer(parameter, context, this.config.maxParameterSize);
|
|
137
|
+
}
|
|
138
|
+
else if (typeof parameter.toBuffer === 'function' ||
|
|
139
|
+
typeof parameter.toBytes === 'function' ||
|
|
140
|
+
typeof parameter.toBase58 === 'function') {
|
|
141
|
+
// Allow Solana PublicKey or similar objects
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
throw new ValidationError(`Unsupported parameter type: ${type} (${parameter?.constructor?.name || 'unknown'})`, ValidationErrorType.TYPE_MISMATCH, context, type);
|
|
146
|
+
}
|
|
147
|
+
break;
|
|
148
|
+
default:
|
|
149
|
+
throw new ValidationError(`Unsupported parameter type: ${type}`, ValidationErrorType.TYPE_MISMATCH, context, type);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Validate account addresses
|
|
154
|
+
*/
|
|
155
|
+
validateAccounts(accounts, context = 'accounts') {
|
|
156
|
+
if (!Array.isArray(accounts)) {
|
|
157
|
+
throw new ValidationError(`Accounts must be an array`, ValidationErrorType.TYPE_MISMATCH, context, typeof accounts);
|
|
158
|
+
}
|
|
159
|
+
if (accounts.length > this.config.maxAccounts) {
|
|
160
|
+
throw new ValidationError(`Too many accounts: ${accounts.length} (max ${this.config.maxAccounts})`, ValidationErrorType.SIZE_EXCEEDED, context, accounts.length);
|
|
161
|
+
}
|
|
162
|
+
accounts.forEach((account, index) => {
|
|
163
|
+
this.validateBase58Address(account, `${context}[${index}]`);
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Validate Base58 address
|
|
168
|
+
*/
|
|
169
|
+
validateBase58Address(address, context = 'address') {
|
|
170
|
+
this.validateString(address, context, 100); // Solana addresses are ~44 chars
|
|
171
|
+
// Solana address length validation (typically 32-44 characters)
|
|
172
|
+
if (address.length < 32 || address.length > 44) {
|
|
173
|
+
throw new ValidationError(`Invalid address length: ${address.length} (expected 32-44 characters)`, ValidationErrorType.INVALID_INPUT, context, address.length);
|
|
174
|
+
}
|
|
175
|
+
// Basic Base58 format validation (after length check)
|
|
176
|
+
const base58Regex = /^[1-9A-HJ-NP-Za-km-z]+$/;
|
|
177
|
+
if (!base58Regex.test(address)) {
|
|
178
|
+
throw new ValidationError(`Invalid Base58 address format: ${address}`, ValidationErrorType.INVALID_INPUT, context, address);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Validate function name or index
|
|
183
|
+
*/
|
|
184
|
+
validateFunctionReference(functionRef, context = 'function') {
|
|
185
|
+
if (typeof functionRef === 'number') {
|
|
186
|
+
this.validateNumberPrivate(functionRef, context);
|
|
187
|
+
if (functionRef < 0 || !Number.isInteger(functionRef)) {
|
|
188
|
+
throw new ValidationError(`Function index must be a non-negative integer: ${functionRef}`, ValidationErrorType.INVALID_INPUT, context, functionRef);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
else if (typeof functionRef === 'string') {
|
|
192
|
+
this.validateString(functionRef, context, 256);
|
|
193
|
+
// Function name validation (alphanumeric + underscore)
|
|
194
|
+
const functionNameRegex = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
|
|
195
|
+
if (!functionNameRegex.test(functionRef)) {
|
|
196
|
+
throw new ValidationError(`Invalid function name format: ${functionRef}`, ValidationErrorType.INVALID_INPUT, context, functionRef);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
throw new ValidationError(`Function reference must be string or number`, ValidationErrorType.TYPE_MISMATCH, context, typeof functionRef);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Validate options object
|
|
205
|
+
*/
|
|
206
|
+
validateOptions(options, context = 'options') {
|
|
207
|
+
if (options === null || options === undefined) {
|
|
208
|
+
return; // Options are optional
|
|
209
|
+
}
|
|
210
|
+
if (typeof options !== 'object' || Array.isArray(options)) {
|
|
211
|
+
throw new ValidationError(`Options must be an object`, ValidationErrorType.TYPE_MISMATCH, context, typeof options);
|
|
212
|
+
}
|
|
213
|
+
// Validate specific option fields
|
|
214
|
+
if ('debug' in options && options.debug !== undefined && typeof options.debug !== 'boolean') {
|
|
215
|
+
throw new ValidationError(`Options.debug must be boolean`, ValidationErrorType.TYPE_MISMATCH, `${context}.debug`, typeof options.debug);
|
|
216
|
+
}
|
|
217
|
+
if ('computeUnitLimit' in options && options.computeUnitLimit !== undefined) {
|
|
218
|
+
this.validateNumberPrivate(options.computeUnitLimit, `${context}.computeUnitLimit`);
|
|
219
|
+
}
|
|
220
|
+
if ('maxSize' in options && options.maxSize !== undefined) {
|
|
221
|
+
this.validateNumberPrivate(options.maxSize, `${context}.maxSize`);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
// ==================== Private Helper Methods ====================
|
|
225
|
+
/**
|
|
226
|
+
* Validate string input
|
|
227
|
+
*/
|
|
228
|
+
validateString(value, context, maxLength) {
|
|
229
|
+
if (typeof value !== 'string') {
|
|
230
|
+
throw new ValidationError(`Expected string but got ${typeof value}`, ValidationErrorType.TYPE_MISMATCH, context, typeof value);
|
|
231
|
+
}
|
|
232
|
+
if (value.length > maxLength) {
|
|
233
|
+
throw new ValidationError(`String too long: ${value.length} characters (max ${maxLength})`, ValidationErrorType.SIZE_EXCEEDED, context, value.length);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Validate number input (also exposed as public for external use)
|
|
238
|
+
*/
|
|
239
|
+
validateNumber(value, context = 'number') {
|
|
240
|
+
this.validateNumberPrivate(value, context);
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Validate number input (private implementation)
|
|
244
|
+
*/
|
|
245
|
+
validateNumberPrivate(value, context) {
|
|
246
|
+
if (typeof value !== 'number') {
|
|
247
|
+
throw new ValidationError(`Expected number but got ${typeof value}`, ValidationErrorType.TYPE_MISMATCH, context, typeof value);
|
|
248
|
+
}
|
|
249
|
+
if (!Number.isFinite(value)) {
|
|
250
|
+
throw new ValidationError(`Number must be finite: ${value}`, ValidationErrorType.INVALID_INPUT, context, value);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Validate buffer input
|
|
255
|
+
*/
|
|
256
|
+
validateBuffer(buffer, context, maxSize) {
|
|
257
|
+
if (!(buffer instanceof Uint8Array)) {
|
|
258
|
+
throw new ValidationError(`Expected Uint8Array but got ${buffer?.constructor?.name || typeof buffer}`, ValidationErrorType.TYPE_MISMATCH, context, buffer?.constructor?.name || typeof buffer);
|
|
259
|
+
}
|
|
260
|
+
if (buffer.length > maxSize) {
|
|
261
|
+
throw new ValidationError(`Buffer too large: ${buffer.length} bytes (max ${maxSize})`, ValidationErrorType.SIZE_EXCEEDED, context, buffer.length);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Validate array input
|
|
266
|
+
*/
|
|
267
|
+
validateArray(array, context) {
|
|
268
|
+
if (array.length > this.config.maxArrayLength) {
|
|
269
|
+
throw new ValidationError(`Array too long: ${array.length} elements (max ${this.config.maxArrayLength})`, ValidationErrorType.SIZE_EXCEEDED, context, array.length);
|
|
270
|
+
}
|
|
271
|
+
array.forEach((item, index) => {
|
|
272
|
+
this.validateParameter(item, `${context}[${index}]`);
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Check for malicious patterns in source code
|
|
277
|
+
*/
|
|
278
|
+
containsMaliciousPatterns(source) {
|
|
279
|
+
const maliciousPatterns = [
|
|
280
|
+
// Script injection patterns
|
|
281
|
+
/<script/i,
|
|
282
|
+
/javascript:/i,
|
|
283
|
+
/vbscript:/i,
|
|
284
|
+
/onload=/i,
|
|
285
|
+
/onerror=/i,
|
|
286
|
+
// File system access patterns
|
|
287
|
+
/\.\.\/\.\.\//,
|
|
288
|
+
/\/etc\/passwd/i,
|
|
289
|
+
/\/proc\//i,
|
|
290
|
+
/\\windows\\system32/i,
|
|
291
|
+
// Network access patterns
|
|
292
|
+
/fetch\(/i,
|
|
293
|
+
/XMLHttpRequest/i,
|
|
294
|
+
/require\(/i,
|
|
295
|
+
/import\(/i,
|
|
296
|
+
// Dangerous functions
|
|
297
|
+
/eval\(/i,
|
|
298
|
+
/Function\(/i,
|
|
299
|
+
/setTimeout\(/i,
|
|
300
|
+
/setInterval\(/i,
|
|
301
|
+
];
|
|
302
|
+
return maliciousPatterns.some(pattern => pattern.test(source));
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Global validator instance
|
|
307
|
+
*/
|
|
308
|
+
export const validator = new InputValidator();
|
|
309
|
+
/**
|
|
310
|
+
* Validation decorators for class methods
|
|
311
|
+
*/
|
|
312
|
+
export function validateInput(validationFn) {
|
|
313
|
+
return function (target, propertyName, descriptor) {
|
|
314
|
+
const method = descriptor.value;
|
|
315
|
+
descriptor.value = function (...args) {
|
|
316
|
+
validationFn(args);
|
|
317
|
+
return method.apply(this, args);
|
|
318
|
+
};
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Common validation patterns
|
|
323
|
+
*/
|
|
324
|
+
export const Validators = {
|
|
325
|
+
sourceCode: (source) => validator.validateSourceCode(source),
|
|
326
|
+
bytecode: (bytecode) => validator.validateBytecode(bytecode),
|
|
327
|
+
filePath: (path) => validator.validateFilePath(path),
|
|
328
|
+
parameters: (params) => validator.validateParameters(params),
|
|
329
|
+
accounts: (accounts) => validator.validateAccounts(accounts),
|
|
330
|
+
functionRef: (ref) => validator.validateFunctionReference(ref),
|
|
331
|
+
options: (opts) => validator.validateOptions(opts)
|
|
332
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { CompilationContext } from "./types.js";
|
|
2
|
+
export declare function generateABI(ctx: CompilationContext, sourceCode: string): Promise<any>;
|
|
3
|
+
export declare function extractAccountDefinitions(ctx: CompilationContext, sourceCode: string): Promise<any>;
|
|
4
|
+
export declare function extractFunctionSignatures(ctx: CompilationContext, sourceCode: string): Promise<any>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { createCompilerError } from "./utils.js";
|
|
2
|
+
export async function generateABI(ctx, sourceCode) {
|
|
3
|
+
if (!ctx.compiler) {
|
|
4
|
+
throw createCompilerError("Compiler not initialized");
|
|
5
|
+
}
|
|
6
|
+
try {
|
|
7
|
+
const abi = ctx.compiler.generate_abi(sourceCode);
|
|
8
|
+
return JSON.parse(abi);
|
|
9
|
+
}
|
|
10
|
+
catch (error) {
|
|
11
|
+
throw createCompilerError("ABI generation failed", error);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export async function extractAccountDefinitions(ctx, sourceCode) {
|
|
15
|
+
if (!ctx.compiler) {
|
|
16
|
+
throw createCompilerError("Compiler not initialized");
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
const definitions = ctx.compiler.extract_account_definitions(sourceCode);
|
|
20
|
+
return JSON.parse(definitions);
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
throw createCompilerError("Account definition extraction failed", error);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export async function extractFunctionSignatures(ctx, sourceCode) {
|
|
27
|
+
if (!ctx.compiler) {
|
|
28
|
+
throw createCompilerError("Compiler not initialized");
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const signatures = ctx.compiler.extract_function_signatures(sourceCode);
|
|
32
|
+
return JSON.parse(signatures);
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
throw createCompilerError("Function signature extraction failed", error);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { CompilationContext } from "./types.js";
|
|
2
|
+
export declare function analyzeBytecode(ctx: CompilationContext, bytecode: Uint8Array): Promise<any>;
|
|
3
|
+
export declare function analyzeInstructionAt(ctx: CompilationContext, bytecode: Uint8Array, offset: number): Promise<any>;
|
|
4
|
+
export declare function getBytecodeStats(ctx: CompilationContext, bytecode: Uint8Array): Promise<any>;
|
|
5
|
+
export declare function getOpcodeUsage(ctx: CompilationContext, sourceCode: string): Promise<any>;
|
|
6
|
+
export declare function getOpcodeAnalysis(ctx: CompilationContext, sourceCode: string): Promise<any>;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { createCompilerError } from "./utils.js";
|
|
2
|
+
export async function analyzeBytecode(ctx, bytecode) {
|
|
3
|
+
if (!ctx.wasmModuleRef) {
|
|
4
|
+
throw createCompilerError("Compiler not initialized");
|
|
5
|
+
}
|
|
6
|
+
try {
|
|
7
|
+
const analysis = ctx.BytecodeAnalyzer.analyze_semantic(bytecode);
|
|
8
|
+
return JSON.parse(analysis);
|
|
9
|
+
}
|
|
10
|
+
catch (error) {
|
|
11
|
+
throw createCompilerError("Bytecode analysis failed", error);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export async function analyzeInstructionAt(ctx, bytecode, offset) {
|
|
15
|
+
if (!ctx.wasmModuleRef) {
|
|
16
|
+
throw createCompilerError("Compiler not initialized");
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
const instruction = ctx.BytecodeAnalyzer.analyze_instruction_at(bytecode, offset);
|
|
20
|
+
return JSON.parse(instruction);
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
throw createCompilerError("Instruction analysis failed", error);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export async function getBytecodeStats(ctx, bytecode) {
|
|
27
|
+
if (!ctx.wasmModuleRef) {
|
|
28
|
+
throw createCompilerError("Compiler not initialized");
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const stats = ctx.BytecodeAnalyzer.get_bytecode_summary(bytecode);
|
|
32
|
+
return JSON.parse(stats);
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
throw createCompilerError("Bytecode stats failed", error);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export async function getOpcodeUsage(ctx, sourceCode) {
|
|
39
|
+
if (!ctx.compiler) {
|
|
40
|
+
throw createCompilerError("Compiler not initialized");
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
const usage = ctx.compiler.get_opcode_usage(sourceCode);
|
|
44
|
+
return JSON.parse(usage);
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
throw createCompilerError("Opcode usage analysis failed", error);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
export async function getOpcodeAnalysis(ctx, sourceCode) {
|
|
51
|
+
if (!ctx.compiler) {
|
|
52
|
+
throw createCompilerError("Compiler not initialized");
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
const analysis = ctx.compiler.get_opcode_analysis(sourceCode);
|
|
56
|
+
return JSON.parse(analysis);
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
throw createCompilerError("Comprehensive opcode analysis failed", error);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { CompilationOptions, CompilationResult } from "../../types.js";
|
|
2
|
+
import { CompilationContext } from "./types.js";
|
|
3
|
+
export declare function compile(ctx: CompilationContext, source: string, options?: any): Promise<any>;
|
|
4
|
+
export declare function compileModules(ctx: CompilationContext, mainSource: string, modules: Array<{
|
|
5
|
+
name: string;
|
|
6
|
+
source: string;
|
|
7
|
+
}>, options?: any): Promise<any>;
|
|
8
|
+
export declare function compileFile(ctx: CompilationContext, options: CompilationOptions): Promise<CompilationResult>;
|
|
9
|
+
export declare function compileWithDiscovery(ctx: CompilationContext, entryPoint: string, options?: any): Promise<any>;
|
|
10
|
+
export declare function compileModulesExplicit(ctx: CompilationContext, moduleFiles: string[], entryPoint: string, options?: any): Promise<any>;
|