duktape

Bindings for the Duktape javascript engine javascript duktape hacktoberfest
0.6.2 released

Duktape.cr

GitHub version Build Status

Duktape.cr provides Crystal bindings to the Duktape javascript engine.

Installation

Duktape.cr is best installed using Shards.

Add this to your shard.yml:

name: example  # your project's name
version: 1.0.0 # your project's version

dependencies:
  duktape:
    github: jessedoyle/duktape.cr
    version: ~> 0.6.2

then execute:

shards install

Shards v0.4.0 or greater will automatically make the native library. You can make the library manually by calling make libduktape from libs/duktape/ext.

Usage

You must first create a Duktape context:

require "duktape"

sbx = Duktape::Sandbox.new

sbx.eval! <<-JS
  var birthYear = 1990;

  function calcAge(birthYear){
    var current = new Date();
    var year = current.getFullYear();
    return year - birthYear;
  }

  print("You are " + calcAge(birthYear) + " years old.");
JS

An overwhelming majority of the Duktape API has been implemented. You can call the API functions directly on a Duktape::Sandbox or Duktape::Context instance:

sbx = Duktape::Sandbox.new
sbx.push_global_object   # [ global ]
sbx.push_string "Math"   # [ global "Math" ]
sbx.get_prop -2          # [ global Math ]
sbx.push_string "PI"     # [ global Math "PI" ]
sbx.get_prop -2          # [ global Math PI ]
pi = sbx.get_number -1
puts "PI: #{pi}"         # => PI: 3.14159
sbx.pop_3

Eval vs Eval!

All of the evaluation API methods have a corresponding bang-method (!). The bang method calls will raise when a javascript error occurs, the non-bang methods will not raise on invalid javascript.

For example:

sbx = Duktape::Context.new
sbx.eval <<-JS
  var a =
JS

will not raise any errors, but will return a non-zero error code.

The following code:

sbx = Duktape::Context.new
sbx.eval! <<-JS
  __invalid();
JS

will raise Duktape::Error "SyntaxError".

Sandbox vs Context

You should only execute untrusted javascript code from within a Duktape::Sandbox instance. A sandbox isolates code from insecure operations such as Duktape's internal require mechanism and the Duktape global javascript object.

Creating a Duktape::Context gives code access to internal Duktape properties:

ctx = Duktape::Context.new
ctx.eval! <<-JS
  print(Duktape.version);
JS

Setting a Timeout

Duktape::Sandbox instances may optionally take an execution timeout limit in milliseconds. This provides protection against infinite loops when executing untrusted code.

A Duktape::Error "RangeError" exception is raised when the following code executes for longer than specified:

sbx = Duktape::Sandbox.new 500 # 500ms execution time limit
sbx.eval! "while (true) {}"    # => RangeError

Calling Crystal Code from Javascript

Note: This functionality is considered experimental and syntax/functionality may change dramatically between releases.

It is possible to call Crystal code from your javascript:

  sbx = Duktape::Sandbox.new

  sbx.push_global_object

  sbx.push_proc(2) do |ptr| # 2 stack arguments
    env = Duktape::Sandbox.new ptr
    a = env.get_number 0
    b = env.get_number 1
    env.push_number a + b
    env.return 1 # return success
  end

  sbx.put_prop_string -2, "adder"
  sbx.eval! "print(adder(2, 3));" # => 5

Contributing

I'll accept any pull requests that are well tested for bugs/features with Duktape.cr.

You should fork the main repo, create a feature branch, write tests and submit a pull request.

License

Duktape.cr is licensed under the MIT License. Please see LICENSE for details.

duktape:
  github: jessedoyle/duktape.cr
  version: ~> 0.6.2
License MIT
Crystal none

Authors

Dependencies 0

Development Dependencies 0

Last synced .
search fire star recently