阅山

  • WIN
    • CSharp
    • JAVA
    • OAM
    • DirectX
    • Emgucv
  • UNIX
    • FFmpeg
    • QT
    • Python
    • Opencv
    • Openwrt
    • Twisted
    • Design Patterns
    • Mysql
    • Mycat
    • MariaDB
    • Make
    • OAM
    • Supervisor
    • Nginx
    • KVM
    • Docker
    • OpenStack
  • WEB
    • ASP
    • Node.js
    • PHP
    • Directadmin
    • Openssl
    • Regex
  • APP
    • Android
  • AI
    • Algorithm
    • Deep Learning
    • Machine Learning
  • IOT
    • Device
    • MSP430
  • DIY
    • Algorithm
    • Design Patterns
    • MATH
    • X98 AIR 3G
    • Tucao
    • fun
  • LIFE
    • 美食
    • 关于我
  • LINKS
  • ME
Claves
长风破浪会有时,直挂云帆济沧海
  1. 首页
  2. Platforms
  3. LINUX
  4. dotnet
  5. 正文

dotnet的Jint的测试案例

2025-07-18

场景

想找一个支持windows/linux/armlinux的脚本引擎。

Jint总结

  • 编译为单文件模式并裁剪后,Windows/Linux可执行文件仅增加4MB左右;
  • Linux/Windows/ARM均测试通过。
  • 性能明显比ClearScript、CScript差,但优点是打包后体积小;
  • Windows单次命令执行0.0005ms左右,ArmLinux单词执行大约0.02ms左右;
  • 支持内联JS lambda函数;

博主认为基本满足跨平台嵌入式运行场景;

Jint功能测试代码

// See https://aka.ms/new-console-template for more information

using Jint;

Console.WriteLine("Hello, World!");

var engine0 = new Engine()
    .Execute(@"
var x = 1 + 2;
var add1 = (x1,x2)=>{return x1+x2;}

var y = add1(10, 3);
"); // 

Console.WriteLine(engine0.GetValue("x").ToObject());
Console.WriteLine(engine0.GetValue("y").ToObject());

var engine1 = new Engine()
    .Execute("var x = 1 + 2;"); // 输出: 3

Console.WriteLine(engine1.GetValue("x").ToObject());

var engine2 = new Engine()
    .Execute("function add(a, b) { return a + b; }");

var result2 = engine2.Invoke("add", 5, 3).ToObject(); // 8
Console.WriteLine(result2);


// 创建 Jint 引擎
var engine = new Engine()
    .SetValue("log", new Action<object>(Console.WriteLine)); // 添加 console.log 功能

// 定义一个包含 if/else、switch 和数学计算的 JavaScript 代码
string jsCode = @"
            function calculate(x, y, operation) {
                let result;
                
                // if/else 示例
                if (operation === 'add') {
                    result = x + y;
                } else if (operation === 'subtract') {
                    result = x - y;
                } else if (operation === 'multiply') {
                    result = x * y;
                } else if (operation === 'divide') {
                    result = x / y;
                } else {
                    result = 'Unknown operation';
                }
                
                // switch 示例
                let message;
                switch (operation) {
                    case 'add':
                        message = 'Addition result: ' + result;
                        break;
                    case 'subtract':
                        message = 'Subtraction result: ' + result;
                        break;
                    case 'multiply':
                        message = 'Multiplication result: ' + result;
                        break;
                    case 'divide':
                        message = 'Division result: ' + result;
                        break;
                    default:
                        message = 'Unknown operation: ' + operation;
                }
                
                // 数学计算示例
                let powerResult = Math.pow(x, y);
                let sqrtResult = Math.sqrt(x);
                let randomValue = Math.random();
                
                return {
                    basicResult: result,
                    message: message,
                    powerResult: powerResult,
                    sqrtResult: sqrtResult,
                    randomValue: randomValue
                };
            }
            
            // 测试计算函数
            let test1 = calculate(10, 5, 'add');
            log(test1.message);
            log('10^5 = ' + test1.powerResult);
            
            let test2 = calculate(20, 4, 'divide');
            log(test2.message);
            log('√20 ≈ ' + test2.sqrtResult.toFixed(2));
            
            let test3 = calculate(7, 3, 'unknown');
            log(test3.message);
            log('Random value: ' + test3.randomValue);
        ";

try
{
    // 执行 JavaScript 代码
    engine.Execute(jsCode);
}
catch (Exception ex)
{
    Console.WriteLine($"执行 JavaScript 时出错: {ex.Message}");
}
Console.ReadLine();

性能测试代码

// See https://aka.ms/new-console-template for more information

using System.Diagnostics;
using Jint;

Console.WriteLine("Hello, World!");

// 创建 Jint 引擎实例
Engine engine = new Engine();

// 预编译多个代码块
var script1 = Engine.PrepareScript("function add(a, b) { return a + b; }");
var script2 = Engine.PrepareScript("function multiply(a, b) { return a * b; }");
var script3 = Engine.PrepareScript("function factorial(n) { return n <= 1 ? 1 : n * factorial(n - 1); }");

// 执行预编译的代码块

engine.Execute(script1);
engine.Execute(script2);
engine.Execute(script3);

// 测试预编译函数的执行性能
TestPerformance(engine, "add(5, 10)", "加法函数", 1000000);
TestPerformance(engine, "multiply(5, 10)", "乘法函数", 1000000);
TestPerformance(engine, "factorial(10)", "阶乘函数", 100000);

Console.ReadLine();

static void TestPerformance(Engine engine, string expression, string testName, int iterations)
{
    // 预编译测试表达式
    var compiledExpr = Engine.PrepareScript(expression);

    // 修复错误:直接调用 Evaluate 方法获取结果
    Console.WriteLine($"{expression}:{engine.Evaluate(compiledExpr).ToObject()}" );

    var stopwatch = new Stopwatch();
    stopwatch.Start();

    for (int i = 0; i < iterations; i++)
    {
        engine.Execute(compiledExpr);
    }

    stopwatch.Stop();

    Console.WriteLine($"{testName} 执行 {iterations} 次耗时: {stopwatch.ElapsedMilliseconds} ms");
    Console.WriteLine($"平均每次执行时间: {(double)stopwatch.ElapsedMilliseconds / iterations} ms");
}

Windows执行结果:

Linux-Armx64 800MHZ 嵌入式设备执行结果:

Jint安全使用注意事项

Jint 是一个 .NET 的 JavaScript 解释器,在使用时需要注意以下安全性问题:

1. 脚本执行限制

  • ​设置执行超时​:防止无限循环或长时间运行的脚本 var engine = new Engine(options => { options.TimeoutInterval(TimeSpan.FromSeconds(5)); // 5秒超时 });
  • ​限制内存使用​:防止内存耗尽攻击 options.MaxMemory(10_000_000); // 限制最大内存为10MB

2. 沙箱环境隔离

  • ​限制访问.NET类型​:默认情况下Jint允许访问所有.NET类型 options.AllowClr(false); // 禁用CLR访问 // 或限制特定程序集 options.AllowClr(typeof(Console).Assembly); // 只允许访问System.Console
  • ​自定义类型解析器​:精确控制可访问的类型 options.SetTypeResolver(new CustomTypeResolver());

3. 输入验证

  • ​验证脚本内容​:检查是否包含危险操作 if (script.Contains("System.IO.File")) { throw new SecurityException("禁止的文件操作"); }

4. 权限控制

  • ​限制危险API​:如文件系统、网络访问等 // 覆盖默认函数实现 engine.SetValue("fetch", new Func<string, object>(url => { throw new JavaScriptException("网络访问被禁用"); }));

5. 错误处理

  • ​捕获并处理异常​:防止敏感信息泄露 try { engine.Execute(script); } catch (JavaScriptException ex) { // 记录但不暴露内部细节 logger.Error($"脚本执行错误: {ex.Message}"); throw new ApplicationException("脚本执行出错"); }

6. 其他注意事项

  • 避免将用户输入直接作为脚本执行
  • 定期更新Jint到最新版本以修复安全漏洞
  • 考虑使用更严格的模式(如严格模式) options.Strict(true);
标签: 暂无
最后更新:2025-07-18

代号山岳

知之为知之 不知为不知

点赞
< 上一篇

COPYRIGHT © 2099 登峰造极境. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

蜀ICP备14031139号-5

川公网安备51012202000587号