Security News
Weekly Downloads Now Available in npm Package Search Results
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.
Safely evaluates code (Ruby and others) by sending it through https://eval.in
It's this simple:
require 'eval_in'
result = EvalIn.call 'puts "hello, #{gets}"', stdin: 'world', language: "ruby/mri-2.1"
result.output # => "hello, world\n"
result.exitstatus # => 0
result.url # => "https://eval.in/182711.json"
result.language # => "ruby/mri-2.1"
result.language_friendly # => "Ruby — MRI 2.1"
result.code # => "puts \"hello, \#{gets}\""
result.status # => "OK (0.064 sec real, 0.073 sec wall, 9 MB, 21 syscalls)"
Docs are here.
Ruby |
ruby/mri-1.0 ruby/mri-1.8.7 ruby/mri-1.9.3 ruby/mri-2.0.0 ruby/mri-2.1 |
---|---|
C |
c/gcc-4.4.3 c/gcc-4.9.1 |
C++ |
c++/c++11-gcc-4.9.1 c++/gcc-4.4.3 c++/gcc-4.9.1 |
CoffeeScript |
coffeescript/node-0.10.29-coffee-1.7.1 |
Fortran |
fortran/f95-4.4.3 |
Haskell |
haskell/hugs98-sep-2006 |
Io |
io/io-20131204 |
JavaScript |
javascript/node-0.10.29 |
Lua |
lua/lua-5.1.5 lua/lua-5.2.3 |
OCaml |
ocaml/ocaml-4.01.0 |
PHP |
php/php-5.5.14 |
Pascal |
pascal/fpc-2.6.4 |
Perl |
perl/perl-5.20.0 |
Python |
python/cpython-2.7.8 python/cpython-3.4.1 |
Slash |
slash/slash-head |
x86 Assembly |
assembly/nasm-2.07 |
The mock that is provided will need to be set into place.
If the code is directly doing EvalIn.call(...)
, then it is
a hard dependency, and there is no ablity to set the mock into place.
You will need to structure your code such that it receives the eval_in
service as an argument, or looks it up in some configuration or something
(I strongly prefer the former).
This will allow your test environment to give it a mock that tests that it
works in all the edge cases, or is just generally benign (doesn't make real http request in tests),
your dev environment to give it an EvalIn
that looks so close to the real one you wouldn't even know,
and your prod environment to give it the actual EvalIn
that actually uses the service.
If this is still unclear, here is an example:
# == before: hard dependency prevents you from giving a mock ==
def get_output(code)
EvalIn.call(code, language: 'ruby/mri-2.1').output
end
# == after: receive the thing you're talking to ==
def get_output(eval_in, code)
eval_in.call(code, language: 'ruby/mri-2.1').output
end
# in test, you call like this
output = 'the output'
assert_equal output, get_output(EvalIn::Mock.new(result: EvalIn::Result.new(output: output)), 'some code')
# in prod you call like this:
get_output(EvalIn, params[:code_sample])
# in dev you call like this:
get_output(EvalIn::Mock.new(languages: {'ruby/mri-2.1' => {program: RbConfig.ruby, args: []}}),
params[:code_sample])
# Now those last_two are probably in the same controller, right?
# How do you get it to do the right thing in the right env, then?
# well, you pass it to your controller, the same way you passed the `get_output`
# for example, you might do this in a rack middleware,
# then have it get the service from the `env` hash
# or set it in an environment initializer
For a test or dev env where you don't care about correctness,
just that it does something that looks real,
you can make a mock that has a Result
,
instantiated with any values you care about.
require 'eval_in/mock'
eval_in = EvalIn::Mock.new(result: EvalIn::Result.new(code: 'injected code', output: 'the output'))
eval_in.call('overridden code', language: 'irrelevant')
# => #<EvalIn::Result:0x007fb503a7a5e8
# @code="injected code",
# @exitstatus=-1,
# @language="",
# @language_friendly="",
# @output="the output",
# @status="",
# @url="">
If you want your environment to behave approximately like the real eval_in
,
you can instantiate a mock that knows how to evaluate code locally.
This is necessary, because it doesn't know how to execute these languages
(eval.in does that, it just knows how to talk to eval.in).
So you must provide it with a list of languages and how to execute them
This is probably idea for a dev environment, the results will be the most realistic.
NOTE THAT THIS DOES NOT WORK ON JRUBY
require 'eval_in/mock'
# a mock that can execute Ruby code and C code
eval_in = EvalIn::Mock.new(languages: {
'ruby/mri-2.1' => {program: RbConfig.ruby,
args: []
},
'c/gcc-4.9.1' => {program: RbConfig.ruby,
args: ['-e',
'system "gcc -x c -o /tmp/eval_in_c_example #{ARGV.first}"
exec "/tmp/eval_in_c_example"']
},
})
eval_in.call 'puts "hello from ruby!"; exit 123', language: 'ruby/mri-2.1'
# => #<EvalIn::Result:0x007fb503a7d518
# @code="puts \"hello from ruby!\"; exit 123",
# @exitstatus=123,
# @language="ruby/mri-2.1",
# @language_friendly="ruby/mri-2.1",
# @output="hello from ruby!\n",
# @status="OK (0.072 sec real, 0.085 sec wall, 8 MB, 19 syscalls)",
# @url="https://eval.in/207744.json">
eval_in.call '#include <stdio.h>
int main() {
puts("hello from c!");
}', language: 'c/gcc-4.9.1'
# => #<EvalIn::Result:0x007fb503a850b0
# @code="#include <stdio.h>\nint main() {\n puts(\"hello from c!\");\n}",
# @exitstatus=0,
# @language="c/gcc-4.9.1",
# @language_friendly="c/gcc-4.9.1",
# @output="hello from c!\n",
# @status="OK (0.072 sec real, 0.085 sec wall, 8 MB, 19 syscalls)",
# @url="https://eval.in/207744.json">
You can also provide a callback that will be invoked to handle the request. This is probably ideal for testing more nuanced edge cases that the mock doesn't inherently provide the ability to do.
require 'eval_in/mock'
eval_in = EvalIn::Mock.new on_call: -> code, options { raise EvalIn::RequestError, 'does my code do the right thing in the event of an exception?' }
eval_in.call('code', language: 'any') rescue $! # => #<EvalIn::RequestError: does my code do the right thing in the event of an exception?>
Thanks to Charlie Sommerville for making eval-in.
Thanks to Mon Oui, I partially stole the first version of the implementation from his gem cinch-eval-in
Fork it, make your changes, send me a pull request. Make sure your code is tested and all tests pass.
Run tests with bundle exec rspec
, run integration tests with bundle exec rspec -t integration
.
Copyright (C) 2014 Josh Cheek <josh.cheek@gmail.com>
This program is free software. It comes without any warranty,
to the extent permitted by applicable law.
You can redistribute it and/or modify it under the terms of the
Do What The Fuck You Want To Public License,
Version 2, as published by Sam Hocevar.
See http://www.wtfpl.net/ for more details.
FAQs
Unknown package
We found that eval_in demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.
Security News
A Stanford study reveals 9.5% of engineers contribute almost nothing, costing tech $90B annually, with remote work fueling the rise of "ghost engineers."
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.