-
Notifications
You must be signed in to change notification settings - Fork 397
Expand file tree
/
Copy pathMySQLBinaryOperation.java
More file actions
114 lines (91 loc) · 3.46 KB
/
MySQLBinaryOperation.java
File metadata and controls
114 lines (91 loc) · 3.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package sqlancer.mysql.ast;
import java.util.function.BinaryOperator;
import sqlancer.IgnoreMeException;
import sqlancer.Randomly;
import sqlancer.mysql.ast.MySQLCastOperation.CastType;
public class MySQLBinaryOperation implements MySQLExpression {
private final MySQLExpression left;
private final MySQLExpression right;
private final MySQLBinaryOperator op;
public enum MySQLBinaryOperator {
AND("&") {
@Override
public MySQLConstant apply(MySQLConstant left, MySQLConstant right) {
return applyBitOperation(left, right, (l, r) -> l & r);
}
},
OR("|") {
@Override
public MySQLConstant apply(MySQLConstant left, MySQLConstant right) {
return applyBitOperation(left, right, (l, r) -> l | r);
}
},
XOR("^") {
@Override
public MySQLConstant apply(MySQLConstant left, MySQLConstant right) {
return applyBitOperation(left, right, (l, r) -> l ^ r);
}
};
private String textRepresentation;
private static MySQLConstant applyBitOperation(MySQLConstant left, MySQLConstant right,
BinaryOperator<Long> op) {
if (left.isNull() || right.isNull()) {
return MySQLConstant.createNullConstant();
} else {
long leftVal = left.castAs(CastType.SIGNED).getInt();
long rightVal = right.castAs(CastType.SIGNED).getInt();
long value = op.apply(leftVal, rightVal);
return MySQLConstant.createUnsignedIntConstant(value);
}
}
MySQLBinaryOperator(String textRepresentation) {
this.textRepresentation = textRepresentation;
}
public String getTextRepresentation() {
return textRepresentation;
}
public abstract MySQLConstant apply(MySQLConstant left, MySQLConstant right);
public static MySQLBinaryOperator getRandom() {
return Randomly.fromOptions(values());
}
}
public MySQLBinaryOperation(MySQLExpression left, MySQLExpression right, MySQLBinaryOperator op) {
this.left = left;
this.right = right;
this.op = op;
}
@Override
public MySQLConstant getExpectedValue() {
MySQLConstant leftExpected = left.getExpectedValue();
MySQLConstant rightExpected = right.getExpectedValue();
/* workaround for https://bugs.mysql.com/bug.php?id=95960 */
if (leftExpected.isString()) {
String text = leftExpected.castAsString();
while (text.startsWith(" ") || text.startsWith("\t")) {
text = text.substring(1);
}
if (text.startsWith("\n") || text.startsWith(".")) {
throw new IgnoreMeException();
}
}
if (rightExpected.isString()) {
String text = rightExpected.castAsString();
while (text.startsWith(" ") || text.startsWith("\t")) {
text = text.substring(1);
}
if (text.startsWith("\n") || text.startsWith(".")) {
throw new IgnoreMeException();
}
}
return op.apply(leftExpected, rightExpected);
}
public MySQLExpression getLeft() {
return left;
}
public MySQLBinaryOperator getOp() {
return op;
}
public MySQLExpression getRight() {
return right;
}
}