github.com/aergoio/aergo@v1.3.1/contract/sqlcheck.c (about)

     1  #include <ctype.h>
     2  #include <string.h>
     3  #include "_cgo_export.h"
     4  
     5  #define KEYWORD_MINSIZE 4
     6  #define KEYWORD_MAXSIZE 16
     7  static char keyword[KEYWORD_MAXSIZE+1];
     8  
     9  static int get_keyword(const char *sql)
    10  {
    11      int in_bc = 0;
    12      int in_lc = 0;
    13      int spos = -1;
    14      int epos = 0;
    15      int l = strlen(sql);
    16      int i;
    17  
    18      for (i = 0; i < l; i++) {
    19          char c = sql[i];
    20          switch (c) {
    21          case ' ':
    22              /* fallthrough */
    23          case '\t':
    24              if (spos > -1) {
    25                  epos = i;
    26                  goto LOOP_END;
    27              }
    28              break;
    29          case '\n':
    30              if (in_lc) {
    31                  in_lc = 0;
    32              }
    33              if (spos > -1) {
    34                  epos = i;
    35                  goto LOOP_END;
    36              }
    37              break;
    38          case '-':
    39              if (spos > -1) {
    40                  epos = i;
    41                  goto LOOP_END;
    42              }
    43              if (!in_bc && !in_lc && sql[i+1] == '-') {
    44                  in_lc = 1;
    45                  i++;
    46              }
    47              break;
    48          case '/':
    49              if (spos > -1) {
    50                  epos = i;
    51                  goto LOOP_END;
    52              }
    53              if (!in_lc && !in_bc && sql[i+1] == '*') {
    54                  in_bc = 1;
    55                  i++;
    56              }
    57              break;
    58          case '*':
    59              if (in_bc) {
    60                  if (sql[i+1] == '/') {
    61                      in_bc = 0;
    62                      i++;
    63                  }
    64              }
    65              break;
    66          case '(':
    67              if (spos > -1) {
    68                  epos = i;
    69                  goto LOOP_END;
    70              }
    71              break;
    72          default:
    73              if (!in_lc && !in_bc && spos == -1) {
    74                  spos = i;
    75              }
    76          }
    77      }
    78      if (!in_bc && !in_lc) { /* EOF */
    79          epos = i;
    80      }
    81  
    82  LOOP_END:
    83      if (spos > -1 && epos > spos) {
    84          int klen = epos - spos;
    85          if (klen >= KEYWORD_MINSIZE && klen <= KEYWORD_MAXSIZE) {
    86              strncpy(keyword, sql + spos, klen);
    87              keyword[klen] = '\0';
    88              i = 0;
    89              while (keyword[i]) {
    90                  keyword[i] = toupper(keyword[i]);
    91                  i++;
    92              }
    93              return epos;
    94          }
    95      }
    96      return -1;
    97  }
    98  
    99  static int sqlcheck_is_permitted_pragma(const char *sql, int end_offset) {
   100      if (strncmp(keyword, "PRAGMA", 6) == 0) {
   101          end_offset = get_keyword(sql + end_offset);
   102          if (end_offset == -1)
   103              return 0;
   104          if (strncmp(keyword, "TABLE_INFO", 10) == 0)
   105              return 1;
   106          if (strncmp(keyword, "INDEX_LIST", 10) == 0)
   107              return 1;
   108          if (strncmp(keyword, "INDEX_INFO", 10) == 0)
   109              return 1;
   110          if (strncmp(keyword, "FOREIGN_KEY_LIST", 16) == 0)
   111              return 1;
   112          return 0;
   113      }
   114      return -1;
   115  }
   116  
   117  int sqlcheck_is_permitted_sql(const char *sql)
   118  {
   119      int end_offset = -1;
   120  
   121      end_offset = get_keyword(sql);
   122      if (end_offset > -1) {
   123          if (strncmp(keyword, "CREATE", 6) == 0) {
   124              end_offset = get_keyword(sql + end_offset);
   125              if (end_offset == -1) {
   126                  return 0;
   127              }
   128              if (strncmp(keyword, "TABLE", 5) == 0 || strncmp(keyword, "INDEX", 5) == 0) {
   129                  return 1;
   130              } else {
   131                  return 0;
   132              }
   133          } else {
   134              int ret;
   135              if ((ret = sqlcheck_is_permitted_pragma(sql, end_offset)) >= 0)
   136                  return ret;
   137              return PermittedCmd(keyword);
   138          }
   139      }
   140      return 0;
   141  }
   142  
   143  int sqlcheck_is_readonly_sql(const char *sql)
   144  {
   145      int end_offset = -1;
   146      int ret;
   147  
   148      end_offset = get_keyword(sql);
   149      if (end_offset > -1) {
   150          if (strncmp(keyword, "SELECT", 6) == 0 )
   151              return 1;
   152          if ((ret = sqlcheck_is_permitted_pragma(sql, end_offset)) >= 0)
   153              return ret;
   154  
   155      }
   156      return 0;
   157  }
   158