rufus-decision 0.9 → 1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+