public static IntConstBlock ReadIntConstBlock(byte[] program, int pc) { List <int> results = new List <int>(); int size = 1; VarintResult result = GetUVarint(program, pc + size); if (result.length <= 0) { throw new ArgumentException( string.Format("could not decode int const block at pc=%d", pc) ); } size += result.length; int numInts = result.value; for (int i = 0; i < numInts; i++) { if (pc + size >= program.Length) { throw new ArgumentException("int const block exceeds program length"); } result = GetUVarint(program, pc + size); if (result.length <= 0) { throw new ArgumentException( string.Format("could not decode int const[%d] block at pc=%d", i, pc + size) ); } size += result.length; results.Add(result.value); } return(new IntConstBlock(size, results)); }
static int CheckIntConstBlock(byte[] program, int pc) { int size = 1; VarintResult result = Uvarint.GetUvarint(JavaHelper <byte> .ArrayCopyRange(program, pc + size, program.Length)); if (result.length <= 0) { throw new ArgumentException(string.Format("could not decode int const block at pc=%d", pc)); } else { size = size + result.length; int numInts = result.value; for (int i = 0; i < numInts; ++i) { if (pc + size >= program.Length) { throw new ArgumentException("int const block exceeds program length"); } result = Uvarint.GetUvarint(JavaHelper <byte> .ArrayCopyRange(program, pc + size, program.Length)); if (result.length <= 0) { throw new ArgumentException(string.Format("could not decode int const[%d] block at pc=%d", i, pc + size)); } size += result.length; } return(size); } }
public static ByteConstBlock ReadByteConstBlock(byte[] program, int pc) { List <byte[]> results = new List <byte[]>(); int size = 1; VarintResult result = GetUVarint(program, pc + size); if (result.length <= 0) { throw new ArgumentException( string.Format("could not decode byte[] const block at pc=%d", pc) ); } size += result.length; int numInts = result.value; for (int i = 0; i < numInts; i++) { if (pc + size >= program.Length) { throw new ArgumentException("byte[] const block exceeds program length"); } result = GetUVarint(program, pc + size); if (result.length <= 0) { throw new ArgumentException( string.Format("could not decode byte[] const[%d] block at pc=%d", i, pc + size) ); } size += result.length; if (pc + size >= program.Length) { throw new ArgumentException("byte[] const block exceeds program length"); } byte[] buff = new byte[result.value]; JavaHelper <byte> .SyatemArrayCopy(program, pc + size, buff, 0, result.value); results.Add(buff); size += result.value; } return(new ByteConstBlock(size, results)); }
/// <summary> /// Performs basic program validation: instruction count and program cost /// </summary> /// <param name="program">program Program to validate</param> /// <param name="args">Program arguments to validate</param> /// <returns></returns> public static ProgramData ReadProgram(byte[] program, List <byte[]> args) { List <int> ints = new List <int>(); List <byte[]> bytes = new List <byte[]>(); if (langSpec == null) { LoadLangSpec(); } VarintResult result = GetUVarint(program, 0); int vlen = result.length; if (vlen <= 0) { throw new ArgumentException("version parsing error"); } int version = result.value; if (version > langSpec.EvalMaxVersion) { throw new ArgumentException("unsupported version"); } if (args == null) { args = new List <byte[]>(); } int cost = 0; int length = program.Length; for (int i = 0; i < args.Count; i++) { length += args[i].Length; } if (length > MAX_LENGTH) { throw new ArgumentException("program too long"); } if (opcodes == null) { opcodes = new Operation[256]; for (int i = 0; i < langSpec.Ops.Length; i++) { Operation op = langSpec.Ops[i]; opcodes[op.Opcode] = op; } } int pc = vlen; while (pc < program.Length) { int opcode = program[pc] & 0xFF; Operation op = opcodes[opcode]; if (op == null) { throw new ArgumentException("invalid instruction: " + opcode); } cost += op.Cost; int size = op.Size; if (size == 0) { switch (op.Opcode) { case INTCBLOCK_OPCODE: IntConstBlock intsBlock = ReadIntConstBlock(program, pc); size += intsBlock.size; ints.AddRange(intsBlock.results); break; case BYTECBLOCK_OPCODE: ByteConstBlock bytesBlock = ReadByteConstBlock(program, pc); size += bytesBlock.size; bytes.AddRange(bytesBlock.results); break; default: throw new ArgumentException("invalid instruction: " + op.Opcode); } } pc += size; } if (cost > MAX_COST) { throw new ArgumentException("program too costly to run"); } return(new ProgramData(true, ints, bytes)); }
/// <summary> /// Performs basic program validation: instruction count and program cost /// </summary> /// <param name="program"></param> /// <param name="args"></param> /// <returns></returns> public static bool CheckProgram(byte[] program, List <byte[]> args) { if (langSpec == null) { var jsonStr = GetFromResources("langspec.json"); langSpec = JsonConvert.DeserializeObject <LangSpec>(jsonStr); } VarintResult result = Uvarint.GetUvarint(program); int vlen = result.length; if (vlen <= 0) { throw new ArgumentException("version parsing error"); } else { int version = result.value; if (version > langSpec.EvalMaxVersion) { throw new ArgumentException("unsupported version"); } else { if (args == null) { args = new List <byte[]>(); } int cost = 0; int length = program.Length; int pc; for (pc = 0; pc < args.Count; ++pc) { length += args[pc].Length; } if (length > 1000) { throw new ArgumentException("program too long"); } else { if (opcodes == null) { opcodes = new Logic.Operation[256]; for (pc = 0; pc < langSpec.Ops.Length; ++pc) { Logic.Operation op = langSpec.Ops[pc]; opcodes[op.Opcode] = op; } } int size; for (pc = vlen; pc < program.Length; pc += size) { int opcode = program[pc] & 255; Logic.Operation op = opcodes[opcode]; if (op == null) { throw new ArgumentException("invalid instruction: " + opcode); } cost += op.Cost; size = op.Size; if (size == 0) { switch (op.Opcode) { case 32: size = CheckIntConstBlock(program, pc); break; case 38: size = CheckByteConstBlock(program, pc); break; default: throw new ArgumentException("invalid instruction: " + op.Opcode); } } } if (cost > 20000) { throw new ArgumentException("program too costly to run"); } else { return(true); } } } } }
/// <summary> /// Performs basic program validation: instruction count and program cost /// </summary> /// <param name="program"></param> /// <param name="args"></param> /// <returns></returns> public static bool CheckProgram(byte[] program, List <byte[]> args) { if (langSpec == null) { // var jsonStr = (new StreamReader("langspec.json")).ReadToEnd(); // langSpec = JsonConvert.DeserializeObject<LangSpec>(jsonStr); // read file from embedded resources - not the file system var jsonStr = GetFromResources("langspec.json"); langSpec = JsonConvert.DeserializeObject <LangSpec>(jsonStr); // InputStreamReader reader; // try { // reader = new InputStreamReader(Logic.class.getResourceAsStream("/langspec.json"), "UTF-8"); // } catch (UnsupportedEncodingException var11) { // throw new IllegalStateException("langspec opening error"); // } // Gson g = (new GsonBuilder()).create(); // langSpec = (Logic.LangSpec) g.fromJson(reader, Logic.LangSpec.class); // reader.close(); } VarintResult result = Uvarint.GetUvarint(program); int vlen = result.length; if (vlen <= 0) { throw new ArgumentException("version parsing error"); } else { int version = result.value; if (version > langSpec.EvalMaxVersion) { throw new ArgumentException("unsupported version"); } else { if (args == null) { args = new List <byte[]>(); } int cost = 0; int length = program.Length; int pc; for (pc = 0; pc < args.Count; ++pc) { length += args[pc].Length; } if (length > 1000) { throw new ArgumentException("program too long"); } else { if (opcodes == null) { opcodes = new Logic.Operation[256]; for (pc = 0; pc < langSpec.Ops.Length; ++pc) { Logic.Operation op = langSpec.Ops[pc]; opcodes[op.Opcode] = op; } } int size; for (pc = vlen; pc < program.Length; pc += size) { int opcode = program[pc] & 255; Logic.Operation op = opcodes[opcode]; if (op == null) { throw new ArgumentException("invalid instruction: " + opcode); } cost += op.Cost; size = op.Size; if (size == 0) { switch (op.Opcode) { case 32: size = CheckIntConstBlock(program, pc); break; case 38: size = CheckByteConstBlock(program, pc); break; default: throw new ArgumentException("invalid instruction: " + op.Opcode); } } } if (cost > 20000) { throw new ArgumentException("program too costly to run"); } else { return(true); } } } } }