Skip to content

Commit 36a6c96

Browse files
Merge pull request #100 from AjayBrahmakshatriya/master
Fixed RCE bug and merged loop inversion changes
2 parents 0416332 + ef56a5a commit 36a6c96

File tree

12 files changed

+269
-35
lines changed

12 files changed

+269
-35
lines changed

include/blocks/if_switcher.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
#ifndef IF_SWITCHER_H
22
#define IF_SWITCHER_H
3-
#include "blocks/block_visitor.h"
3+
#include "blocks/block_replacer.h"
44
#include "blocks/stmt.h"
55
namespace block {
6-
class if_switcher : public block_visitor {
6+
class if_switcher : public block_replacer {
77
public:
8-
using block_visitor::visit;
8+
using block_replacer::visit;
99
virtual void visit(if_stmt::Ptr);
1010
};
1111
} // namespace block

make/tests.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ endif
1212
TEST ?=
1313
run: SHELL:=/bin/bash
1414
run: $(SAMPLES)
15+
@ export CLICOLOR=1
1516
@ if [ "$(TEST)" == "" ]; then \
1617
total=0;\
1718
success=0;\

samples/outputs.var_names/sample40

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,26 @@
22
int match_re (char* arg1) {
33
int var3;
44
int var5;
5+
char* var0 = arg1;
56
int str_len_1 = strlen(arg1);
67
int to_match_2 = 0;
78
if (to_match_2 < str_len_1) {
89
if (arg1[to_match_2] == 97) {
910
to_match_2 = to_match_2 + 1;
1011
label0:
1112
if (to_match_2 < str_len_1) {
12-
if (arg1[to_match_2] == 98) {
13+
if (var0[to_match_2] == 98) {
1314
to_match_2 = to_match_2 + 1;
1415
goto label0;
1516
}
16-
if (arg1[to_match_2] == 99) {
17+
if (var0[to_match_2] == 99) {
1718
label1:
1819
to_match_2 = to_match_2 + 1;
1920
if (to_match_2 < str_len_1) {
20-
if (arg1[to_match_2] == 99) {
21+
if (var0[to_match_2] == 99) {
2122
goto label1;
2223
}
23-
if (arg1[to_match_2] == 100) {
24+
if (var0[to_match_2] == 100) {
2425
label2:
2526
to_match_2 = to_match_2 + 1;
2627
if (to_match_2 < str_len_1) {
@@ -35,7 +36,7 @@ int match_re (char* arg1) {
3536
var5 = 0;
3637
return var5;
3738
}
38-
if (arg1[to_match_2] == 100) {
39+
if (var0[to_match_2] == 100) {
3940
goto label2;
4041
}
4142
var3 = 0;

samples/outputs.var_names/sample44

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
void staged (void) {
22
int var0 = 24;
3-
if (!(var0)) {
3+
if (var0) {
44
}
55
int var1 = 0;
66
var1 != 1;
77
int var2 = 32;
8-
if (!(var2)) {
8+
if (var2) {
99
}
1010
int var3 = 0;
1111
(var1 != 1) && (var3 != 1);

samples/outputs.var_names/sample64

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
int power (int arg0, int arg1) {
2+
int exponent_3 = arg1;
3+
int res_4 = 1;
4+
int x_5 = arg0;
5+
while (exponent_3 > 1) {
6+
if ((exponent_3 % 2) == 1) {
7+
res_4 = res_4 * x_5;
8+
}
9+
x_5 = x_5 * x_5;
10+
exponent_3 = exponent_3 / 2;
11+
}
12+
return res_4 * x_5;
13+
}
14+
15+
void bar (void) {
16+
int a_0;
17+
int x_1 = a_0 + 1;
18+
while (x_1) {
19+
a_0 = a_0 + 1;
20+
}
21+
}
22+

samples/outputs/sample40

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,26 @@
22
int match_re (char* arg1) {
33
int var3;
44
int var5;
5+
char* var0 = arg1;
56
int var1 = strlen(arg1);
67
int var2 = 0;
78
if (var2 < var1) {
89
if (arg1[var2] == 97) {
910
var2 = var2 + 1;
1011
label0:
1112
if (var2 < var1) {
12-
if (arg1[var2] == 98) {
13+
if (var0[var2] == 98) {
1314
var2 = var2 + 1;
1415
goto label0;
1516
}
16-
if (arg1[var2] == 99) {
17+
if (var0[var2] == 99) {
1718
label1:
1819
var2 = var2 + 1;
1920
if (var2 < var1) {
20-
if (arg1[var2] == 99) {
21+
if (var0[var2] == 99) {
2122
goto label1;
2223
}
23-
if (arg1[var2] == 100) {
24+
if (var0[var2] == 100) {
2425
label2:
2526
var2 = var2 + 1;
2627
if (var2 < var1) {
@@ -35,7 +36,7 @@ int match_re (char* arg1) {
3536
var5 = 0;
3637
return var5;
3738
}
38-
if (arg1[var2] == 100) {
39+
if (var0[var2] == 100) {
3940
goto label2;
4041
}
4142
var3 = 0;

samples/outputs/sample44

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
void staged (void) {
22
int var0 = 24;
3-
if (!(var0)) {
3+
if (var0) {
44
}
55
int var1 = 0;
66
var1 != 1;
77
int var2 = 32;
8-
if (!(var2)) {
8+
if (var2) {
99
}
1010
int var3 = 0;
1111
(var1 != 1) && (var3 != 1);

samples/outputs/sample64

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
int power (int arg0, int arg1) {
2+
int var3 = arg1;
3+
int var4 = 1;
4+
int var5 = arg0;
5+
while (var3 > 1) {
6+
if ((var3 % 2) == 1) {
7+
var4 = var4 * var5;
8+
}
9+
var5 = var5 * var5;
10+
var3 = var3 / 2;
11+
}
12+
return var4 * var5;
13+
}
14+
15+
void bar (void) {
16+
int var0;
17+
int var1 = var0 + 1;
18+
while (var1) {
19+
var0 = var0 + 1;
20+
}
21+
}
22+

samples/sample64.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Include the headers
2+
#include "blocks/c_code_generator.h"
3+
#include "builder/static_var.h"
4+
#include "builder/dyn_var.h"
5+
#include "blocks/rce.h"
6+
#include <iostream>
7+
8+
// Include the BuildIt types
9+
using builder::dyn_var;
10+
using builder::static_var;
11+
12+
static dyn_var<int> power(dyn_var<int> base_in, dyn_var<int> exp_in) {
13+
14+
// Create copies so that test cases work well
15+
// MAC os has descripancy in the order arguments are copied in
16+
dyn_var<int> base = base_in; dyn_var<int> exponent = exp_in;
17+
18+
dyn_var<int> res = 1, x = base;
19+
while (exponent > 1) {
20+
if (exponent % 2 == 1)
21+
res = res * x;
22+
x = x * x;
23+
exponent = exponent / 2;
24+
}
25+
return res * x;
26+
}
27+
28+
static void bar(void) {
29+
30+
dyn_var<int> a;
31+
dyn_var<int> x = a + 1;
32+
while (x) {
33+
a = a + 1;
34+
}
35+
36+
}
37+
38+
int main(int argc, char* argv[]) {
39+
40+
builder::builder_context context;
41+
context.run_rce = true;
42+
auto ast = context.extract_function_ast(power, "power");
43+
block::c_code_generator::generate_code(ast, std::cout, 0);
44+
45+
46+
builder::builder_context context2;
47+
context2.run_rce = true;
48+
auto ast2 = context2.extract_function_ast(bar, "bar");
49+
block::c_code_generator::generate_code(ast2, std::cout, 0);
50+
51+
return 0;
52+
}
53+
54+

src/blocks/if_switcher.cpp

Lines changed: 91 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,107 @@
22

33
namespace block {
44

5+
6+
class continue_counter: public block_visitor {
7+
public:
8+
int count = 0;
9+
using block_visitor::visit;
10+
virtual void visit(continue_stmt::Ptr) {
11+
count++;
12+
}
13+
14+
// Do not recurse for loops
15+
virtual void visit(while_stmt::Ptr) {
16+
return;
17+
}
18+
virtual void visit(for_stmt::Ptr) {
19+
return;
20+
}
21+
};
22+
23+
24+
static stmt::Ptr fix_loop_inversion(if_stmt::Ptr ifs) {
25+
26+
if (!isa<stmt_block>(ifs->then_stmt))
27+
return ifs;
28+
29+
auto then_block = to<stmt_block>(ifs->then_stmt);
30+
auto else_block = to<stmt_block>(ifs->else_stmt);
31+
32+
if (then_block->stmts.size() != 1 || else_block->stmts.size() != 0)
33+
return ifs;
34+
35+
if (!isa<while_stmt>(then_block->stmts[0]))
36+
return ifs;
37+
38+
auto ws = to<while_stmt>(then_block->stmts[0]);
39+
40+
if (!isa<int_const>(ws->cond))
41+
return ifs;
42+
43+
if (!(to<int_const>(ws->cond)->value == 1))
44+
return ifs;
45+
46+
if (!isa<stmt_block>(ws->body))
47+
return ifs;
48+
49+
if (to<stmt_block>(ws->body)->stmts.size() == 0)
50+
return ifs;
51+
52+
auto last_stmt = to<stmt_block>(ws->body)->stmts.back();
53+
if (!isa<if_stmt>(last_stmt))
54+
return ifs;
55+
56+
if (!isa<not_expr>(to<if_stmt>(last_stmt)->cond))
57+
return ifs;
58+
if (!to<not_expr>(to<if_stmt>(last_stmt)->cond)->expr1->is_same(ifs->cond))
59+
return ifs;
60+
61+
auto nfs = to<if_stmt>(last_stmt);
62+
63+
if (!isa<stmt_block>(nfs->then_stmt) || to<stmt_block>(nfs->then_stmt)->stmts.size() != 1)
64+
return ifs;
65+
if (!isa<stmt_block>(nfs->else_stmt) || to<stmt_block>(nfs->else_stmt)->stmts.size() != 0)
66+
return ifs;
67+
68+
if (!isa<break_stmt>(to<stmt_block>(nfs->then_stmt)->stmts[0]))
69+
return ifs;
70+
71+
// make sure ws has no continues
72+
continue_counter counter;
73+
ws->accept(&counter);
74+
if (counter.count != 0)
75+
return ifs;
76+
77+
78+
// everything looks good, time to patch
79+
ws->cond = ifs->cond;
80+
to<stmt_block>(ws->body)->stmts.pop_back();
81+
82+
return ws;
83+
}
84+
85+
86+
587
void if_switcher::visit(if_stmt::Ptr ifs) {
688
if (isa<stmt_block>(ifs->then_stmt)) {
789
auto then_block = to<stmt_block>(ifs->then_stmt);
8-
if (then_block->stmts.size() == 0) {
90+
auto else_block = to<stmt_block>(ifs->else_stmt);
91+
if (then_block->stmts.size() == 0 && else_block->stmts.size() != 0) {
992
ifs->then_stmt = ifs->else_stmt;
1093
ifs->else_stmt = then_block;
1194
auto ne = std::make_shared<not_expr>();
1295
ne->expr1 = ifs->cond;
1396
ifs->cond = ne;
1497
}
98+
1599
}
16-
block_visitor::visit(ifs);
100+
block_replacer::visit(ifs);
101+
102+
node = fix_loop_inversion(ifs);
17103
}
18104

105+
106+
107+
19108
} // namespace block

0 commit comments

Comments
 (0)