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