Exemple #1
0
        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));
        }
Exemple #2
0
        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);
            }
        }
Exemple #3
0
        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));
        }
Exemple #4
0
        /// <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));
        }
Exemple #5
0
        /// <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);
                        }
                    }
                }
            }
        }
Exemple #6
0
        /// <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);
                        }
                    }
                }
            }
        }