oso-oso 0.5.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cf2c949f57a56b4849f24ed9593c78da58baa5a0
4
- data.tar.gz: 31ac99dcfa3bba1bbbee68474a3fe3702fb7484d
3
+ metadata.gz: eb279f6dd2c9ea6d862b47f1e6cc109bab429d19
4
+ data.tar.gz: 8c998ace146905bfb32574fe7d233fa0cb69e240
5
5
  SHA512:
6
- metadata.gz: f1708d82f2531d50456ddcadb967bd024414700808e81b440836eb344f542cfda46af651382a6445a098dce9cf1e1c63c6802df73e3f97713a819d0b07ef5aae
7
- data.tar.gz: d96b91d530555ed98d040c2d3c8e8e0adbdffa352cef6bd49c22e6f225c16bfa9f4c488d37468201e16e0950791581621737b94f1b9d5ffc8b8c4dffeaa4e656
6
+ metadata.gz: 1bd787012da6991d59d14877111b4022bc8855d16e3556faf859eaa1e09dcb41cb0e6d91d6d7e52faba7cf2c0a8b7993a784553221afcb6fa9dc7633ea40ec1b
7
+ data.tar.gz: c26f0285df44ac39e6f10717f0ca5143cf32ca1193133ce1a977885688fe72f0665de74d0c13cbc0d3ab71f4f85aa6fd39719b0872ebc4e738c25aa798fd6887
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- oso-oso (0.5.1)
4
+ oso-oso (0.5.2)
5
5
  ffi (~> 1.0)
6
6
 
7
7
  GEM
Binary file
Binary file
@@ -115,29 +115,22 @@ module Oso
115
115
  # Construct and cache a Ruby instance.
116
116
  #
117
117
  # @param cls_name [String]
118
- # @param initargs [Hash<String, Hash>]
118
+ # @param args [Array<Object>]
119
+ # @param kwargs [Hash<String, Object>]
119
120
  # @param id [Integer]
120
121
  # @raise [PolarRuntimeError] if instance construction fails.
121
- def make_instance(cls_name, initargs:, id:) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
122
+ def make_instance(cls_name, args:, kwargs:, id:) # rubocop:disable Metrics/MethodLength
122
123
  constructor = get_constructor(cls_name)
123
124
  instance = if constructor == :new
124
- if initargs.empty?
125
- get_class(cls_name).__send__(:new)
126
- elsif initargs.is_a? Array
127
- get_class(cls_name).__send__(:new, *initargs)
128
- elsif initargs.is_a? Hash
129
- get_class(cls_name).__send__(:new, **initargs)
125
+ if kwargs.empty?
126
+ get_class(cls_name).__send__(:new, *args)
130
127
  else
131
- raise PolarRuntimeError, "Bad initargs: #{initargs}"
128
+ get_class(cls_name).__send__(:new, *args, **kwargs)
132
129
  end
133
- elsif initargs.empty?
134
- constructor.call
135
- elsif initargs.is_a? Array
136
- constructor.call(*initargs)
137
- elsif initargs.is_a? Hash
138
- constructor.call(**initargs)
130
+ elsif kwargs.empty?
131
+ constructor.call(*args)
139
132
  else
140
- raise PolarRuntimeError, "Bad initargs: #{initargs}"
133
+ constructor.call(*args, **kwargs)
141
134
  end
142
135
  cache_instance(instance, id: id)
143
136
  rescue StandardError => e
@@ -189,22 +182,29 @@ module Oso
189
182
  #
190
183
  # @param value [Object]
191
184
  # @return [Hash<String, Object>]
192
- def to_polar_term(value) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
185
+ def to_polar(value) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
193
186
  value = case true # rubocop:disable Lint/LiteralAsCondition
194
187
  when value.instance_of?(TrueClass) || value.instance_of?(FalseClass)
195
188
  { 'Boolean' => value }
196
189
  when value.instance_of?(Integer)
197
190
  { 'Number' => { 'Integer' => value } }
198
191
  when value.instance_of?(Float)
192
+ if value == Float::INFINITY
193
+ value = 'Infinity'
194
+ elsif value == -Float::INFINITY
195
+ value = '-Infinity'
196
+ elsif value.nan?
197
+ value = 'NaN'
198
+ end
199
199
  { 'Number' => { 'Float' => value } }
200
200
  when value.instance_of?(String)
201
201
  { 'String' => value }
202
202
  when value.instance_of?(Array)
203
- { 'List' => value.map { |el| to_polar_term(el) } }
203
+ { 'List' => value.map { |el| to_polar(el) } }
204
204
  when value.instance_of?(Hash)
205
- { 'Dictionary' => { 'fields' => value.transform_values { |v| to_polar_term(v) } } }
205
+ { 'Dictionary' => { 'fields' => value.transform_values { |v| to_polar(v) } } }
206
206
  when value.instance_of?(Predicate)
207
- { 'Call' => { 'name' => value.name, 'args' => value.args.map { |el| to_polar_term(el) } } }
207
+ { 'Call' => { 'name' => value.name, 'args' => value.args.map { |el| to_polar(el) } } }
208
208
  when value.instance_of?(Variable)
209
209
  # This is supported so that we can query for unbound variables
210
210
  { 'Variable' => value }
@@ -222,13 +222,28 @@ module Oso
222
222
  # @option data [Hash<String, Object>] :value
223
223
  # @return [Object]
224
224
  # @raise [UnexpectedPolarTypeError] if type cannot be converted to Ruby.
225
- def to_ruby(data) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
225
+ def to_ruby(data) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
226
226
  tag, value = data['value'].first
227
227
  case tag
228
228
  when 'String', 'Boolean'
229
229
  value
230
230
  when 'Number'
231
- value.values.first
231
+ num = value.values.first
232
+ if value.key? 'Float'
233
+ case num
234
+ when 'Infinity'
235
+ return Float::INFINITY
236
+ when '-Infinity'
237
+ return -Float::INFINITY
238
+ when 'NaN'
239
+ return Float::NAN
240
+ else
241
+ unless value['Float'].is_a? Float # rubocop:disable Metrics/BlockNesting
242
+ raise PolarRuntimeError, "Expected a floating point number, got \"#{value['Float']}\""
243
+ end
244
+ end
245
+ end
246
+ num
232
247
  when 'List'
233
248
  value.map { |el| to_ruby(el) }
234
249
  when 'Dictionary'
@@ -110,7 +110,7 @@ module Oso
110
110
  when String
111
111
  ffi_query = ffi_polar.new_query_from_str(query)
112
112
  when Predicate
113
- ffi_query = ffi_polar.new_query_from_term(new_host.to_polar_term(query))
113
+ ffi_query = ffi_polar.new_query_from_term(new_host.to_polar(query))
114
114
  else
115
115
  raise InvalidQueryTypeError
116
116
  end
@@ -140,7 +140,7 @@ module Oso
140
140
  end
141
141
 
142
142
  def register_constant(name, value:)
143
- ffi_polar.register_constant(name, value: host.to_polar_term(value))
143
+ ffi_polar.register_constant(name, value: host.to_polar(value))
144
144
  end
145
145
 
146
146
  # Start a REPL session.
@@ -220,7 +220,7 @@ module Oso
220
220
  puts true
221
221
  else
222
222
  result.each do |variable, value|
223
- puts "#{variable} => #{value.inspect}"
223
+ puts "#{variable} = #{value.inspect}"
224
224
  end
225
225
  end
226
226
  end
@@ -68,13 +68,13 @@ module Oso
68
68
  ffi_query.call_result(result, call_id: call_id)
69
69
  end
70
70
 
71
- # Retrieve the next result from a registered call and pass it to {#to_polar_term}.
71
+ # Retrieve the next result from a registered call and pass it to {#to_polar}.
72
72
  #
73
73
  # @param id [Integer]
74
74
  # @return [Hash]
75
75
  # @raise [StopIteration] if the call has been exhausted.
76
76
  def next_call_result(id)
77
- host.to_polar_term(calls[id].next)
77
+ host.to_polar(calls[id].next)
78
78
  end
79
79
 
80
80
  # Send application error across FFI boundary.
@@ -104,12 +104,37 @@ module Oso
104
104
  call_result(nil, call_id: call_id)
105
105
  end
106
106
 
107
+ def handle_make_external(data) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
108
+ id = data['instance_id']
109
+ raise DuplicateInstanceRegistrationError, id if host.instance? id
110
+
111
+ constructor = data['constructor']['value']
112
+ if constructor.key? 'InstanceLiteral'
113
+ cls_name = constructor['InstanceLiteral']['tag']
114
+ fields = constructor['InstanceLiteral']['fields']['fields']
115
+ kwargs = Hash[fields.map { |k, v| [k.to_sym, host.to_ruby(v)] }]
116
+ args = []
117
+ elsif constructor.key? 'Call'
118
+ cls_name = constructor['Call']['name']
119
+ args = constructor['Call']['args'].map { |arg| host.to_ruby(arg) }
120
+ kwargs = constructor['Call']['kwargs']
121
+ kwargs = if kwargs.nil?
122
+ {}
123
+ else
124
+ Hash[kwargs.map { |k, v| [k.to_sym, host.to_ruby(v)] }]
125
+ end
126
+ else
127
+ raise InvalidConstructorError
128
+ end
129
+ host.make_instance(cls_name, args: args, kwargs: kwargs, id: id)
130
+ end
131
+
107
132
  # Create a generator that can be polled to advance the query loop.
108
133
  #
109
134
  # @yieldparam [Hash<String, Object>]
110
135
  # @return [Enumerator]
111
136
  # @raise [Error] if any of the FFI calls raise one.
112
- def start # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
137
+ def start # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
113
138
  Enumerator.new do |yielder| # rubocop:disable Metrics/BlockLength
114
139
  loop do # rubocop:disable Metrics/BlockLength
115
140
  event = ffi_query.next_event
@@ -119,21 +144,7 @@ module Oso
119
144
  when 'Result'
120
145
  yielder << event.data['bindings'].transform_values { |v| host.to_ruby(v) }
121
146
  when 'MakeExternal'
122
- id = event.data['instance_id']
123
- raise DuplicateInstanceRegistrationError, id if host.instance? id
124
-
125
- constructor = event.data['constructor']['value']
126
- if constructor.key? 'InstanceLiteral'
127
- cls_name = constructor['InstanceLiteral']['tag']
128
- fields = constructor['InstanceLiteral']['fields']['fields']
129
- initargs = Hash[fields.map { |k, v| [k.to_sym, host.to_ruby(v)] }]
130
- elsif constructor.key? 'Call'
131
- cls_name = constructor['Call']['name']
132
- initargs = constructor['Call']['args'].map { |arg| host.to_ruby(arg) }
133
- else
134
- raise InvalidConstructorError
135
- end
136
- host.make_instance(cls_name, initargs: initargs, id: id)
147
+ handle_make_external(event.data)
137
148
  when 'ExternalCall'
138
149
  call_id = event.data['call_id']
139
150
  instance = event.data['instance']
@@ -164,7 +175,7 @@ module Oso
164
175
  rescue EOFError
165
176
  next
166
177
  end
167
- command = JSON.dump(host.to_polar_term(input))
178
+ command = JSON.dump(host.to_polar(input))
168
179
  ffi_query.debug_command(command)
169
180
  else
170
181
  raise "Unhandled event: #{JSON.dump(event.inspect)}"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Oso
4
- VERSION = '0.5.1'
4
+ VERSION = '0.5.2'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oso-oso
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oso Security, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-01 00:00:00.000000000 Z
11
+ date: 2020-09-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi