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 +4 -4
- data/Gemfile.lock +1 -1
- data/ext/oso-oso/lib/libpolar.dylib +0 -0
- data/ext/oso-oso/lib/libpolar.so +0 -0
- data/ext/oso-oso/lib/polar.dll +0 -0
- data/lib/oso/polar/host.rb +37 -22
- data/lib/oso/polar/polar.rb +3 -3
- data/lib/oso/polar/query.rb +30 -19
- data/lib/oso/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eb279f6dd2c9ea6d862b47f1e6cc109bab429d19
|
4
|
+
data.tar.gz: 8c998ace146905bfb32574fe7d233fa0cb69e240
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1bd787012da6991d59d14877111b4022bc8855d16e3556faf859eaa1e09dcb41cb0e6d91d6d7e52faba7cf2c0a8b7993a784553221afcb6fa9dc7633ea40ec1b
|
7
|
+
data.tar.gz: c26f0285df44ac39e6f10717f0ca5143cf32ca1193133ce1a977885688fe72f0665de74d0c13cbc0d3ab71f4f85aa6fd39719b0872ebc4e738c25aa798fd6887
|
data/Gemfile.lock
CHANGED
Binary file
|
data/ext/oso-oso/lib/libpolar.so
CHANGED
Binary file
|
data/ext/oso-oso/lib/polar.dll
CHANGED
Binary file
|
data/lib/oso/polar/host.rb
CHANGED
@@ -115,29 +115,22 @@ module Oso
|
|
115
115
|
# Construct and cache a Ruby instance.
|
116
116
|
#
|
117
117
|
# @param cls_name [String]
|
118
|
-
# @param
|
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,
|
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
|
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
|
-
|
128
|
+
get_class(cls_name).__send__(:new, *args, **kwargs)
|
132
129
|
end
|
133
|
-
elsif
|
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
|
-
|
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
|
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|
|
203
|
+
{ 'List' => value.map { |el| to_polar(el) } }
|
204
204
|
when value.instance_of?(Hash)
|
205
|
-
{ 'Dictionary' => { 'fields' => value.transform_values { |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|
|
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'
|
data/lib/oso/polar/polar.rb
CHANGED
@@ -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.
|
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.
|
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}
|
223
|
+
puts "#{variable} = #{value.inspect}"
|
224
224
|
end
|
225
225
|
end
|
226
226
|
end
|
data/lib/oso/polar/query.rb
CHANGED
@@ -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 {#
|
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.
|
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
|
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
|
-
|
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.
|
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)}"
|
data/lib/oso/version.rb
CHANGED
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.
|
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-
|
11
|
+
date: 2020-09-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|