flaw_detector 0.0.1
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/.gitignore +7 -0
- data/.travis.yml +18 -0
- data/Gemfile +4 -0
- data/LICENSE +25 -0
- data/README.md +4 -0
- data/Rakefile +4 -0
- data/bin/flaw_detector +38 -0
- data/ext/insns_ext/extconf.rb +2 -0
- data/ext/insns_ext/insn_ext.rb +7 -0
- data/ext/insns_ext/insns.inc +179 -0
- data/ext/insns_ext/insns_ext.c +36 -0
- data/ext/insns_ext/insns_info.inc +695 -0
- data/flaw_detector.gemspec +26 -0
- data/lib/flaw_detector/code_model/cfg_node.rb +190 -0
- data/lib/flaw_detector/code_model/code_document.rb +63 -0
- data/lib/flaw_detector/code_model/insns_frame.rb +341 -0
- data/lib/flaw_detector/controller.rb +27 -0
- data/lib/flaw_detector/detector/abstract_detector.rb +10 -0
- data/lib/flaw_detector/detector/nil_false_path_flow.rb +179 -0
- data/lib/flaw_detector/formatter/csv_formatter.rb +24 -0
- data/lib/flaw_detector/message.rb +45 -0
- data/lib/flaw_detector/version.rb +3 -0
- data/lib/flaw_detector.rb +169 -0
- data/sample/flaw_in_code.rb +9 -0
- data/spec/lib/flaw_detector_spec.rb +526 -0
- data/spec/spec_helper.rb +7 -0
- metadata +92 -0
@@ -0,0 +1,526 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'yaml'
|
3
|
+
require 'tempfile'
|
4
|
+
|
5
|
+
describe FlawDetector do
|
6
|
+
def flaws_from_comment(filename, code)
|
7
|
+
result = []
|
8
|
+
code.split("\n").each_with_index do |line, lineno_zero_basis|
|
9
|
+
next unless line =~ /#\*\*([\w_]+)(,([\w,]+))*\*\*/
|
10
|
+
lineno = lineno_zero_basis + 1
|
11
|
+
params = if $3 then $3.split(",") else [] end
|
12
|
+
result << FlawDetector::make_info(:file => filename, :line => lineno, :msgid => $1, :params => params)
|
13
|
+
end
|
14
|
+
result
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "::NilVarDereference#analyze" do
|
18
|
+
let(:nvd){ FlawDetector::Detector::NilFalsePathFlow.new}
|
19
|
+
|
20
|
+
context "refer a variable which don't have def" do
|
21
|
+
before{
|
22
|
+
code =<<EOF
|
23
|
+
def nil_var_ref(a)
|
24
|
+
if a
|
25
|
+
i = 1
|
26
|
+
else
|
27
|
+
# i's type is Nil
|
28
|
+
puts(i + 1) # will be detected
|
29
|
+
end
|
30
|
+
return i
|
31
|
+
end
|
32
|
+
nil_var_ref(1)
|
33
|
+
EOF
|
34
|
+
}
|
35
|
+
it 'should detect nil variable dereference'
|
36
|
+
end
|
37
|
+
|
38
|
+
context "NP_ALWAYS_FALSE exists" do
|
39
|
+
let(:code){
|
40
|
+
<<EOF
|
41
|
+
def nil_var_ref(a)
|
42
|
+
if a
|
43
|
+
rl = a + 1
|
44
|
+
rl = 1 + a
|
45
|
+
elsif
|
46
|
+
rl = a + 1 #**NP_ALWAYS_FALSE,a**
|
47
|
+
rl = 1 + a #**NP_ALWAYS_FALSE,a**
|
48
|
+
end
|
49
|
+
return rl
|
50
|
+
end
|
51
|
+
nil_var_ref(1)
|
52
|
+
EOF
|
53
|
+
}
|
54
|
+
let(:dom){FlawDetector::parse(code)}
|
55
|
+
it {expect(nvd.analyze(dom)).to eq(flaws_from_comment("<compiled>", code))}
|
56
|
+
end
|
57
|
+
|
58
|
+
context "Falsecheck of value previously dereferenced" do
|
59
|
+
let(:code){
|
60
|
+
<<EOF
|
61
|
+
a.times do |i|
|
62
|
+
some_method1(i+a)
|
63
|
+
end
|
64
|
+
if a #**RCN_REDUNDANT_FALSECHECK_WOULD_HAVE_BEEN_A_NPE,a**
|
65
|
+
some_method2(a)
|
66
|
+
end
|
67
|
+
EOF
|
68
|
+
}
|
69
|
+
let(:dom){FlawDetector::parse(code)}
|
70
|
+
#it {expect(nvd.analyze(dom)).to eq(flaws_from_comment("<compiled>", code))}
|
71
|
+
it "Falsecheck of value previously dereferenced"
|
72
|
+
end
|
73
|
+
|
74
|
+
context "RCN_REDUNDANT_FALSECHECK_OF_FALSE_VALUE exists" do
|
75
|
+
let(:code) {
|
76
|
+
code =<<EOF
|
77
|
+
def nil_var_ref(a)
|
78
|
+
if a
|
79
|
+
rl = a + 1
|
80
|
+
elsif a #**RCN_REDUNDANT_FALSECHECK_OF_FALSE_VALUE,a,2**
|
81
|
+
rl = 1
|
82
|
+
else
|
83
|
+
rl = 1
|
84
|
+
end
|
85
|
+
end
|
86
|
+
nil_var_ref(1)
|
87
|
+
EOF
|
88
|
+
}
|
89
|
+
let(:dom){FlawDetector::parse(code)}
|
90
|
+
it {expect(nvd.analyze(dom)).to eq(flaws_from_comment("<compiled>", code))}
|
91
|
+
end
|
92
|
+
|
93
|
+
context "complex error exists" do
|
94
|
+
let(:code) {
|
95
|
+
code =<<EOF
|
96
|
+
def nil_var_ref(a)
|
97
|
+
if a
|
98
|
+
rl = a + 1
|
99
|
+
elsif a #**RCN_REDUNDANT_FALSECHECK_OF_FALSE_VALUE,a,2**
|
100
|
+
rl = 1 + a
|
101
|
+
else
|
102
|
+
rl = a + 1 #**NP_ALWAYS_FALSE,a**
|
103
|
+
end
|
104
|
+
end
|
105
|
+
nil_var_ref(1)
|
106
|
+
EOF
|
107
|
+
}
|
108
|
+
let(:dom){FlawDetector::parse(code)}
|
109
|
+
it {expect(nvd.analyze(dom)).to eq(flaws_from_comment("<compiled>", code))}
|
110
|
+
end
|
111
|
+
|
112
|
+
context "complex error exists2" do
|
113
|
+
let(:code) {
|
114
|
+
code =<<EOF
|
115
|
+
def nil_var_ref(a)
|
116
|
+
if a.nil?
|
117
|
+
rl = a + 1 #**NP_ALWAYS_FALSE,a**
|
118
|
+
elsif a.nil? #**RCN_REDUNDANT_FALSECHECK_OF_TRUE_VALUE,a,2**
|
119
|
+
rl = a + 1
|
120
|
+
else
|
121
|
+
rl = 1 + a
|
122
|
+
end
|
123
|
+
end
|
124
|
+
nil_var_ref(1)
|
125
|
+
EOF
|
126
|
+
}
|
127
|
+
let(:dom){FlawDetector::parse(code)}
|
128
|
+
it {expect(nvd.analyze(dom)).to eq(flaws_from_comment("<compiled>", code))}
|
129
|
+
end
|
130
|
+
|
131
|
+
describe "bug fixed" do
|
132
|
+
context "no error1" do
|
133
|
+
let(:code){
|
134
|
+
<<EOF
|
135
|
+
def find_def_insn_index_of_arg(index, insn, argnum=0)
|
136
|
+
if index
|
137
|
+
elsif insn
|
138
|
+
end
|
139
|
+
end
|
140
|
+
EOF
|
141
|
+
}
|
142
|
+
let(:dom){FlawDetector::parse(code)}
|
143
|
+
it {expect(nvd.analyze(dom)).to eq(flaws_from_comment("<compiled>", code))}
|
144
|
+
end
|
145
|
+
context "no RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE" do
|
146
|
+
let(:code){
|
147
|
+
<<EOF
|
148
|
+
namespace = "hogehoge"
|
149
|
+
unnamespaced = self.sub(/^::/, '') if namespace
|
150
|
+
param_key = (namespace ? _singularize(unnamespaced) : singular).freeze
|
151
|
+
EOF
|
152
|
+
}
|
153
|
+
let(:dom){FlawDetector::parse(code)}
|
154
|
+
it {expect(nvd.analyze(dom)).to eq(flaws_from_comment("<compiled>", code))}
|
155
|
+
end
|
156
|
+
context "no undefined method" do
|
157
|
+
let(:code){
|
158
|
+
<<EOF
|
159
|
+
def _parse_validates_options(options) #:nodoc:
|
160
|
+
case options
|
161
|
+
when TrueClass
|
162
|
+
{}
|
163
|
+
when Hash
|
164
|
+
options
|
165
|
+
when Range, Array
|
166
|
+
{ :in => options }
|
167
|
+
else
|
168
|
+
{ :with => options }
|
169
|
+
end
|
170
|
+
end
|
171
|
+
EOF
|
172
|
+
}
|
173
|
+
let(:dom){FlawDetector::parse(code)}
|
174
|
+
it {expect(nvd.analyze(dom)).to eq(flaws_from_comment("<compiled>", code))}
|
175
|
+
end
|
176
|
+
|
177
|
+
context "no undefined method" do
|
178
|
+
let(:code){
|
179
|
+
<<-'EOF'
|
180
|
+
def human_attribute_name(attribute, options = {})
|
181
|
+
defaults = []
|
182
|
+
parts = attribute.to_s.split(".")
|
183
|
+
attribute = parts.pop
|
184
|
+
namespace = parts.join("/") unless parts.empty?
|
185
|
+
|
186
|
+
if namespace
|
187
|
+
lookup_ancestors.each do |klass|
|
188
|
+
defaults << :"#{self.i18n_scope}.attributes.#{klass.model_name.i18n_key}/#{namespace}.#{attribute}"
|
189
|
+
end
|
190
|
+
else
|
191
|
+
lookup_ancestors.each do |klass|
|
192
|
+
defaults << :"#{self.i18n_scope}.attributes.#{klass.model_name.i18n_key}.#{attribute}"
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
defaults << options.delete(:default) if options[:default]
|
197
|
+
end
|
198
|
+
EOF
|
199
|
+
}
|
200
|
+
let(:dom){FlawDetector::parse(code)}
|
201
|
+
it {expect(nvd.analyze(dom)).to eq(flaws_from_comment("<compiled>", code))}
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
describe "::CodeModel::CodeDocument" do
|
206
|
+
context "one branch code in a method" do
|
207
|
+
before {
|
208
|
+
code =<<EOF
|
209
|
+
def nil_var_ref(a)
|
210
|
+
if a
|
211
|
+
i = 1
|
212
|
+
else
|
213
|
+
# i's type is Nil
|
214
|
+
puts(i + 1)
|
215
|
+
end
|
216
|
+
return i
|
217
|
+
end
|
218
|
+
nil_var_ref(1)
|
219
|
+
EOF
|
220
|
+
@dom = FlawDetector::parse(code)
|
221
|
+
}
|
222
|
+
|
223
|
+
it 'should have no branch in the top frame' do
|
224
|
+
cfg = @dom.root.entry_cfg_node
|
225
|
+
branches_cnt = 0
|
226
|
+
cfg.each do |name, node|
|
227
|
+
if node.next_nodes.count >= 2
|
228
|
+
branches_cnt += 1
|
229
|
+
end
|
230
|
+
end
|
231
|
+
expect(branches_cnt).to eq(0)
|
232
|
+
end
|
233
|
+
|
234
|
+
it 'should have one branch in the method frame' do
|
235
|
+
cfg = @dom.select_methods("nil_var_ref").first.entry_cfg_node
|
236
|
+
branches_cnt = 0
|
237
|
+
cfg.each do |name, node|
|
238
|
+
if node.next_nodes.count >= 2
|
239
|
+
branches_cnt += 1
|
240
|
+
end
|
241
|
+
end
|
242
|
+
expect(branches_cnt).to eq(1)
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
context "two branches code in a block in a method" do
|
247
|
+
before {
|
248
|
+
code =<<EOF
|
249
|
+
def one_branch_in_block
|
250
|
+
puts("aaa")
|
251
|
+
1.upto(3) do |num| #a branch
|
252
|
+
if num > 2 #a branch
|
253
|
+
puts(num)
|
254
|
+
end
|
255
|
+
end
|
256
|
+
puts("bbb")
|
257
|
+
end
|
258
|
+
EOF
|
259
|
+
@dom = FlawDetector::parse(code)
|
260
|
+
}
|
261
|
+
|
262
|
+
it 'should have no branch in the top frame' do
|
263
|
+
cfg = @dom.root.entry_cfg_node
|
264
|
+
branches_cnt = 0
|
265
|
+
cfg.each do |name, node|
|
266
|
+
if node.next_nodes.count >= 2
|
267
|
+
branches_cnt += 1
|
268
|
+
end
|
269
|
+
end
|
270
|
+
expect(branches_cnt).to eq(0)
|
271
|
+
end
|
272
|
+
|
273
|
+
it 'should have two branches in the method frame' do
|
274
|
+
cfg = @dom.select_methods("one_branch_in_block").first.entry_cfg_node
|
275
|
+
branches_cnt = 0
|
276
|
+
cfg.each do |name, node|
|
277
|
+
if node.next_nodes.count >= 2
|
278
|
+
branches_cnt += 1
|
279
|
+
end
|
280
|
+
end
|
281
|
+
expect(branches_cnt).to eq(2)
|
282
|
+
end
|
283
|
+
|
284
|
+
it 'each send instruction has obj of [:putspecialobject,1]' do
|
285
|
+
block = @dom.root
|
286
|
+
block.raw_block_data[:body][:insns].each_with_index do |insn, index|
|
287
|
+
next unless insn[0] == :send
|
288
|
+
obj_index,argnum = block.find_insn_index_of_send_obj(index, insn)
|
289
|
+
obj_insn = block.raw_block_data[:body][:insns][obj_index]
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
it 'each send instruction has obj of [:putnil] or [:putobject,1]' do
|
294
|
+
block = @dom.select_methods("one_branch_in_block").first
|
295
|
+
block.raw_block_data[:body][:insns].each_with_index do |insn, index|
|
296
|
+
next unless insn[0] == :send
|
297
|
+
obj_index,argnum = block.find_insn_index_of_send_obj(index, insn)
|
298
|
+
obj_insn = block.raw_block_data[:body][:insns][obj_index]
|
299
|
+
end
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
context "one branch code in a proc in a method" do
|
304
|
+
before {
|
305
|
+
code =<<-EOF
|
306
|
+
def one_branch_in_block
|
307
|
+
pr = proc {|num| p num} #a branch
|
308
|
+
1.upto(3,&pr)
|
309
|
+
puts("bbb")
|
310
|
+
end
|
311
|
+
EOF
|
312
|
+
@dom = FlawDetector::parse(code)
|
313
|
+
}
|
314
|
+
|
315
|
+
it 'should have no branch in the top frame' do
|
316
|
+
cfg = @dom.root.entry_cfg_node
|
317
|
+
branches_cnt = 0
|
318
|
+
cfg.each do |name, node|
|
319
|
+
if node.next_nodes.count >= 2
|
320
|
+
branches_cnt += 1
|
321
|
+
end
|
322
|
+
end
|
323
|
+
expect(branches_cnt).to eq(0)
|
324
|
+
end
|
325
|
+
|
326
|
+
it 'should have one branch in the method frame' do
|
327
|
+
cfg = @dom.select_methods("one_branch_in_block").first.entry_cfg_node
|
328
|
+
branches_cnt = 0
|
329
|
+
cfg.each do |name, node|
|
330
|
+
if node.next_nodes.count >= 2
|
331
|
+
branches_cnt += 1
|
332
|
+
end
|
333
|
+
end
|
334
|
+
expect(branches_cnt).to eq(1)
|
335
|
+
end
|
336
|
+
|
337
|
+
it 'each send instruction has obj of [:putnil] or [:putobject,1]' do
|
338
|
+
block = @dom.select_methods("one_branch_in_block").first
|
339
|
+
block.raw_block_data[:body][:insns].each_with_index do |insn, index|
|
340
|
+
next unless insn[0] == :send
|
341
|
+
obj_index,argnum = block.find_insn_index_of_send_obj(index, insn)
|
342
|
+
obj_insn = block.raw_block_data[:body][:insns][obj_index]
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
end
|
347
|
+
|
348
|
+
context "two branches code in a block in a method of SomeClass" do
|
349
|
+
before {
|
350
|
+
code =<<EOF
|
351
|
+
class SomeClass
|
352
|
+
def one_branch_in_block
|
353
|
+
puts("aaa")
|
354
|
+
1.upto(3) do |num| #a branch
|
355
|
+
if num > 2 #a branch
|
356
|
+
puts(num)
|
357
|
+
end
|
358
|
+
end
|
359
|
+
puts("bbb")
|
360
|
+
end
|
361
|
+
end
|
362
|
+
EOF
|
363
|
+
@dom = FlawDetector::parse(code)
|
364
|
+
}
|
365
|
+
|
366
|
+
it 'should have no branch in the top frame' do
|
367
|
+
cfg = @dom.root.entry_cfg_node
|
368
|
+
branches_cnt = 0
|
369
|
+
cfg.each do |name, node|
|
370
|
+
if node.next_nodes.count >= 2
|
371
|
+
branches_cnt += 1
|
372
|
+
end
|
373
|
+
end
|
374
|
+
expect(branches_cnt).to eq(0)
|
375
|
+
end
|
376
|
+
|
377
|
+
it 'each send instruction has obj of [:putspecialobject,1]' do
|
378
|
+
block = @dom.select_class("SomeClass")
|
379
|
+
block.raw_block_data[:body][:insns].each_with_index do |insn, index|
|
380
|
+
next unless insn[0] == :send
|
381
|
+
obj_index,argnum = block.find_insn_index_of_send_obj(index, insn)
|
382
|
+
obj_insn = block.raw_block_data[:body][:insns][obj_index]
|
383
|
+
end
|
384
|
+
end
|
385
|
+
end
|
386
|
+
|
387
|
+
context "two branches and a throw for return in a block in a method" do
|
388
|
+
before {
|
389
|
+
code =<<EOF
|
390
|
+
def one_branch_in_block
|
391
|
+
puts("aaa")
|
392
|
+
1.upto(3) do |num| #a branch
|
393
|
+
if num > 2 #a branch
|
394
|
+
puts(num)
|
395
|
+
else
|
396
|
+
return #throw
|
397
|
+
end
|
398
|
+
end
|
399
|
+
puts("bbb")
|
400
|
+
end
|
401
|
+
EOF
|
402
|
+
@dom = FlawDetector::parse(code)
|
403
|
+
}
|
404
|
+
|
405
|
+
it 'should have two branches in the method frame'
|
406
|
+
it 'should have outer in the break\'s basic block'
|
407
|
+
end
|
408
|
+
|
409
|
+
context "two branches and a throw for break code in a block in a method" do
|
410
|
+
before {
|
411
|
+
code =<<EOF
|
412
|
+
def one_branch_in_block
|
413
|
+
puts("aaa")
|
414
|
+
1.upto(3) do |num| #a branch
|
415
|
+
if num > 2 #a branch
|
416
|
+
puts(num)
|
417
|
+
else
|
418
|
+
break #throw
|
419
|
+
end
|
420
|
+
end
|
421
|
+
puts("bbb")
|
422
|
+
end
|
423
|
+
EOF
|
424
|
+
@dom = FlawDetector::parse(code)
|
425
|
+
}
|
426
|
+
|
427
|
+
it 'should have two branches in the cfg'
|
428
|
+
it 'should have outer in the break\'s basic block'
|
429
|
+
end
|
430
|
+
|
431
|
+
end
|
432
|
+
|
433
|
+
USE_OPS = [:getlocal, :getspecial, :getdynamic, :getinstancevariable, :getclassvariable, :getconstant, :getglobal]
|
434
|
+
describe "::InsnBlock" do
|
435
|
+
context "one branch code in a method" do
|
436
|
+
before {
|
437
|
+
code =<<EOF
|
438
|
+
def nil_var_ref(a)
|
439
|
+
if a # use at :branchif and arg0
|
440
|
+
rl = a + 1 #*flaw*
|
441
|
+
rl = 1 + a #*flaw*
|
442
|
+
elsif a.nil? #use at send and arg0
|
443
|
+
rl = a + 1 #*flaw*
|
444
|
+
rl = 1 + a #*flaw*
|
445
|
+
else
|
446
|
+
rl = 1 + a #use at optplus
|
447
|
+
rl = a + 1 #use at optplus
|
448
|
+
end
|
449
|
+
some_method(1,2,a) # use at send and arg3
|
450
|
+
a.times do |i| #*flaw*
|
451
|
+
puts(i)
|
452
|
+
end
|
453
|
+
return i
|
454
|
+
end
|
455
|
+
nil_var_ref(1)
|
456
|
+
EOF
|
457
|
+
@dom = FlawDetector::parse(code)
|
458
|
+
}
|
459
|
+
it 'use def' do
|
460
|
+
block = @dom.select_methods("nil_var_ref").first
|
461
|
+
block.raw_block_data[:body][:insns].each_with_index do |insn, index|
|
462
|
+
next unless USE_OPS.include?(insn[0])
|
463
|
+
obj_index,argnum = block.find_use_insn_index_of_ret(index, insn)
|
464
|
+
obj_insn = block.raw_block_data[:body][:insns][obj_index]
|
465
|
+
robj_index,retnum = block.find_def_insn_index_of_arg(obj_index, obj_insn, argnum)
|
466
|
+
robj_insn = block.raw_block_data[:body][:insns][robj_index]
|
467
|
+
expect(robj_index).to eq(index)
|
468
|
+
end
|
469
|
+
a = block.domtree
|
470
|
+
a.each do |key, val|
|
471
|
+
next unless val
|
472
|
+
#p "node: #{key}, idom: #{val.name}"
|
473
|
+
#p val.dominators.count
|
474
|
+
end
|
475
|
+
end
|
476
|
+
|
477
|
+
end
|
478
|
+
|
479
|
+
context "two branches code in a block in a method of SomeClass" do
|
480
|
+
before {
|
481
|
+
code =<<EOF
|
482
|
+
class SomeClass
|
483
|
+
def one_branch_in_block
|
484
|
+
puts("aaa")
|
485
|
+
1.upto(3) do |num| #a branch
|
486
|
+
if num > 2 #a branch
|
487
|
+
puts(num)
|
488
|
+
end
|
489
|
+
end
|
490
|
+
puts("bbb")
|
491
|
+
end
|
492
|
+
end
|
493
|
+
obj = SomeClass.new
|
494
|
+
EOF
|
495
|
+
@dom = FlawDetector::parse(code)
|
496
|
+
}
|
497
|
+
|
498
|
+
it 'should have no branch in the top frame' do
|
499
|
+
block = @dom.root
|
500
|
+
block.raw_block_data[:body][:insns].each_with_index do |insn, index|
|
501
|
+
next unless USE_OPS.include?(insn[0])
|
502
|
+
obj_index,argnum = block.find_use_insn_index_of_ret(index, insn)
|
503
|
+
obj_insn = block.raw_block_data[:body][:insns][obj_index]
|
504
|
+
robj_index,retnum = block.find_def_insn_index_of_arg(obj_index, obj_insn, argnum)
|
505
|
+
robj_insn = block.raw_block_data[:body][:insns][robj_index]
|
506
|
+
expect(robj_index).to eq(index)
|
507
|
+
end
|
508
|
+
end
|
509
|
+
|
510
|
+
it 'each send instruction has obj of [:putspecialobject,1]' do
|
511
|
+
block = @dom.select_class("SomeClass")
|
512
|
+
block.raw_block_data[:body][:insns].each_with_index do |insn, index|
|
513
|
+
next unless USE_OPS.include?(insn[0])
|
514
|
+
obj_index,argnum = block.find_use_insn_index_of_ret(index, insn)
|
515
|
+
obj_insn = block.raw_block_data[:body][:insns][obj_index]
|
516
|
+
robj_index,retnum = block.find_def_insn_index_of_arg(obj_index, obj_insn, argnum)
|
517
|
+
robj_insn = block.raw_block_data[:body][:insns][robj_index]
|
518
|
+
|
519
|
+
expect(robj_index).to eq(index)
|
520
|
+
end
|
521
|
+
end
|
522
|
+
end
|
523
|
+
|
524
|
+
end
|
525
|
+
|
526
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: flaw_detector
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Rikiya Ayukawa
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2013-04-28 00:00:00 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rspec
|
17
|
+
prerelease: false
|
18
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
type: :development
|
25
|
+
version_requirements: *id001
|
26
|
+
description: The tool detects code's flaw, which should be fixed, with static analysis of RubyVM bytecode. Therefore, it works for only ruby 1.9.x. ASAP, I will support ruby 2.0.x .
|
27
|
+
email:
|
28
|
+
- dbc.ginriki@gmail.com
|
29
|
+
executables:
|
30
|
+
- flaw_detector
|
31
|
+
extensions:
|
32
|
+
- ext/insns_ext/extconf.rb
|
33
|
+
extra_rdoc_files: []
|
34
|
+
|
35
|
+
files:
|
36
|
+
- .gitignore
|
37
|
+
- .travis.yml
|
38
|
+
- Gemfile
|
39
|
+
- LICENSE
|
40
|
+
- README.md
|
41
|
+
- Rakefile
|
42
|
+
- bin/flaw_detector
|
43
|
+
- ext/insns_ext/extconf.rb
|
44
|
+
- ext/insns_ext/insn_ext.rb
|
45
|
+
- ext/insns_ext/insns.inc
|
46
|
+
- ext/insns_ext/insns_ext.c
|
47
|
+
- ext/insns_ext/insns_info.inc
|
48
|
+
- flaw_detector.gemspec
|
49
|
+
- lib/flaw_detector.rb
|
50
|
+
- lib/flaw_detector/code_model/cfg_node.rb
|
51
|
+
- lib/flaw_detector/code_model/code_document.rb
|
52
|
+
- lib/flaw_detector/code_model/insns_frame.rb
|
53
|
+
- lib/flaw_detector/controller.rb
|
54
|
+
- lib/flaw_detector/detector/abstract_detector.rb
|
55
|
+
- lib/flaw_detector/detector/nil_false_path_flow.rb
|
56
|
+
- lib/flaw_detector/formatter/csv_formatter.rb
|
57
|
+
- lib/flaw_detector/message.rb
|
58
|
+
- lib/flaw_detector/version.rb
|
59
|
+
- sample/flaw_in_code.rb
|
60
|
+
- spec/lib/flaw_detector_spec.rb
|
61
|
+
- spec/spec_helper.rb
|
62
|
+
homepage: ""
|
63
|
+
licenses: []
|
64
|
+
|
65
|
+
post_install_message:
|
66
|
+
rdoc_options: []
|
67
|
+
|
68
|
+
require_paths:
|
69
|
+
- lib
|
70
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.9.0
|
76
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
|
+
none: false
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: "0"
|
82
|
+
requirements: []
|
83
|
+
|
84
|
+
rubyforge_project: flaw detector
|
85
|
+
rubygems_version: 1.8.12
|
86
|
+
signing_key:
|
87
|
+
specification_version: 3
|
88
|
+
summary: The tool to detect code's flaw with static analysis
|
89
|
+
test_files:
|
90
|
+
- spec/lib/flaw_detector_spec.rb
|
91
|
+
- spec/spec_helper.rb
|
92
|
+
has_rdoc:
|