calc 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ pkg/*
2
+ .idea
3
+ *.gem
4
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in calc.gemspec
4
+ gemspec
@@ -0,0 +1,14 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ calc (1.0.0)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+
10
+ PLATFORMS
11
+ ruby
12
+
13
+ DEPENDENCIES
14
+ calc!
@@ -0,0 +1,49 @@
1
+ # Calc
2
+
3
+ Calc is safe, simple, pure Ruby mathematical expressions evaluator (calculator) library.
4
+
5
+ Although based on Ruby 'eval', it takes special care to sanitize the expression.
6
+
7
+ Calc supports all basic mathematical operations +, -, \*, / and the power function (through ** operator).
8
+ Calc also supports parenthesis and nesting.
9
+ Calc does NOT support advanced mathematical functions like trigonometry, logarithm, etc.
10
+
11
+ Calc plays well with Rails ActiveModel::Validations.
12
+ If the supplied expression is invalid (nil, blank, or syntax error),
13
+ it returns the expression itself verbatim,
14
+ thus allowing to handle errors via Rails validations.
15
+
16
+ ## Usage
17
+
18
+ require 'calc'
19
+
20
+ Calc.evaluate( "2 + 2" ) # => 4
21
+
22
+ Calc.evaluate( "2 * (1 + 9)" ) # => 20
23
+
24
+ Calc.evaluate( "2 ** (1.0 / 2)" ) # => 1.4142135623730951 (the square of two)
25
+
26
+ Calc.evaluate( "( ( 2 - 3 ) / 13 * ( 50 + 325.843 ) ) ** 3" ) # => -53090815.704202116
27
+
28
+ ## Installation
29
+
30
+ gem install calc
31
+
32
+ ## Using Bundler?
33
+
34
+ Add the following to your Gemfile:
35
+
36
+ gem 'calc'
37
+
38
+ Then run as usual:
39
+
40
+ bundle
41
+
42
+ ## Calc is safe
43
+
44
+ Calc defines a white list of characters allowed in the expression to prevent code injection attacks.
45
+ All letters are outlawed as well as majority of other characters. Calc comes with tests.
46
+
47
+ ## License
48
+
49
+ Copyright (C) 2010 Piotr 'Qertoip' Włodarek. Distributed under the MIT License.
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "calc/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "calc"
7
+ s.version = Calc::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Piotr 'Qertoip' Włodarek"]
10
+ s.email = ["qertoip@gmail.com"]
11
+ s.homepage = "http://github.com/qertoip/calc"
12
+ s.summary = %q{Calculator (mathematical expressions evaluator) library for Ruby}
13
+ s.description = %q{Calc is safe, simple, pure-ruby mathematical expressions evaluator (calculator) library. Although based on Ruby 'eval', it takes special care to sanitize the expression.}
14
+
15
+ s.rubyforge_project = "calc"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+ end
@@ -0,0 +1,35 @@
1
+ module Calc
2
+
3
+ def self.evaluate( unsafe_expression )
4
+ return nil if unsafe_expression.nil?
5
+
6
+ safe_expression = sanitize( unsafe_expression )
7
+
8
+ return unsafe_expression if blank?( safe_expression )
9
+
10
+ begin
11
+ return eval( safe_expression )
12
+ rescue SyntaxError
13
+ # return expression verbatim so ActiveModel::Validations could take care of this
14
+ return unsafe_expression
15
+ end
16
+ end
17
+
18
+ def self.evaluate_to_int( unsafe_expression )
19
+ return nil if unsafe_expression.nil?
20
+ return unsafe_expression if unsafe_expression.blank?
21
+ return evaluate( unsafe_expression ).to_i
22
+ end
23
+
24
+ private
25
+
26
+ def self.sanitize( unsafe_expression )
27
+ allowed_characters = Regexp.escape( '+-*/.()' )
28
+ return unsafe_expression.gsub( /[^\d#{allowed_characters}]/, '' )
29
+ end
30
+
31
+ def self.blank?( s )
32
+ s =~ /^\s*$/
33
+ end
34
+
35
+ end
@@ -0,0 +1,3 @@
1
+ module Calc
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,47 @@
1
+ require File.expand_path( "../../lib/calc", __FILE__ )
2
+ require 'test/unit'
3
+
4
+ class CalcTest < Test::Unit::TestCase
5
+
6
+ # .evaluate()
7
+
8
+ def test_evaluate_returns_correct_value_when_given_valid_expression
9
+ assert_equal( 2, Calc.evaluate( "1+1" ) )
10
+ assert_equal( 6, Calc.evaluate( " 3 * 2 " ) )
11
+ assert_equal( 10, Calc.evaluate( "5 * ( 1 + 1 )" ) )
12
+ assert_equal( 25, Calc.evaluate( "5 ** ( 1 + 1 )" ) )
13
+ assert_equal( 0, Calc.evaluate( "5 ** ( 1 + 1 ) / 5 - 5" ) )
14
+ assert_in_delta( 0.5, Calc.evaluate( "1.0/2" ), 0.0000001 )
15
+ end
16
+
17
+ def test_evaluate_returns_nil_when_given_nil
18
+ assert_nil( Calc.evaluate( nil ) )
19
+ end
20
+
21
+ def test_evaluate_returns_expression_verbatim_when_given_blank_expression
22
+ blank_expression = " \r \n "
23
+ assert_equal( blank_expression, Calc.evaluate( blank_expression ) )
24
+ assert_equal( "", Calc.evaluate( "" ) )
25
+ end
26
+
27
+ def test_evaluate_returns_expression_verbatim_when_given_invalid_expression
28
+ invalid_expression_1 = "2//3"
29
+ assert_equal( invalid_expression_1, Calc.evaluate( invalid_expression_1 ) )
30
+ invalid_expression_2 = "2 * (5 + 4"
31
+ assert_equal( invalid_expression_2, Calc.evaluate( invalid_expression_2 ) )
32
+ end
33
+
34
+ def test_evaluate_is_code_injection_proof
35
+ payload_1 = "raise 'evil'"
36
+ assert_nothing_raised do
37
+ Calc.evaluate( payload_1 )
38
+ end
39
+
40
+ payload_2 = "binding"
41
+ assert_equal( "binding", Calc.evaluate( payload_2 ) ) # returned verbatim - not evaled
42
+
43
+ payload_3 = "__FILE__"
44
+ assert_equal( "__FILE__", Calc.evaluate( payload_3 ) )
45
+ end
46
+
47
+ end
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: calc
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 0
8
+ - 0
9
+ version: 1.0.0
10
+ platform: ruby
11
+ authors:
12
+ - "Piotr 'Qertoip' W\xC5\x82odarek"
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-12-26 00:00:00 +01:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: Calc is safe, simple, pure-ruby mathematical expressions evaluator (calculator) library. Although based on Ruby 'eval', it takes special care to sanitize the expression.
22
+ email:
23
+ - qertoip@gmail.com
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
30
+ files:
31
+ - .gitignore
32
+ - Gemfile
33
+ - Gemfile.lock
34
+ - README.md
35
+ - Rakefile
36
+ - calc.gemspec
37
+ - lib/calc.rb
38
+ - lib/calc/version.rb
39
+ - test/calc.rb
40
+ has_rdoc: true
41
+ homepage: http://github.com/qertoip/calc
42
+ licenses: []
43
+
44
+ post_install_message:
45
+ rdoc_options: []
46
+
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ segments:
55
+ - 0
56
+ version: "0"
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ segments:
63
+ - 0
64
+ version: "0"
65
+ requirements: []
66
+
67
+ rubyforge_project: calc
68
+ rubygems_version: 1.3.7
69
+ signing_key:
70
+ specification_version: 3
71
+ summary: Calculator (mathematical expressions evaluator) library for Ruby
72
+ test_files: []
73
+