Browse Source

Fixed a crash in serpent compiler when converting to number a string containing non-ascii character (e.g.: a = "però"). To prevent further signed int overflows: modified intToDecimal() and decimalToInt() into unsignedToDecimal() and decimalToUnsigned() because they currently make sense only on unsigned integers.

cl-refactor
Giacomo Tazzari 11 years ago
parent
commit
9db294a5b7
  1. 8
      libserpent/bignum.cpp
  2. 4
      libserpent/bignum.h
  3. 26
      libserpent/compiler.cpp
  4. 8
      libserpent/rewriter.cpp
  5. 12
      libserpent/util.cpp
  6. 2
      sc/cmdline.cpp

8
libserpent/bignum.cpp

@ -5,9 +5,9 @@
#include "bignum.h" #include "bignum.h"
//Integer to string conversion //Integer to string conversion
std::string intToDecimal(int branch) { std::string unsignedToDecimal(unsigned branch) {
if (branch < 10) return nums.substr(branch, 1); if (branch < 10) return nums.substr(branch, 1);
else return intToDecimal(branch / 10) + nums.substr(branch % 10,1); else return unsignedToDecimal(branch / 10) + nums.substr(branch % 10,1);
} }
//Add two strings representing decimal values //Add two strings representing decimal values
@ -91,8 +91,8 @@ std::string decimalMod(std::string a, std::string b) {
} }
//String to int conversion //String to int conversion
int decimalToInt(std::string a) { unsigned decimalToUnsigned(std::string a) {
if (a.size() == 0) return 0; if (a.size() == 0) return 0;
else return (a[a.size() - 1] - '0') else return (a[a.size() - 1] - '0')
+ decimalToInt(a.substr(0,a.size()-1)) * 10; + decimalToUnsigned(a.substr(0,a.size()-1)) * 10;
} }

4
libserpent/bignum.h

@ -11,7 +11,7 @@ const std::string tt255 =
"57896044618658097711785492504343953926634992332820282019728792003956564819968" "57896044618658097711785492504343953926634992332820282019728792003956564819968"
; ;
std::string intToDecimal(int branch); std::string unsignedToDecimal(unsigned branch);
std::string decimalAdd(std::string a, std::string b); std::string decimalAdd(std::string a, std::string b);
@ -25,6 +25,6 @@ std::string decimalMod(std::string a, std::string b);
bool decimalGt(std::string a, std::string b, bool eqAllowed=false); bool decimalGt(std::string a, std::string b, bool eqAllowed=false);
int decimalToInt(std::string a); unsigned decimalToUnsigned(std::string a);
#endif #endif

26
libserpent/compiler.cpp

@ -55,7 +55,7 @@ programData opcodeify(Node node, programAux aux=Aux()) {
else if (node.val == "ref" || node.val == "get" || node.val == "set") { else if (node.val == "ref" || node.val == "get" || node.val == "set") {
std::string varname = node.args[0].val; std::string varname = node.args[0].val;
if (!aux.vars.count(varname)) { if (!aux.vars.count(varname)) {
aux.vars[varname] = intToDecimal(aux.vars.size() * 32); aux.vars[varname] = unsignedToDecimal(aux.vars.size() * 32);
} }
if (varname == "msg.data") aux.calldataUsed = true; if (varname == "msg.data") aux.calldataUsed = true;
// Set variable // Set variable
@ -165,7 +165,7 @@ programData opcodeify(Node node, programAux aux=Aux()) {
nodes.push_back(token("MSIZE", m)); nodes.push_back(token("MSIZE", m));
nodes.push_back(token("0", m)); nodes.push_back(token("0", m));
nodes.push_back(token("MSIZE", m)); nodes.push_back(token("MSIZE", m));
nodes.push_back(token(intToDecimal(subs.size() * 32 - 1), m)); nodes.push_back(token(unsignedToDecimal(subs.size() * 32 - 1), m));
nodes.push_back(token("ADD", m)); nodes.push_back(token("ADD", m));
nodes.push_back(token("MSTORE8", m)); nodes.push_back(token("MSTORE8", m));
for (unsigned i = 0; i < subs.size(); i++) { for (unsigned i = 0; i < subs.size(); i++) {
@ -173,7 +173,7 @@ programData opcodeify(Node node, programAux aux=Aux()) {
nodes.push_back(subs[i]); nodes.push_back(subs[i]);
nodes.push_back(token("SWAP", m)); nodes.push_back(token("SWAP", m));
if (i > 0) { if (i > 0) {
nodes.push_back(token(intToDecimal(i * 32), m)); nodes.push_back(token(unsignedToDecimal(i * 32), m));
nodes.push_back(token("ADD", m)); nodes.push_back(token("ADD", m));
} }
nodes.push_back(token("MSTORE", m)); nodes.push_back(token("MSTORE", m));
@ -201,7 +201,7 @@ Node finalize(programData c) {
if (c.aux.allocUsed && c.aux.vars.size() > 0) { if (c.aux.allocUsed && c.aux.vars.size() > 0) {
Node nodelist[] = { Node nodelist[] = {
token("0", m), token("0", m),
token(intToDecimal(c.aux.vars.size() * 32 - 1)), token(unsignedToDecimal(c.aux.vars.size() * 32 - 1)),
token("MSTORE8", m) token("MSTORE8", m)
}; };
bottom.push_back(multiToken(nodelist, 3, m)); bottom.push_back(multiToken(nodelist, 3, m));
@ -235,7 +235,7 @@ programAux buildDict(Node program, programAux aux, int labelLength) {
aux.step += 1 + toByteArr(program.val, m).size(); aux.step += 1 + toByteArr(program.val, m).size();
} }
else if (program.val[0] == '~') { else if (program.val[0] == '~') {
aux.vars[program.val.substr(1)] = intToDecimal(aux.step); aux.vars[program.val.substr(1)] = unsignedToDecimal(aux.step);
} }
else if (program.val[0] == '$') { else if (program.val[0] == '$') {
aux.step += labelLength + 1; aux.step += labelLength + 1;
@ -271,7 +271,7 @@ Node substDict(Node program, programAux aux, int labelLength) {
std::vector<Node> inner; std::vector<Node> inner;
if (program.type == TOKEN) { if (program.type == TOKEN) {
if (program.val[0] == '$') { if (program.val[0] == '$') {
std::string tokStr = "PUSH"+intToDecimal(labelLength); std::string tokStr = "PUSH"+unsignedToDecimal(labelLength);
out.push_back(token(tokStr, m)); out.push_back(token(tokStr, m));
int dotLoc = program.val.find('.'); int dotLoc = program.val.find('.');
if (dotLoc == -1) { if (dotLoc == -1) {
@ -289,7 +289,7 @@ Node substDict(Node program, programAux aux, int labelLength) {
else if (program.val[0] == '~') { } else if (program.val[0] == '~') { }
else if (isNumberLike(program)) { else if (isNumberLike(program)) {
inner = toByteArr(program.val, m); inner = toByteArr(program.val, m);
out.push_back(token("PUSH"+intToDecimal(inner.size()))); out.push_back(token("PUSH"+unsignedToDecimal(inner.size())));
out.push_back(astnode("_", inner, m)); out.push_back(astnode("_", inner, m));
} }
else return program; else return program;
@ -333,10 +333,10 @@ std::string serialize(std::vector<Node> codons) {
for (unsigned i = 0; i < codons.size(); i++) { for (unsigned i = 0; i < codons.size(); i++) {
int v; int v;
if (isNumberLike(codons[i])) { if (isNumberLike(codons[i])) {
v = decimalToInt(codons[i].val); v = decimalToUnsigned(codons[i].val);
} }
else if (codons[i].val.substr(0,4) == "PUSH") { else if (codons[i].val.substr(0,4) == "PUSH") {
v = 95 + decimalToInt(codons[i].val.substr(4)); v = 95 + decimalToUnsigned(codons[i].val.substr(4));
} }
else { else {
v = opcode(codons[i].val); v = opcode(codons[i].val);
@ -355,9 +355,9 @@ std::vector<Node> deserialize(std::string ser) {
std::string oper = op((int)v); std::string oper = op((int)v);
if (oper != "" && backCount <= 0) o.push_back(token(oper)); if (oper != "" && backCount <= 0) o.push_back(token(oper));
else if (v >= 96 && v < 128 && backCount <= 0) { else if (v >= 96 && v < 128 && backCount <= 0) {
o.push_back(token("PUSH"+intToDecimal(v - 95))); o.push_back(token("PUSH"+unsignedToDecimal(v - 95)));
} }
else o.push_back(token(intToDecimal(v))); else o.push_back(token(unsignedToDecimal(v)));
if (v >= 96 && v < 128 && backCount <= 0) { if (v >= 96 && v < 128 && backCount <= 0) {
backCount = v - 95; backCount = v - 95;
} }
@ -392,7 +392,7 @@ std::string encodeDatalist(std::vector<std::string> vals) {
for (unsigned i = 0; i < vals.size(); i++) { for (unsigned i = 0; i < vals.size(); i++) {
std::vector<Node> n = toByteArr(strToNumeric(vals[i]), Metadata(), 32); std::vector<Node> n = toByteArr(strToNumeric(vals[i]), Metadata(), 32);
for (unsigned j = 0; j < n.size(); j++) { for (unsigned j = 0; j < n.size(); j++) {
int v = decimalToInt(n[j].val); int v = decimalToUnsigned(n[j].val);
o += (char)v; o += (char)v;
} }
} }
@ -406,7 +406,7 @@ std::vector<std::string> decodeDatalist(std::string ser) {
std::string o = "0"; std::string o = "0";
for (unsigned j = i; j < i + 32; j++) { for (unsigned j = i; j < i + 32; j++) {
int vj = (int)(unsigned char)ser[j]; int vj = (int)(unsigned char)ser[j];
o = decimalAdd(decimalMul(o, "256"), intToDecimal(vj)); o = decimalAdd(decimalMul(o, "256"), unsignedToDecimal(vj));
} }
out.push_back(o); out.push_back(o);
} }

8
libserpent/rewriter.cpp

@ -344,7 +344,7 @@ Node subst(Node pattern,
Node array_lit_transform(Node node) { Node array_lit_transform(Node node) {
std::vector<Node> o1; std::vector<Node> o1;
o1.push_back(token(intToDecimal(node.args.size() * 32), node.metadata)); o1.push_back(token(unsignedToDecimal(node.args.size() * 32), node.metadata));
std::vector<Node> o2; std::vector<Node> o2;
std::string symb = "_temp"+mkUniqueToken()+"_0"; std::string symb = "_temp"+mkUniqueToken()+"_0";
o2.push_back(token(symb, node.metadata)); o2.push_back(token(symb, node.metadata));
@ -357,7 +357,7 @@ Node array_lit_transform(Node node) {
o5.push_back(token(symb, node.metadata)); o5.push_back(token(symb, node.metadata));
std::vector<Node> o6; std::vector<Node> o6;
o6.push_back(astnode("get", o5, node.metadata)); o6.push_back(astnode("get", o5, node.metadata));
o6.push_back(token(intToDecimal(i * 32), node.metadata)); o6.push_back(token(unsignedToDecimal(i * 32), node.metadata));
std::vector<Node> o7; std::vector<Node> o7;
o7.push_back(astnode("add", o6)); o7.push_back(astnode("add", o6));
o7.push_back(node.args[i]); o7.push_back(node.args[i]);
@ -474,10 +474,10 @@ Node validate(Node inp) {
int i = 0; int i = 0;
while(valid[i][0] != "---END---") { while(valid[i][0] != "---END---") {
if (inp.val == valid[i][0]) { if (inp.val == valid[i][0]) {
if (decimalGt(valid[i][1], intToDecimal(inp.args.size()))) { if (decimalGt(valid[i][1], unsignedToDecimal(inp.args.size()))) {
err("Too few arguments for "+inp.val, inp.metadata); err("Too few arguments for "+inp.val, inp.metadata);
} }
if (decimalGt(intToDecimal(inp.args.size()), valid[i][2])) { if (decimalGt(unsignedToDecimal(inp.args.size()), valid[i][2])) {
err("Too many arguments for "+inp.val, inp.metadata); err("Too many arguments for "+inp.val, inp.metadata);
} }
} }

12
libserpent/util.cpp

@ -60,8 +60,8 @@ std::string printAST(Node ast, bool printMetadata) {
std::string o = "("; std::string o = "(";
if (printMetadata) { if (printMetadata) {
o += ast.metadata.file + " "; o += ast.metadata.file + " ";
o += intToDecimal(ast.metadata.ln) + " "; o += unsignedToDecimal(ast.metadata.ln) + " ";
o += intToDecimal(ast.metadata.ch) + ": "; o += unsignedToDecimal(ast.metadata.ch) + ": ";
} }
o += ast.val; o += ast.val;
std::vector<std::string> subs; std::vector<std::string> subs;
@ -132,14 +132,14 @@ std::string strToNumeric(std::string inp) {
else if ((inp[0] == '"' && inp[inp.length()-1] == '"') else if ((inp[0] == '"' && inp[inp.length()-1] == '"')
|| (inp[0] == '\'' && inp[inp.length()-1] == '\'')) { || (inp[0] == '\'' && inp[inp.length()-1] == '\'')) {
for (unsigned i = 1; i < inp.length() - 1; i++) { for (unsigned i = 1; i < inp.length() - 1; i++) {
o = decimalAdd(decimalMul(o,"256"), intToDecimal(inp[i])); o = decimalAdd(decimalMul(o,"256"), unsignedToDecimal((unsigned char)inp[i]));
} }
} }
else if (inp.substr(0,2) == "0x") { else if (inp.substr(0,2) == "0x") {
for (unsigned i = 2; i < inp.length(); i++) { for (unsigned i = 2; i < inp.length(); i++) {
int dig = std::string("0123456789abcdef").find(inp[i]); int dig = std::string("0123456789abcdef").find(inp[i]);
if (dig < 0) return ""; if (dig < 0) return "";
o = decimalAdd(decimalMul(o,"16"), intToDecimal(dig)); o = decimalAdd(decimalMul(o,"16"), unsignedToDecimal(dig));
} }
} }
else { else {
@ -188,7 +188,7 @@ int counter = 0;
//Makes a unique token //Makes a unique token
std::string mkUniqueToken() { std::string mkUniqueToken() {
counter++; counter++;
return intToDecimal(counter); return unsignedToDecimal(counter);
} }
//Does a file exist? http://stackoverflow.com/questions/12774207 //Does a file exist? http://stackoverflow.com/questions/12774207
@ -217,7 +217,7 @@ std::string get_file_contents(std::string filename)
//Report error //Report error
void err(std::string errtext, Metadata met) { void err(std::string errtext, Metadata met) {
std::string err = "Error (file \"" + met.file + "\", line " + std::string err = "Error (file \"" + met.file + "\", line " +
intToDecimal(met.ln) + ", char " + intToDecimal(met.ch) + unsignedToDecimal(met.ln) + ", char " + unsignedToDecimal(met.ch) +
"): " + errtext; "): " + errtext;
std::cerr << err << "\n"; std::cerr << err << "\n";
throw(err); throw(err);

2
sc/cmdline.cpp

@ -96,7 +96,7 @@ int main(int argv, char** argc) {
else if (command == "biject") { else if (command == "biject") {
if (argv == 3) if (argv == 3)
std::cerr << "Not enough arguments for biject\n"; std::cerr << "Not enough arguments for biject\n";
int pos = decimalToInt(secondInput); int pos = decimalToUnsigned(secondInput);
std::vector<Node> n = prettyCompile(input); std::vector<Node> n = prettyCompile(input);
if (pos >= (int)n.size()) if (pos >= (int)n.size())
std::cerr << "Code position too high\n"; std::cerr << "Code position too high\n";

Loading…
Cancel
Save