Что мне делать, чтобы изменить операцию или символ в AST, анализируемом парсером скриптдома?

Что мне делать, чтобы изменить операцию или символ в абстрактном синтаксическом дереве, анализируемом парсером scriptdom? Мне нужно вывести измененные операторы SQL в исходном порядке.

      using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.SqlServer.TransactSql.ScriptDom;
using System.IO;
using System.Reflection;
namespace Greatest
{
    public class Greatest
    {
        public String sql;
        public Greatest(String payload, String template)
        {
            this.sql = template + payload;
        }
        static void Main(string[] args)
        {
            var rdr = new StringReader(@"select first_name, last_name from user_info where user_id=1 or 3>1 union select 1, version()");
            IList<ParseError> errors = null;
            var parser = new TSql150Parser(true);
            var tree = parser.ParseStatementList(rdr, out errors);

            foreach (ParseError err in errors)
            {
                Console.WriteLine(err.Message);
            }

            string payload = "1 or 3>1 union select 1, version()";
            string template = "select first_name, last_name from user_info where user_id=";

            //Console.WriteLine("payload: " + payload);
            //Console.WriteLine("paypost: " + payloadPost);
            //Console.WriteLine("Oringnal_sql: " + template + payload);
            //Console.WriteLine("Paypost_sql: " + template + payloadPost);
            var container = new DataContainer();
            Greatest greatest = new Greatest(payload, template);
            string dc = greatest.action(tree, rdr);
    }
        public string action(StatementList tree, StringReader rdr)
        {
        /*
         * ">" sign  --> greatest
         * */
            //parse sql to get AST,take SQLSelectStatement as an example
            foreach (var statement in tree.Statements)
            {
                if (statement is SelectStatement)
                {
                    var select = statement as SelectStatement;
                    var query = select.QueryExpression;              //select.QueryExpression为BinaryQueryExpression
                    if (query is QuerySpecification)
                    {
                        query = query as QuerySpecification;
                        QuerySpecification queryblock = (QuerySpecification)query;

                        //对queryLeft的条件改变逻辑,关系运算符
                        BooleanExpression where = queryblock.WhereClause.SearchCondition;

                        //遍历where,> 关系式 替换为 greatest
                        double pr = 0.5;
                        greatest(where, pr);
                    }
                    else if (query is BinaryQueryExpression)
                    {
                        BinaryQueryExpression unionQuery = (BinaryQueryExpression)query;

                        //对queryLeft的条件改变逻辑,关系运算符
                        QuerySpecification queryLeft = (QuerySpecification)unionQuery.FirstQueryExpression;

                        //where
                        BooleanExpression where = queryLeft.WhereClause.SearchCondition;

                        //遍历where,> 关系式 替换为 greatest
                        double pr = 0.5;
                        greatest(where, pr);
                    }
                    else
                    {
                        //queryRight 没有 查询条件,不用处理
                        //MySqlSelectQueryBlock queryRight = (MySqlSelectQueryBlock)unionQuery.getRight();
                    }
                }
            }
        //    /*
        //     由AST得到变异后的sql,并扣除变异的payload
        //    */
            String sqlPost = tree.ToString().Replace("\n", " ").Replace("\t", "");
            String locStr = "user_id = ";
            int pos = sqlPost.IndexOf(locStr) + locStr.Length;
            //System.out.println(sqlPost);
            return sqlPost.Substring(pos);
        }
    }
}

0 ответов

Другие вопросы по тегам