rufus-decision 0.9 → 1.0

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.
data/lib/rufus/hashes.rb CHANGED
@@ -8,10 +8,10 @@
8
8
  # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
9
  # copies of the Software, and to permit persons to whom the Software is
10
10
  # furnished to do so, subject to the following conditions:
11
- #
11
+ #
12
12
  # The above copyright notice and this permission notice shall be included in
13
13
  # all copies or substantial portions of the Software.
14
- #
14
+ #
15
15
  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
16
  # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
17
  # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -28,158 +28,193 @@
28
28
  # John Mettraux at openwfe.org
29
29
  #
30
30
 
31
- require 'rubygems'
32
- require 'rufus/eval'
31
+ require 'rufus/treechecker'
33
32
 
34
33
 
35
34
  module Rufus
36
35
 
37
- #
38
- # In the Java world, this class would be considered abstract.
39
- #
40
- # It's used to build sequences of filter on hashes (or instances
41
- # that respond to the [], []=, has_key? methods).
42
- #
43
- # It relies on 'prefixed string keys' like "x:y", where the prefix is 'x'
44
- # and the partial key is then 'y'.
45
- #
46
- # Rufus::EvalHashFilter is an implementation of an HashFilter.
47
- #
48
- class HashFilter
49
-
50
- def initialize (parent_hash)
51
-
52
- @parent_hash = parent_hash
53
- end
36
+ #
37
+ # In the Java world, this class would be considered abstract.
38
+ #
39
+ # It's used to build sequences of filter on hashes (or instances
40
+ # that respond to the [], []=, has_key? methods).
41
+ #
42
+ # It relies on 'prefixed string keys' like "x:y", where the prefix is 'x'
43
+ # and the partial key is then 'y'.
44
+ #
45
+ # Rufus::EvalHashFilter is an implementation of an HashFilter.
46
+ #
47
+ class HashFilter
48
+
49
+ def initialize (parent_hash)
50
+
51
+ @parent_hash = parent_hash
52
+ end
54
53
 
55
- def [] (key)
54
+ def [] (key)
56
55
 
57
- p, k = do_split(key)
56
+ p, k = do_split(key)
58
57
 
59
- do_lookup(key, p, k)
60
- end
58
+ do_lookup(key, p, k)
59
+ end
61
60
 
62
- def []= (key, value)
61
+ def []= (key, value)
63
62
 
64
- p, v = do_split(value)
63
+ p, v = do_split(value)
65
64
 
66
- do_put(key, value, p, v)
67
- end
65
+ do_put(key, value, p, v)
66
+ end
68
67
 
69
- protected
68
+ protected
70
69
 
71
- def do_split (element)
70
+ def do_split (element)
72
71
 
73
- return [ nil, element ] unless element.is_a?(String)
72
+ return [ nil, element ] unless element.is_a?(String)
74
73
 
75
- a = element.split(':', 2)
76
- return [ nil ] + a if a.length == 1
77
- a
78
- end
74
+ a = element.split(':', 2)
75
+ return [ nil ] + a if a.length == 1
76
+ a
77
+ end
79
78
 
80
- def handles_prefix? (p)
79
+ def handles_prefix? (p)
81
80
 
82
- false
83
- end
81
+ false
82
+ end
84
83
 
85
- def do_eval (key, p, k)
84
+ def do_eval (key, p, k)
86
85
 
87
- raise NotImplementedError.new(
88
- "missing do_eval(key, p, k) implementation")
89
- end
86
+ raise NotImplementedError.new(
87
+ "missing do_eval(key, p, k) implementation")
88
+ end
90
89
 
91
- def do_lookup (key, p, k)
90
+ def do_lookup (key, p, k)
92
91
 
93
- if handles_prefix?(p)
92
+ if handles_prefix?(p)
94
93
 
95
- do_eval(key, p, k)
94
+ do_eval(key, p, k)
96
95
 
97
- elsif @parent_hash.respond_to?(:do_lookup)
96
+ elsif @parent_hash.respond_to?(:do_lookup)
98
97
 
99
- @parent_hash.do_lookup key, p, k
98
+ @parent_hash.do_lookup key, p, k
100
99
 
101
- else
100
+ else
102
101
 
103
- @parent_hash[key]
104
- end
105
- end
102
+ @parent_hash[key]
103
+ end
104
+ end
106
105
 
107
- def do_put (key, value, p, v)
106
+ def do_put (key, value, p, v)
108
107
 
109
- val = value
108
+ val = value
110
109
 
111
- if handles_prefix?(p)
110
+ if handles_prefix?(p)
112
111
 
113
- @parent_hash[key] = do_eval(value, p, v)
112
+ @parent_hash[key] = do_eval(value, p, v)
114
113
 
115
- elsif @parent_hash.respond_to?(:do_put)
114
+ elsif @parent_hash.respond_to?(:do_put)
116
115
 
117
- @parent_hash.do_put key, value, p, v
116
+ @parent_hash.do_put key, value, p, v
118
117
 
119
- else
118
+ else
120
119
 
121
- @parent_hash[key] = value
122
- end
123
- end
120
+ @parent_hash[key] = value
121
+ end
122
+ end
123
+ end
124
+
125
+ #
126
+ # Implements the r:, ruby: and reval: prefixes in lookups
127
+ #
128
+ # require 'rubygems'
129
+ # require 'rufus/hashes'
130
+ #
131
+ # h = {}
132
+ #
133
+ # eh = Rufus::EvalHashFilter.new(h, 0)
134
+ #
135
+ # eh['a'] = :a
136
+ # p h # => { 'a' => :a }
137
+ #
138
+ # eh['b'] = "r:5 * 5"
139
+ # p h # => { 'a' => :a, 'b' => 25 }
140
+ #
141
+ # assert_equal :a, eh['a']
142
+ # assert_equal 25, eh['b']
143
+ # assert_equal 72, eh['r:36+36']
144
+ #
145
+ class EvalHashFilter < HashFilter
146
+
147
+ def initialize (parent_hash)
148
+
149
+ super parent_hash
124
150
  end
125
151
 
126
- #
127
- # Implements the r:, ruby: and reval: prefixes in lookups
128
- #
129
- # require 'rubygems'
130
- # require 'rufus/hashes'
131
- #
132
- # h = {}
133
- #
134
- # eh = Rufus::EvalHashFilter.new(h, 0)
135
- #
136
- # eh['a'] = :a
137
- # p h # => { 'a' => :a }
138
- #
139
- # eh['b'] = "r:5 * 5"
140
- # p h # => { 'a' => :a, 'b' => 25 }
141
- #
142
- # assert_equal :a, eh['a']
143
- # assert_equal 25, eh['b']
144
- # assert_equal 72, eh['r:36+36']
145
- #
146
- class EvalHashFilter < HashFilter
147
-
148
- def initialize (parent_hash, eval_safety_level=0)
149
-
150
- super parent_hash
151
- @safe_level = eval_safety_level
152
- end
152
+ protected
153
153
 
154
- protected
154
+ RP = [ 'r', 'ruby', 'reval' ]
155
155
 
156
- RP = [ 'r', 'ruby', 'reval' ]
156
+ def handles_prefix? (prefix)
157
157
 
158
- def handles_prefix? (prefix)
158
+ RP.include?(prefix)
159
+ end
159
160
 
160
- RP.include?(prefix)
161
- end
161
+ #
162
+ # Ready for override.
163
+ #
164
+ def get_binding
162
165
 
163
- #
164
- # Ready for override.
165
- #
166
- def get_binding
166
+ binding()
167
+ end
167
168
 
168
- binding()
169
- end
169
+ def do_eval (key, p, k)
170
170
 
171
- def do_eval (key, p, k)
171
+ #Rufus::eval_safely(k, @safe_level, get_binding)
172
+ Rufus::check_and_eval(k, get_binding)
173
+ end
174
+ end
172
175
 
173
- Rufus::eval_safely(k, @safe_level, get_binding)
174
- end
175
- end
176
+ TREECHECKER = Rufus::TreeChecker.new do
176
177
 
177
- private
178
+ exclude_fvccall :abort, :exit, :exit!
179
+ exclude_fvccall :system, :fork, :syscall, :trap, :require, :load
178
180
 
179
- def Rufus.unescape (text)
181
+ #exclude_call_to :class
182
+ exclude_fvcall :private, :public, :protected
180
183
 
181
- text.gsub("\\\\\\$\\{", "\\${")
182
- end
184
+ exclude_def # no method definition
185
+ exclude_eval # no eval, module_eval or instance_eval
186
+ exclude_backquotes # no `rm -fR the/kitchen/sink`
187
+ exclude_alias # no alias or aliast_method
188
+ exclude_global_vars # $vars are off limits
189
+ exclude_module_tinkering # no module opening
190
+ exclude_raise # no raise or throw
191
+
192
+ exclude_rebinding Kernel # no 'k = Kernel'
193
+
194
+ exclude_access_to(
195
+ IO, File, FileUtils, Process, Signal, Thread, ThreadGroup)
196
+
197
+ exclude_class_tinkering
198
+
199
+ exclude_call_to :instance_variable_get, :instance_variable_set
200
+ end
201
+ TREECHECKER.freeze
202
+
203
+ def self.check_and_eval (ruby_code, bndng=binding())
204
+
205
+ TREECHECKER.check(ruby_code)
206
+
207
+ # OK, green for eval...
208
+
209
+ eval(ruby_code, bndng)
210
+ end
211
+
212
+ private
213
+
214
+ def Rufus.unescape (text)
215
+
216
+ text.gsub("\\\\\\$\\{", "\\${")
217
+ end
183
218
 
184
219
  end
185
220
 
@@ -0,0 +1,3 @@
1
+
2
+ require 'rufus/decision'
3
+