Skip to content

Commit

Permalink
Merge pull request #231 from looker-open-source/fix-vuln
Browse files Browse the repository at this point in the history
fix: remove usage of eval to satisfy vulnerability scanners
  • Loading branch information
drstrangelooker authored Nov 8, 2023
2 parents e6e70e1 + 70f1e27 commit a6caa72
Show file tree
Hide file tree
Showing 24 changed files with 58 additions and 178 deletions.
89 changes: 19 additions & 70 deletions lib/gzr/command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -400,78 +400,27 @@ def field_names(opt_fields)
end

##
# This method will accept a field name in a format like 'c.e.g'
# and convert it into 'c&.e&.g', which can be evaluated to get
# the value of g, or nil if any intermediate value is nil.

def field_expression(name)
parts = name.split(/\./)
parts.join('&.')
end

def field_expression_hash(name)
parts = name.split(/\./)
parts.collect { |p| "&.fetch(:#{p},nil)" }.join('')
end


# This version of field names yields an expression that can be evaluated against a hash structure
# like this one...
#
# data&.fetch(:a,nil)
# val1
# data&.fetch(:b,nil)
# val2
# data&.fetch(:c,nil)&.fetch(:d,nil)
# val3
# data&.fetch(:c,nil)&.fetch(:e,nil)&.fetch(:f,nil)
# val4
# data&.fetch(:c,nil)&.fetch(:e,nil)&.fetch(:g,nil)
# val5
# data&.fetch(:h,nil)
# val6
#
# data =
# {
# a: "val",
# b: "val",
# c: {
# d: "val",
# e: {
# f: "val",
# g: "val"
# }
# },
# h: "val"
# }
#
# field_names_hash(fields).each do |field|
# puts "data#{field}"
# puts eval "data#{field}"
# end

def field_names_hash(opt_fields)
fields = []
token_stack = []
last_token = false
tokens = opt_fields.split /(\(|,|\))/
tokens << nil
tokens.each do |t|
if t == '(' then
token_stack.push(last_token)
elsif t.nil? || t == ',' then
fields << "&.fetch(:#{(token_stack + [last_token]).join(',nil)&.fetch(:')},nil)" if last_token
elsif t.empty? then
next
elsif t == ')' then
fields << "&.fetch(:#{(token_stack + [last_token]).join(',nil)&.fetch(:')},nil)" if last_token
token_stack.pop
last_token = false
else
last_token = t
# This method will accept an array of field name expressions in a format like 'c.e.g'
# and convert each into the value of g, or nil if any intermediate value is nil.

def field_expressions_eval(expressions, data)
expressions.map do |exp|
nesting = exp.split('.')
current = data
while (nesting.length > 0) do
field = nesting.shift
if (current.kind_of?(Hash))
value = current.fetch(field.to_sym,nil)
current = value
else
current = nil
end
end
if current.kind_of? Array
current = current.join("\n")
end
current
end
fields
end

##
Expand Down
5 changes: 1 addition & 4 deletions lib/gzr/commands/alert/ls.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,8 @@ def execute(input: $stdin, output: $stdout)
table_hash = Hash.new
fields = field_names(@options[:fields])
table_hash[:header] = fields unless @options[:plain]
expressions = fields.collect { |fn| field_expression_hash(fn) }
table_hash[:rows] = data.map do |row|
expressions.collect do |e|
eval "row#{e}"
end
field_expressions_eval(fields,row)
end
table = TTY::Table.new(table_hash)
alignments = fields.collect do |k|
Expand Down
5 changes: 1 addition & 4 deletions lib/gzr/commands/alert/notifications.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,8 @@ def execute(input: $stdin, output: $stdout)
table_hash = Hash.new
fields = field_names(@fields)
table_hash[:header] = fields unless @options[:plain]
expressions = fields.collect { |fn| field_expression_hash(fn) }
table_hash[:rows] = data.map do |row|
expressions.collect do |e|
eval "row#{e}"
end
field_expressions_eval(fields,row)
end
table = TTY::Table.new(table_hash)
alignments = fields.collect do |k|
Expand Down
5 changes: 1 addition & 4 deletions lib/gzr/commands/attribute/ls.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,8 @@ def execute(input: $stdin, output: $stdout)
table_hash = Hash.new
fields = field_names(@options[:fields])
table_hash[:header] = fields unless @options[:plain]
expressions = fields.collect { |fn| field_expression_hash(fn) }
table_hash[:rows] = data.map do |row|
expressions.collect do |e|
eval "row#{e}"
end
field_expressions_eval(fields,row)
end
table = TTY::Table.new(table_hash)
alignments = fields.collect do |k|
Expand Down
5 changes: 1 addition & 4 deletions lib/gzr/commands/connection/dialects.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,8 @@ def execute(input: $stdin, output: $stdout)
table_hash = Hash.new
fields = field_names(@options[:fields])
table_hash[:header] = data[0].keys unless @options[:plain]
expressions = fields.collect { |fn| field_expression_hash(fn) }
table_hash[:rows] = data.map do |row|
expressions.collect do |e|
eval "row#{e}"
end
field_expressions_eval(fields,row)
end
table = TTY::Table.new(table_hash)
alignments = fields.collect do |k|
Expand Down
5 changes: 1 addition & 4 deletions lib/gzr/commands/connection/ls.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,8 @@ def execute(input: $stdin, output: $stdout)
table_hash = Hash.new
fields = field_names(@options[:fields])
table_hash[:header] = fields unless @options[:plain]
expressions = fields.collect { |fn| field_expression_hash(fn) }
table_hash[:rows] = data.map do |row|
expressions.collect do |e|
eval "row#{e}"
end
field_expressions_eval(fields,row)
end
table = TTY::Table.new(table_hash)
alignments = fields.collect do |k|
Expand Down
5 changes: 1 addition & 4 deletions lib/gzr/commands/connection/test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,8 @@ def execute(input: $stdin, output: $stdout)
table_hash = Hash.new
fields = field_names(@options[:fields])
table_hash[:header] = fields unless @options[:plain]
expressions = fields.collect { |fn| field_expression_hash(fn) }
table_hash[:rows] = data.map do |row|
expressions.collect do |e|
eval "row#{e}"
end
field_expressions_eval(fields,row)
end
table = TTY::Table.new(table_hash)
alignments = fields.collect do |k|
Expand Down
12 changes: 3 additions & 9 deletions lib/gzr/commands/folder/top.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,10 @@ def execute(input: $stdin, output: $stdout)
table_hash = Hash.new
fields = field_names(@options[:fields])
table_hash[:header] = fields unless @options[:plain]
expressions = fields.collect { |fn| field_expression_hash(fn) }
rows = []
folders.each do |h|
if ( h[:is_shared_root] || h[:is_users_root] || h[:is_embed_shared_root] || h[:is_embed_users_root] ) then
rows << expressions.collect do |e|
eval "h#{e}"
end
end
data = folders.select { |h| ( h[:is_shared_root] || h[:is_users_root] || h[:is_embed_shared_root] || h[:is_embed_users_root] )}
table_hash[:rows] = data.map do |row|
field_expressions_eval(fields,row)
end
table_hash[:rows] = rows
table = TTY::Table.new(table_hash)
begin
if @options[:csv] then
Expand Down
5 changes: 1 addition & 4 deletions lib/gzr/commands/group/ls.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,8 @@ def execute(input: $stdin, output: $stdout)
table_hash = Hash.new
fields = field_names(@options[:fields])
table_hash[:header] = fields unless @options[:plain]
expressions = fields.collect { |fn| field_expression_hash(fn) }
table_hash[:rows] = data.map do |row|
expressions.collect do |e|
eval "row#{e}"
end
field_expressions_eval(fields,row)
end
table = TTY::Table.new(table_hash)
alignments = fields.collect do |k|
Expand Down
5 changes: 1 addition & 4 deletions lib/gzr/commands/group/member_groups.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,8 @@ def execute(input: $stdin, output: $stdout)
table_hash = Hash.new
fields = field_names(@options[:fields])
table_hash[:header] = fields unless @options[:plain]
expressions = fields.collect { |fn| field_expression_hash(fn) }
table_hash[:rows] = data.map do |row|
expressions.collect do |e|
eval "row#{e}"
end
field_expressions_eval(fields,row)
end
table = TTY::Table.new(table_hash)
alignments = fields.collect do |k|
Expand Down
5 changes: 1 addition & 4 deletions lib/gzr/commands/group/member_users.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,8 @@ def execute(input: $stdin, output: $stdout)
table_hash = Hash.new
fields = field_names(@options[:fields])
table_hash[:header] = fields unless @options[:plain]
expressions = fields.collect { |fn| field_expression_hash(fn) }
table_hash[:rows] = data.map do |row|
expressions.collect do |e|
eval "row#{e}"
end
field_expressions_eval(fields,row)
end
table = TTY::Table.new(table_hash)
alignments = fields.collect do |k|
Expand Down
5 changes: 1 addition & 4 deletions lib/gzr/commands/model/ls.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,8 @@ def execute(input: $stdin, output: $stdout)
table_hash = Hash.new
fields = field_names(@options[:fields])
table_hash[:header] = fields unless @options[:plain]
expressions = fields.collect { |fn| field_expression_hash(fn) }
table_hash[:rows] = data.map do |row|
expressions.collect do |e|
eval "row#{e}"
end
field_expressions_eval(fields,row)
end
table = TTY::Table.new(table_hash)
alignments = fields.collect do |k|
Expand Down
7 changes: 2 additions & 5 deletions lib/gzr/commands/model/set/ls.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,8 @@ def execute(input: $stdin, output: $stdout)
table_hash = Hash.new
fields = field_names(@options[:fields])
table_hash[:header] = fields unless @options[:plain]
expressions = fields.collect { |fn| field_expression_hash(fn) }
table_hash[:rows] = data.map do |row|
expressions.collect do |e|
eval "row#{e}"
end
field_expressions_eval(fields,row)
end
table = TTY::Table.new(table_hash)
alignments = fields.collect do |k|
Expand All @@ -62,7 +59,7 @@ def execute(input: $stdin, output: $stdout)
if @options[:csv] then
output.puts render_csv(table)
else
output.puts table.render(if @options[:plain] then :basic else :ascii end, alignments: alignments, width: @options[:width] || TTY::Screen.width)
output.puts table.render(if @options[:plain] then :basic else :ascii end, multiline: true, alignments: alignments, width: @options[:width] || TTY::Screen.width)
end
end if table
end
Expand Down
5 changes: 1 addition & 4 deletions lib/gzr/commands/permission/ls.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,8 @@ def execute(input: $stdin, output: $stdout)
table_hash = Hash.new
fields = field_names('permission,parent,description')
table_hash[:header] = fields unless @options[:plain]
expressions = fields.collect { |fn| field_expression_hash(fn) }
table_hash[:rows] = data.map do |row|
expressions.collect do |e|
eval "row#{e}"
end
field_expressions_eval(fields,row)
end
table = TTY::Table.new(table_hash)
alignments = fields.collect do |k|
Expand Down
9 changes: 1 addition & 8 deletions lib/gzr/commands/permission/set/ls.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,8 @@ def execute(input: $stdin, output: $stdout)
table_hash = Hash.new
fields = field_names(@options[:fields])
table_hash[:header] = fields unless @options[:plain]
expressions = fields.collect { |fn| field_expression_hash(fn) }
table_hash[:rows] = data.map do |row|
expressions.collect do |e|
exp = eval "row#{e}"
if exp.kind_of? Array
exp = exp.join "\n"
end
exp
end
field_expressions_eval(fields,row)
end
table = TTY::Table.new(table_hash)
alignments = fields.collect do |k|
Expand Down
5 changes: 2 additions & 3 deletions lib/gzr/commands/plan/failures.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ def execute(input: $stdin, output: $stdout)
}
data = run_inline_query(query)
fields = query[:fields]
expressions = fields.collect { |f| "[:'#{f}']" }
begin
say_ok "No plans found in history"
return nil
Expand All @@ -80,8 +79,8 @@ def execute(input: $stdin, output: $stdout)
next if row[:'scheduled_plan.id'] == prior_plan_id
prior_plan_id = row[:'scheduled_plan.id']
next if row[:'scheduled_job.status'] == 'success'
expressions.collect do |e|
eval "row#{e}"
fields.collect do |f|
row.fetch(f.to_sym, nil)
end
end.compact
table = TTY::Table.new(table_hash)
Expand Down
10 changes: 6 additions & 4 deletions lib/gzr/commands/plan/ls.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,9 @@ def execute(input: $stdin, output: $stdout)
}
data = run_inline_query(query)
fields = query[:fields]
expressions = fields.collect { |f| "[:'#{f}']" }
else
data = query_all_scheduled_plans("all",@options[:fields])
fields = field_names(@options[:fields])
expressions = fields.collect { |fn| field_expression_hash(fn) }
end
begin
say_ok "No plans found"
Expand All @@ -78,8 +76,12 @@ def execute(input: $stdin, output: $stdout)
table_hash = Hash.new
table_hash[:header] = fields unless @options[:plain]
table_hash[:rows] = data.map do |row|
expressions.collect do |e|
eval "row#{e}"
if @options[:disabled] then
fields.collect do |f|
row.fetch(f.to_sym, nil)
end
else
field_expressions_eval(fields,row)
end
end
table = TTY::Table.new(table_hash)
Expand Down
5 changes: 1 addition & 4 deletions lib/gzr/commands/project/branch.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,8 @@ def execute(input: $stdin, output: $stdout)
table_hash = Hash.new
fields = field_names(@options[:fields])
table_hash[:header] = fields unless @options[:plain]
expressions = fields.collect { |fn| field_expression_hash(fn) }
table_hash[:rows] = data.map do |row|
expressions.collect do |e|
eval "row#{e}"
end
field_expressions_eval(fields,row)
end
table = TTY::Table.new(table_hash)
alignments = fields.collect do |k|
Expand Down
5 changes: 1 addition & 4 deletions lib/gzr/commands/project/ls.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,8 @@ def execute(input: $stdin, output: $stdout)
table_hash = Hash.new
fields = field_names(@options[:fields])
table_hash[:header] = fields unless @options[:plain]
expressions = fields.collect { |fn| field_expression_hash(fn) }
table_hash[:rows] = data.map do |row|
expressions.collect do |e|
eval "row#{e}"
end
field_expressions_eval(fields,row)
end
table = TTY::Table.new(table_hash)
alignments = fields.collect do |k|
Expand Down
7 changes: 1 addition & 6 deletions lib/gzr/commands/role/group_ls.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,8 @@ def execute(input: $stdin, output: $stdout)
table_hash = Hash.new
fields = field_names(@options[:fields])
table_hash[:header] = fields unless @options[:plain]
expressions = fields.collect { |fn| field_expression_hash(fn) }
table_hash[:rows] = data.map do |row|
expressions.collect do |e|
v = eval "row#{e}"
next (v.join "\n") if v.kind_of? Array
v
end
field_expressions_eval(fields,row)
end
table = TTY::Table.new(table_hash)
alignments = fields.collect do |k|
Expand Down
Loading

0 comments on commit a6caa72

Please sign in to comment.