diff --git a/apache2/libinjection/COPYING.txt b/apache2/libinjection/COPYING.txt index ff3360c6..772b0562 100644 --- a/apache2/libinjection/COPYING.txt +++ b/apache2/libinjection/COPYING.txt @@ -1,813 +1,36 @@ - - - - - - - - - ModSecurity/apache2/libinjection/COPYING.txt at da961d4c1535d2131c1733258b3f809feeabadf5 · client9/ModSecurity · GitHub - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - -
- -
- - - - - - - -
-
- -
-
-
- - - - - -

- public - - - / - ModSecurity - - forked from SpiderLabs/ModSecurity - -

-
- - - - -
- - - - - - -
- - -
- - - tree: - da961d4c15 - - -
- -
-
- Switch branches/tags - -
- -
-
- -
-
- -
-
- -
- -
- -
- - master -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
Nothing to show
-
- - -
-
- -
- - 2.7.3 -
-
- - 2.7.2 -
-
- - 2.7.1 -
-
- -
Nothing to show
- -
- -
-
-
- -
- - - -
- - - - - - - -
-
- -
- - - - - - - -
-
- - - - - - - - - -
- - - - - - - -
- - -
- -
-
- -
-
-
-
- - file - 38 lines (37 sloc) - 1.76 kb -
-
-
- Edit - Raw - Blame - History -
-
- -
-
- - - - - -
- 1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 - - -
/*
 * Copyright 2012, 2013
 * Nick Galbreath -- nickg [at] client9 [dot] com
 * http://www.client9.com/projects/libinjection/
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * Neither the name of libinjection nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This is the standard "new" BSD license:
 * http://www.opensource.org/licenses/bsd-license.php
 */
-
-
- -
-
- - - - -
-
-
- - - - -
-
-
-
- - -
- - - - - -
-
-
- -
-
-
-
-
-
-
- - - - - - -
-
- - - -
- - Something went wrong with that request. Please try again. - -
- - - - - - - - +/* Copyright 2012, 2013 + * Nick Galbreath -- nickg [at] client9 [dot] com + * http://www.client9.com/projects/libinjection/ + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of libinjection nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This is the standard "new" BSD license: + * http://www.opensource.org/licenses/bsd-license.php + */ diff --git a/apache2/libinjection/sqli_fingerprints.h b/apache2/libinjection/sqli_fingerprints.h index 20a17df0..4d635987 100644 --- a/apache2/libinjection/sqli_fingerprints.h +++ b/apache2/libinjection/sqli_fingerprints.h @@ -1,2940 +1,2163 @@ - - - - - - - - - ModSecurity/apache2/libinjection/sqli_fingerprints.h at da961d4c1535d2131c1733258b3f809feeabadf5 · client9/ModSecurity · GitHub - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - -
- -
- - - - - - - -
-
- -
-
-
- - - - - -

- public - - - / - ModSecurity - - forked from SpiderLabs/ModSecurity - -

-
- - - - -
- - - - - - -
- - -
- - - tree: - da961d4c15 - - -
- -
-
- Switch branches/tags - -
- -
-
- -
-
- -
-
- -
- -
- -
- - master -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
Nothing to show
-
- - -
-
- -
- - 2.7.3 -
-
- - 2.7.2 -
-
- - 2.7.1 -
-
- -
Nothing to show
- -
- -
-
-
- -
- - - -
- - - - - - - -
-
- -
- - - - - - - -
-
- - - - - - - - - -
- - - - - - - -
- - -
- -
-
- -
-
-
-
- - file - 2165 lines (2159 sloc) - 28.197 kb -
-
-
- Edit - Raw - Blame - History -
-
- -
-
- - - - - -
- 1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303 -304 -305 -306 -307 -308 -309 -310 -311 -312 -313 -314 -315 -316 -317 -318 -319 -320 -321 -322 -323 -324 -325 -326 -327 -328 -329 -330 -331 -332 -333 -334 -335 -336 -337 -338 -339 -340 -341 -342 -343 -344 -345 -346 -347 -348 -349 -350 -351 -352 -353 -354 -355 -356 -357 -358 -359 -360 -361 -362 -363 -364 -365 -366 -367 -368 -369 -370 -371 -372 -373 -374 -375 -376 -377 -378 -379 -380 -381 -382 -383 -384 -385 -386 -387 -388 -389 -390 -391 -392 -393 -394 -395 -396 -397 -398 -399 -400 -401 -402 -403 -404 -405 -406 -407 -408 -409 -410 -411 -412 -413 -414 -415 -416 -417 -418 -419 -420 -421 -422 -423 -424 -425 -426 -427 -428 -429 -430 -431 -432 -433 -434 -435 -436 -437 -438 -439 -440 -441 -442 -443 -444 -445 -446 -447 -448 -449 -450 -451 -452 -453 -454 -455 -456 -457 -458 -459 -460 -461 -462 -463 -464 -465 -466 -467 -468 -469 -470 -471 -472 -473 -474 -475 -476 -477 -478 -479 -480 -481 -482 -483 -484 -485 -486 -487 -488 -489 -490 -491 -492 -493 -494 -495 -496 -497 -498 -499 -500 -501 -502 -503 -504 -505 -506 -507 -508 -509 -510 -511 -512 -513 -514 -515 -516 -517 -518 -519 -520 -521 -522 -523 -524 -525 -526 -527 -528 -529 -530 -531 -532 -533 -534 -535 -536 -537 -538 -539 -540 -541 -542 -543 -544 -545 -546 -547 -548 -549 -550 -551 -552 -553 -554 -555 -556 -557 -558 -559 -560 -561 -562 -563 -564 -565 -566 -567 -568 -569 -570 -571 -572 -573 -574 -575 -576 -577 -578 -579 -580 -581 -582 -583 -584 -585 -586 -587 -588 -589 -590 -591 -592 -593 -594 -595 -596 -597 -598 -599 -600 -601 -602 -603 -604 -605 -606 -607 -608 -609 -610 -611 -612 -613 -614 -615 -616 -617 -618 -619 -620 -621 -622 -623 -624 -625 -626 -627 -628 -629 -630 -631 -632 -633 -634 -635 -636 -637 -638 -639 -640 -641 -642 -643 -644 -645 -646 -647 -648 -649 -650 -651 -652 -653 -654 -655 -656 -657 -658 -659 -660 -661 -662 -663 -664 -665 -666 -667 -668 -669 -670 -671 -672 -673 -674 -675 -676 -677 -678 -679 -680 -681 -682 -683 -684 -685 -686 -687 -688 -689 -690 -691 -692 -693 -694 -695 -696 -697 -698 -699 -700 -701 -702 -703 -704 -705 -706 -707 -708 -709 -710 -711 -712 -713 -714 -715 -716 -717 -718 -719 -720 -721 -722 -723 -724 -725 -726 -727 -728 -729 -730 -731 -732 -733 -734 -735 -736 -737 -738 -739 -740 -741 -742 -743 -744 -745 -746 -747 -748 -749 -750 -751 -752 -753 -754 -755 -756 -757 -758 -759 -760 -761 -762 -763 -764 -765 -766 -767 -768 -769 -770 -771 -772 -773 -774 -775 -776 -777 -778 -779 -780 -781 -782 -783 -784 -785 -786 -787 -788 -789 -790 -791 -792 -793 -794 -795 -796 -797 -798 -799 -800 -801 -802 -803 -804 -805 -806 -807 -808 -809 -810 -811 -812 -813 -814 -815 -816 -817 -818 -819 -820 -821 -822 -823 -824 -825 -826 -827 -828 -829 -830 -831 -832 -833 -834 -835 -836 -837 -838 -839 -840 -841 -842 -843 -844 -845 -846 -847 -848 -849 -850 -851 -852 -853 -854 -855 -856 -857 -858 -859 -860 -861 -862 -863 -864 -865 -866 -867 -868 -869 -870 -871 -872 -873 -874 -875 -876 -877 -878 -879 -880 -881 -882 -883 -884 -885 -886 -887 -888 -889 -890 -891 -892 -893 -894 -895 -896 -897 -898 -899 -900 -901 -902 -903 -904 -905 -906 -907 -908 -909 -910 -911 -912 -913 -914 -915 -916 -917 -918 -919 -920 -921 -922 -923 -924 -925 -926 -927 -928 -929 -930 -931 -932 -933 -934 -935 -936 -937 -938 -939 -940 -941 -942 -943 -944 -945 -946 -947 -948 -949 -950 -951 -952 -953 -954 -955 -956 -957 -958 -959 -960 -961 -962 -963 -964 -965 -966 -967 -968 -969 -970 -971 -972 -973 -974 -975 -976 -977 -978 -979 -980 -981 -982 -983 -984 -985 -986 -987 -988 -989 -990 -991 -992 -993 -994 -995 -996 -997 -998 -999 -1000 -1001 -1002 -1003 -1004 -1005 -1006 -1007 -1008 -1009 -1010 -1011 -1012 -1013 -1014 -1015 -1016 -1017 -1018 -1019 -1020 -1021 -1022 -1023 -1024 -1025 -1026 -1027 -1028 -1029 -1030 -1031 -1032 -1033 -1034 -1035 -1036 -1037 -1038 -1039 -1040 -1041 -1042 -1043 -1044 -1045 -1046 -1047 -1048 -1049 -1050 -1051 -1052 -1053 -1054 -1055 -1056 -1057 -1058 -1059 -1060 -1061 -1062 -1063 -1064 -1065 -1066 -1067 -1068 -1069 -1070 -1071 -1072 -1073 -1074 -1075 -1076 -1077 -1078 -1079 -1080 -1081 -1082 -1083 -1084 -1085 -1086 -1087 -1088 -1089 -1090 -1091 -1092 -1093 -1094 -1095 -1096 -1097 -1098 -1099 -1100 -1101 -1102 -1103 -1104 -1105 -1106 -1107 -1108 -1109 -1110 -1111 -1112 -1113 -1114 -1115 -1116 -1117 -1118 -1119 -1120 -1121 -1122 -1123 -1124 -1125 -1126 -1127 -1128 -1129 -1130 -1131 -1132 -1133 -1134 -1135 -1136 -1137 -1138 -1139 -1140 -1141 -1142 -1143 -1144 -1145 -1146 -1147 -1148 -1149 -1150 -1151 -1152 -1153 -1154 -1155 -1156 -1157 -1158 -1159 -1160 -1161 -1162 -1163 -1164 -1165 -1166 -1167 -1168 -1169 -1170 -1171 -1172 -1173 -1174 -1175 -1176 -1177 -1178 -1179 -1180 -1181 -1182 -1183 -1184 -1185 -1186 -1187 -1188 -1189 -1190 -1191 -1192 -1193 -1194 -1195 -1196 -1197 -1198 -1199 -1200 -1201 -1202 -1203 -1204 -1205 -1206 -1207 -1208 -1209 -1210 -1211 -1212 -1213 -1214 -1215 -1216 -1217 -1218 -1219 -1220 -1221 -1222 -1223 -1224 -1225 -1226 -1227 -1228 -1229 -1230 -1231 -1232 -1233 -1234 -1235 -1236 -1237 -1238 -1239 -1240 -1241 -1242 -1243 -1244 -1245 -1246 -1247 -1248 -1249 -1250 -1251 -1252 -1253 -1254 -1255 -1256 -1257 -1258 -1259 -1260 -1261 -1262 -1263 -1264 -1265 -1266 -1267 -1268 -1269 -1270 -1271 -1272 -1273 -1274 -1275 -1276 -1277 -1278 -1279 -1280 -1281 -1282 -1283 -1284 -1285 -1286 -1287 -1288 -1289 -1290 -1291 -1292 -1293 -1294 -1295 -1296 -1297 -1298 -1299 -1300 -1301 -1302 -1303 -1304 -1305 -1306 -1307 -1308 -1309 -1310 -1311 -1312 -1313 -1314 -1315 -1316 -1317 -1318 -1319 -1320 -1321 -1322 -1323 -1324 -1325 -1326 -1327 -1328 -1329 -1330 -1331 -1332 -1333 -1334 -1335 -1336 -1337 -1338 -1339 -1340 -1341 -1342 -1343 -1344 -1345 -1346 -1347 -1348 -1349 -1350 -1351 -1352 -1353 -1354 -1355 -1356 -1357 -1358 -1359 -1360 -1361 -1362 -1363 -1364 -1365 -1366 -1367 -1368 -1369 -1370 -1371 -1372 -1373 -1374 -1375 -1376 -1377 -1378 -1379 -1380 -1381 -1382 -1383 -1384 -1385 -1386 -1387 -1388 -1389 -1390 -1391 -1392 -1393 -1394 -1395 -1396 -1397 -1398 -1399 -1400 -1401 -1402 -1403 -1404 -1405 -1406 -1407 -1408 -1409 -1410 -1411 -1412 -1413 -1414 -1415 -1416 -1417 -1418 -1419 -1420 -1421 -1422 -1423 -1424 -1425 -1426 -1427 -1428 -1429 -1430 -1431 -1432 -1433 -1434 -1435 -1436 -1437 -1438 -1439 -1440 -1441 -1442 -1443 -1444 -1445 -1446 -1447 -1448 -1449 -1450 -1451 -1452 -1453 -1454 -1455 -1456 -1457 -1458 -1459 -1460 -1461 -1462 -1463 -1464 -1465 -1466 -1467 -1468 -1469 -1470 -1471 -1472 -1473 -1474 -1475 -1476 -1477 -1478 -1479 -1480 -1481 -1482 -1483 -1484 -1485 -1486 -1487 -1488 -1489 -1490 -1491 -1492 -1493 -1494 -1495 -1496 -1497 -1498 -1499 -1500 -1501 -1502 -1503 -1504 -1505 -1506 -1507 -1508 -1509 -1510 -1511 -1512 -1513 -1514 -1515 -1516 -1517 -1518 -1519 -1520 -1521 -1522 -1523 -1524 -1525 -1526 -1527 -1528 -1529 -1530 -1531 -1532 -1533 -1534 -1535 -1536 -1537 -1538 -1539 -1540 -1541 -1542 -1543 -1544 -1545 -1546 -1547 -1548 -1549 -1550 -1551 -1552 -1553 -1554 -1555 -1556 -1557 -1558 -1559 -1560 -1561 -1562 -1563 -1564 -1565 -1566 -1567 -1568 -1569 -1570 -1571 -1572 -1573 -1574 -1575 -1576 -1577 -1578 -1579 -1580 -1581 -1582 -1583 -1584 -1585 -1586 -1587 -1588 -1589 -1590 -1591 -1592 -1593 -1594 -1595 -1596 -1597 -1598 -1599 -1600 -1601 -1602 -1603 -1604 -1605 -1606 -1607 -1608 -1609 -1610 -1611 -1612 -1613 -1614 -1615 -1616 -1617 -1618 -1619 -1620 -1621 -1622 -1623 -1624 -1625 -1626 -1627 -1628 -1629 -1630 -1631 -1632 -1633 -1634 -1635 -1636 -1637 -1638 -1639 -1640 -1641 -1642 -1643 -1644 -1645 -1646 -1647 -1648 -1649 -1650 -1651 -1652 -1653 -1654 -1655 -1656 -1657 -1658 -1659 -1660 -1661 -1662 -1663 -1664 -1665 -1666 -1667 -1668 -1669 -1670 -1671 -1672 -1673 -1674 -1675 -1676 -1677 -1678 -1679 -1680 -1681 -1682 -1683 -1684 -1685 -1686 -1687 -1688 -1689 -1690 -1691 -1692 -1693 -1694 -1695 -1696 -1697 -1698 -1699 -1700 -1701 -1702 -1703 -1704 -1705 -1706 -1707 -1708 -1709 -1710 -1711 -1712 -1713 -1714 -1715 -1716 -1717 -1718 -1719 -1720 -1721 -1722 -1723 -1724 -1725 -1726 -1727 -1728 -1729 -1730 -1731 -1732 -1733 -1734 -1735 -1736 -1737 -1738 -1739 -1740 -1741 -1742 -1743 -1744 -1745 -1746 -1747 -1748 -1749 -1750 -1751 -1752 -1753 -1754 -1755 -1756 -1757 -1758 -1759 -1760 -1761 -1762 -1763 -1764 -1765 -1766 -1767 -1768 -1769 -1770 -1771 -1772 -1773 -1774 -1775 -1776 -1777 -1778 -1779 -1780 -1781 -1782 -1783 -1784 -1785 -1786 -1787 -1788 -1789 -1790 -1791 -1792 -1793 -1794 -1795 -1796 -1797 -1798 -1799 -1800 -1801 -1802 -1803 -1804 -1805 -1806 -1807 -1808 -1809 -1810 -1811 -1812 -1813 -1814 -1815 -1816 -1817 -1818 -1819 -1820 -1821 -1822 -1823 -1824 -1825 -1826 -1827 -1828 -1829 -1830 -1831 -1832 -1833 -1834 -1835 -1836 -1837 -1838 -1839 -1840 -1841 -1842 -1843 -1844 -1845 -1846 -1847 -1848 -1849 -1850 -1851 -1852 -1853 -1854 -1855 -1856 -1857 -1858 -1859 -1860 -1861 -1862 -1863 -1864 -1865 -1866 -1867 -1868 -1869 -1870 -1871 -1872 -1873 -1874 -1875 -1876 -1877 -1878 -1879 -1880 -1881 -1882 -1883 -1884 -1885 -1886 -1887 -1888 -1889 -1890 -1891 -1892 -1893 -1894 -1895 -1896 -1897 -1898 -1899 -1900 -1901 -1902 -1903 -1904 -1905 -1906 -1907 -1908 -1909 -1910 -1911 -1912 -1913 -1914 -1915 -1916 -1917 -1918 -1919 -1920 -1921 -1922 -1923 -1924 -1925 -1926 -1927 -1928 -1929 -1930 -1931 -1932 -1933 -1934 -1935 -1936 -1937 -1938 -1939 -1940 -1941 -1942 -1943 -1944 -1945 -1946 -1947 -1948 -1949 -1950 -1951 -1952 -1953 -1954 -1955 -1956 -1957 -1958 -1959 -1960 -1961 -1962 -1963 -1964 -1965 -1966 -1967 -1968 -1969 -1970 -1971 -1972 -1973 -1974 -1975 -1976 -1977 -1978 -1979 -1980 -1981 -1982 -1983 -1984 -1985 -1986 -1987 -1988 -1989 -1990 -1991 -1992 -1993 -1994 -1995 -1996 -1997 -1998 -1999 -2000 -2001 -2002 -2003 -2004 -2005 -2006 -2007 -2008 -2009 -2010 -2011 -2012 -2013 -2014 -2015 -2016 -2017 -2018 -2019 -2020 -2021 -2022 -2023 -2024 -2025 -2026 -2027 -2028 -2029 -2030 -2031 -2032 -2033 -2034 -2035 -2036 -2037 -2038 -2039 -2040 -2041 -2042 -2043 -2044 -2045 -2046 -2047 -2048 -2049 -2050 -2051 -2052 -2053 -2054 -2055 -2056 -2057 -2058 -2059 -2060 -2061 -2062 -2063 -2064 -2065 -2066 -2067 -2068 -2069 -2070 -2071 -2072 -2073 -2074 -2075 -2076 -2077 -2078 -2079 -2080 -2081 -2082 -2083 -2084 -2085 -2086 -2087 -2088 -2089 -2090 -2091 -2092 -2093 -2094 -2095 -2096 -2097 -2098 -2099 -2100 -2101 -2102 -2103 -2104 -2105 -2106 -2107 -2108 -2109 -2110 -2111 -2112 -2113 -2114 -2115 -2116 -2117 -2118 -2119 -2120 -2121 -2122 -2123 -2124 -2125 -2126 -2127 -2128 -2129 -2130 -2131 -2132 -2133 -2134 -2135 -2136 -2137 -2138 -2139 -2140 -2141 -2142 -2143 -2144 -2145 -2146 -2147 -2148 -2149 -2150 -2151 -2152 -2153 -2154 -2155 -2156 -2157 -2158 -2159 -2160 -2161 -2162 -2163 -2164 - - -
#ifndef _SQLPARSE_FINGERPRINTS_H
#define _SQLPARSE_FINGERPRINTS_H

static const char* patmap[] = {
    "&1o1U",
    "&1osU",
    "&1ovU",
    "&f()o",
    "&f(1)",
    "&f(1o",
    "&f(s)",
    "&f(v)",
    "&so1U",
    "&sovU",
    "&vo1U",
    "&vosU",
    "&vovU",
    "1&((f",
    "1&((k",
    "1&(1)",
    "1&(1,",
    "1&(1o",
    "1&(f(",
    "1&(k(",
    "1&(k1",
    "1&(kf",
    "1&(kk",
    "1&(kn",
    "1&(ko",
    "1&(ks",
    "1&(kv",
    "1&(s)",
    "1&(s,",
    "1&(so",
    "1&(v)",
    "1&(v,",
    "1&(vo",
    "1&1",
    "1&1Bf",
    "1&1Uk",
    "1&1c",
    "1&1f(",
    "1&1o(",
    "1&1o1",
    "1&1of",
    "1&1ok",
    "1&1on",
    "1&1oo",
    "1&1os",
    "1&1ov",
    "1&f((",
    "1&f()",
    "1&f(1",
    "1&f(f",
    "1&f(k",
    "1&f(n",
    "1&f(s",
    "1&f(v",
    "1&k(1",
    "1&k(f",
    "1&k(s",
    "1&k(v",
    "1&k1k",
    "1&kUk",
    "1&kk1",
    "1&kks",
    "1&kkv",
    "1&ksk",
    "1&kvk",
    "1&n()",
    "1&no1",
    "1&nos",
    "1&nov",
    "1&o(1",
    "1&o(s",
    "1&o(v",
    "1&o1o",
    "1&oso",
    "1&ovo",
    "1&sBf",
    "1&sU(",
    "1&sUk",
    "1&sf(",
    "1&so(",
    "1&so1",
    "1&sof",
    "1&sok",
    "1&son",
    "1&soo",
    "1&sos",
    "1&sov",
    "1&vBf",
    "1&vU(",
    "1&vUk",
    "1&vf(",
    "1&vo(",
    "1&vo1",
    "1&vof",
    "1&vok",
    "1&von",
    "1&voo",
    "1&vos",
    "1&vov",
    "1)&(1",
    "1)&(f",
    "1)&(k",
    "1)&(n",
    "1)&(s",
    "1)&(v",
    "1)&1B",
    "1)&1U",
    "1)&1f",
    "1)&1o",
    "1)&f(",
    "1)&o(",
    "1)&sB",
    "1)&sU",
    "1)&sf",
    "1)&so",
    "1)&vB",
    "1)&vU",
    "1)&vf",
    "1)&vo",
    "1)()s",
    "1)()v",
    "1))&(",
    "1))&1",
    "1))&f",
    "1))&o",
    "1))&s",
    "1))&v",
    "1)))&",
    "1))))",
    "1)));",
    "1)))B",
    "1)))U",
    "1)))k",
    "1)))o",
    "1));k",
    "1))B1",
    "1))Bs",
    "1))Bv",
    "1))Uk",
    "1))Un",
    "1))k1",
    "1))kk",
    "1))ks",
    "1))kv",
    "1))o(",
    "1))o1",
    "1))of",
    "1))ok",
    "1))on",
    "1))os",
    "1))ov",
    "1),(1",
    "1),(s",
    "1),(v",
    "1);k&",
    "1);k(",
    "1);kf",
    "1);kk",
    "1);kn",
    "1);ko",
    "1)B1",
    "1)B1&",
    "1)B1c",
    "1)B1o",
    "1)Bs",
    "1)Bs&",
    "1)Bsc",
    "1)Bso",
    "1)Bv",
    "1)Bv&",
    "1)Bvc",
    "1)Bvo",
    "1)U(k",
    "1)Uk(",
    "1)Uk1",
    "1)Ukf",
    "1)Ukk",
    "1)Ukn",
    "1)Uko",
    "1)Uks",
    "1)Ukv",
    "1)Unk",
    "1)k1",
    "1)k1c",
    "1)k1o",
    "1)kks",
    "1)kkv",
    "1)knk",
    "1)ks",
    "1)ksc",
    "1)kso",
    "1)kv",
    "1)kvc",
    "1)kvo",
    "1)o(1",
    "1)o(k",
    "1)o(n",
    "1)o(s",
    "1)o(v",
    "1)o1)",
    "1)o1B",
    "1)o1U",
    "1)o1f",
    "1)o1k",
    "1)o1o",
    "1)of(",
    "1)ok(",
    "1)ok1",
    "1)oks",
    "1)okv",
    "1)on&",
    "1)ono",
    "1)os)",
    "1)osB",
    "1)osU",
    "1)osf",
    "1)osk",
    "1)oso",
    "1)ov)",
    "1)ovB",
    "1)ovU",
    "1)ovf",
    "1)ovk",
    "1)ovo",
    "1,(f(",
    "1,(k(",
    "1,(k1",
    "1,(kf",
    "1,(ks",
    "1,(kv",
    "1,1),",
    "1,1)o",
    "1,1B1",
    "1,1Bs",
    "1,1Bv",
    "1,1Uk",
    "1,f(1",
    "1,f(s",
    "1,f(v",
    "1,s),",
    "1,s)o",
    "1,sB1",
    "1,sBv",
    "1,sUk",
    "1,v),",
    "1,v)o",
    "1,vB1",
    "1,vBs",
    "1,vBv",
    "1,vUk",
    "1;k&k",
    "1;k((",
    "1;k(1",
    "1;k(o",
    "1;k(s",
    "1;k(v",
    "1;k1,",
    "1;kf(",
    "1;kks",
    "1;kkv",
    "1;kn(",
    "1;kn,",
    "1;knc",
    "1;ko(",
    "1;kok",
    "1;ks,",
    "1;kv,",
    "1B1",
    "1B1,1",
    "1B1,n",
    "1B1,s",
    "1B1,v",
    "1B1Uk",
    "1B1c",
    "1B1k1",
    "1B1ks",
    "1B1kv",
    "1Bf(1",
    "1Bf(f",
    "1Bf(s",
    "1Bf(v",
    "1Bk(1",
    "1Bk(s",
    "1Bk(v",
    "1Bn,n",
    "1Bnk1",
    "1Bnks",
    "1Bnkv",
    "1Bs",
    "1Bs,1",
    "1Bs,n",
    "1Bs,v",
    "1BsUk",
    "1Bsc",
    "1Bsk1",
    "1Bsks",
    "1Bskv",
    "1Bv",
    "1Bv,1",
    "1Bv,n",
    "1Bv,s",
    "1Bv,v",
    "1BvUk",
    "1Bvc",
    "1Bvk1",
    "1Bvks",
    "1Bvkv",
    "1U",
    "1U((k",
    "1U(k1",
    "1U(kf",
    "1U(kn",
    "1U(ks",
    "1U(kv",
    "1U1,1",
    "1U1,s",
    "1U1,v",
    "1Uc",
    "1Uk",
    "1Uk(1",
    "1Uk(k",
    "1Uk(n",
    "1Uk(s",
    "1Uk(v",
    "1Uk1",
    "1Uk1,",
    "1Uk1c",
    "1Uk1f",
    "1Uk1k",
    "1Uk1n",
    "1Uk1o",
    "1Ukf",
    "1Ukf(",
    "1Ukf,",
    "1Ukk(",
    "1Ukk,",
    "1Ukk1",
    "1Ukkk",
    "1Ukkn",
    "1Ukks",
    "1Ukkv",
    "1Ukn&",
    "1Ukn(",
    "1Ukn,",
    "1Ukn1",
    "1Uknc",
    "1Uknk",
    "1Ukno",
    "1Ukns",
    "1Uknv",
    "1Uko1",
    "1Ukok",
    "1Ukos",
    "1Ukov",
    "1Uks",
    "1Uks,",
    "1Uksc",
    "1Uksf",
    "1Uksk",
    "1Uksn",
    "1Ukso",
    "1Ukv",
    "1Ukv,",
    "1Ukvc",
    "1Ukvf",
    "1Ukvk",
    "1Ukvn",
    "1Ukvo",
    "1Un,1",
    "1Un,s",
    "1Un,v",
    "1Un1,",
    "1Unk(",
    "1Unk1",
    "1Unkf",
    "1Unks",
    "1Unkv",
    "1Uns,",
    "1Unv,",
    "1Uon1",
    "1Uons",
    "1Uonv",
    "1Us,1",
    "1Us,v",
    "1Uv,1",
    "1Uv,s",
    "1Uv,v",
    "1c",
    "1f()k",
    "1k1U(",
    "1k1Uk",
    "1k1c",
    "1kU1,",
    "1kUs,",
    "1kUv,",
    "1kf(1",
    "1kf(s",
    "1kf(v",
    "1kk(1",
    "1kk(s",
    "1kk(v",
    "1kksc",
    "1kkvc",
    "1knkn",
    "1kno1",
    "1kokn",
    "1ksU(",
    "1ksUk",
    "1ksc",
    "1kvU(",
    "1kvUk",
    "1kvc",
    "1n&f(",
    "1n)Uk",
    "1nUk1",
    "1nUkn",
    "1nUks",
    "1nUkv",
    "1nk1c",
    "1nkf(",
    "1nksc",
    "1nkvc",
    "1o(((",
    "1o((1",
    "1o((f",
    "1o((s",
    "1o((v",
    "1o(1)",
    "1o(1o",
    "1o(f(",
    "1o(k(",
    "1o(k1",
    "1o(kf",
    "1o(kn",
    "1o(ks",
    "1o(kv",
    "1o(n)",
    "1o(o1",
    "1o(os",
    "1o(s)",
    "1o(so",
    "1o(v)",
    "1o(vo",
    "1o1)&",
    "1o1)o",
    "1o1Bf",
    "1o1Uk",
    "1o1f(",
    "1o1kf",
    "1o1o(",
    "1o1o1",
    "1o1of",
    "1o1oo",
    "1o1os",
    "1o1ov",
    "1of()",
    "1of(1",
    "1of(f",
    "1of(n",
    "1of(s",
    "1of(v",
    "1ok(1",
    "1ok(k",
    "1ok(s",
    "1ok(v",
    "1ok)U",
    "1ok)o",
    "1ok1",
    "1ok1,",
    "1ok1c",
    "1ok1k",
    "1okUk",
    "1okf(",
    "1oks",
    "1oks,",
    "1oksc",
    "1oksk",
    "1okv",
    "1okv,",
    "1okvc",
    "1okvk",
    "1onov",
    "1os)&",
    "1os)U",
    "1os)o",
    "1osBf",
    "1osUk",
    "1osf(",
    "1oskf",
    "1oso(",
    "1oso1",
    "1osof",
    "1osoo",
    "1osos",
    "1osov",
    "1ov)&",
    "1ov)U",
    "1ov)o",
    "1ovBf",
    "1ovUk",
    "1ovf(",
    "1ovkf",
    "1ovo(",
    "1ovo1",
    "1ovof",
    "1ovoo",
    "1ovos",
    "1ovov",
    ";kknc",
    "Uk1,1",
    "Uk1,f",
    "Uk1,n",
    "Uk1,s",
    "Uk1,v",
    "Ukkkn",
    "Uks,1",
    "Uks,f",
    "Uks,n",
    "Uks,v",
    "Ukv,1",
    "Ukv,f",
    "Ukv,n",
    "Ukv,s",
    "Ukv,v",
    "f((k(",
    "f((kf",
    "f()&f",
    "f()of",
    "f(1)&",
    "f(1)U",
    "f(1)o",
    "f(1,1",
    "f(1,f",
    "f(1,s",
    "f(1,v",
    "f(1o1",
    "f(1os",
    "f(1ov",
    "f(f()",
    "f(f(1",
    "f(f(f",
    "f(f(s",
    "f(f(v",
    "f(k()",
    "f(k,(",
    "f(k,n",
    "f(n()",
    "f(s)&",
    "f(s)U",
    "f(s)o",
    "f(s,1",
    "f(s,f",
    "f(s,v",
    "f(so1",
    "f(sov",
    "f(v)&",
    "f(v)U",
    "f(v)o",
    "f(v,1",
    "f(v,f",
    "f(v,s",
    "f(v,v",
    "f(vo1",
    "f(vos",
    "f(vov",
    "k()ok",
    "k(1)U",
    "k(ok(",
    "k(s)U",
    "k(sv)",
    "k(v)U",
    "k(vs)",
    "k(vv)",
    "k1,1,",
    "k1,1c",
    "k1,1k",
    "k1,f(",
    "k1,n,",
    "k1,s,",
    "k1,sc",
    "k1,sk",
    "k1,v,",
    "k1,vc",
    "k1,vk",
    "k1k(k",
    "k1o(s",
    "k1o(v",
    "k;non",
    "kf(1)",
    "kf(1,",
    "kf(f(",
    "kf(n,",
    "kf(o)",
    "kf(s)",
    "kf(s,",
    "kf(s:",
    "kf(v)",
    "kf(v,",
    "kf(v:",
    "kk(f(",
    "kk1f(",
    "kk1fn",
    "kk1kk",
    "kk1nk",
    "kk1sk",
    "kk1sn",
    "kk1vk",
    "kk1vn",
    "kksf(",
    "kksfn",
    "kkskk",
    "kksnk",
    "kksvk",
    "kksvn",
    "kkvf(",
    "kkvfn",
    "kkvkk",
    "kkvnk",
    "kkvsk",
    "kkvsn",
    "kkvvk",
    "kkvvn",
    "kn1kk",
    "kn1sk",
    "kn1sn",
    "kn1vk",
    "kn1vn",
    "knk(k",
    "knskk",
    "knsvk",
    "knsvn",
    "knvkk",
    "knvsk",
    "knvsn",
    "knvvk",
    "knvvn",
    "ko(k(",
    "ko(kf",
    "kok(k",
    "ks)",
    "ks,1,",
    "ks,1c",
    "ks,1k",
    "ks,f(",
    "ks,v,",
    "ks,vc",
    "ks,vk",
    "ksf(1",
    "ksf(v",
    "ksk(1",
    "ksk(k",
    "ksk(v",
    "kso(s",
    "kso(v",
    "kv)",
    "kv,1,",
    "kv,1c",
    "kv,1k",
    "kv,f(",
    "kv,s,",
    "kv,sc",
    "kv,sk",
    "kv,v,",
    "kv,vc",
    "kv,vk",
    "kvf(1",
    "kvf(s",
    "kvf(v",
    "kvk(1",
    "kvk(k",
    "kvk(s",
    "kvk(v",
    "kvo(s",
    "kvo(v",
    "n&(1)",
    "n&(1,",
    "n&(k1",
    "n&(ks",
    "n&(kv",
    "n&(o1",
    "n&(os",
    "n&(ov",
    "n&(s)",
    "n&(s,",
    "n&(v)",
    "n&(v,",
    "n&1Bf",
    "n&1f(",
    "n&1o(",
    "n&1o1",
    "n&1of",
    "n&1oo",
    "n&1os",
    "n&1ov",
    "n&f(1",
    "n&f(f",
    "n&f(s",
    "n&f(v",
    "n&k(1",
    "n&k(s",
    "n&k(v",
    "n&o1o",
    "n&oso",
    "n&ovo",
    "n&sf(",
    "n&so(",
    "n&so1",
    "n&sof",
    "n&soo",
    "n&sov",
    "n&vf(",
    "n&vo(",
    "n&vo1",
    "n&vof",
    "n&voo",
    "n&vos",
    "n&vov",
    "n)&(k",
    "n)&1f",
    "n)&1o",
    "n)&f(",
    "n)&sf",
    "n)&so",
    "n)&vf",
    "n)&vo",
    "n))&(",
    "n))&1",
    "n))&f",
    "n))&s",
    "n))&v",
    "n)))&",
    "n)));",
    "n)))k",
    "n)))o",
    "n));k",
    "n))kk",
    "n))o(",
    "n))o1",
    "n))of",
    "n))ok",
    "n))os",
    "n))ov",
    "n);k&",
    "n);k(",
    "n);kf",
    "n);kk",
    "n);kn",
    "n);ko",
    "n)k1o",
    "n)kks",
    "n)kkv",
    "n)kso",
    "n)kvo",
    "n)o(k",
    "n)o1&",
    "n)o1f",
    "n)o1o",
    "n)of(",
    "n)ok(",
    "n)os&",
    "n)osf",
    "n)oso",
    "n)ov&",
    "n)ovf",
    "n)ovo",
    "n,(f(",
    "n,(k(",
    "n,(k1",
    "n,(kf",
    "n,(ks",
    "n,(kv",
    "n,f(1",
    "n,f(s",
    "n,f(v",
    "n:o1U",
    "n:osU",
    "n:ovU",
    "n;k&k",
    "n;k((",
    "n;k(1",
    "n;k(s",
    "n;k(v",
    "n;kf(",
    "n;kks",
    "n;kkv",
    "n;kn(",
    "n;ko(",
    "n;kok",
    "nUk(k",
    "nUk1,",
    "nUkf(",
    "nUkn,",
    "nUks,",
    "nUkv,",
    "nUnk(",
    "nk1Uk",
    "nk1o1",
    "nkf(1",
    "nkf(s",
    "nkf(v",
    "nkksc",
    "nkkvc",
    "nksUk",
    "nkvUk",
    "nnn)U",
    "nno1U",
    "nnosU",
    "nnovU",
    "no(k1",
    "no(ks",
    "no(kv",
    "no(o1",
    "no(os",
    "no(ov",
    "no1&1",
    "no1&s",
    "no1&v",
    "no1Uk",
    "no1f(",
    "no1o(",
    "no1of",
    "no1oo",
    "no1os",
    "no1ov",
    "nof(1",
    "nof(s",
    "nof(v",
    "nok(f",
    "nok(k",
    "nok(s",
    "nok(v",
    "nono1",
    "nos&1",
    "nos&v",
    "nosUk",
    "nosf(",
    "noso(",
    "noso1",
    "nosof",
    "nosoo",
    "nosov",
    "nov&1",
    "nov&s",
    "nov&v",
    "novUk",
    "novf(",
    "novo(",
    "novo1",
    "novof",
    "novoo",
    "novos",
    "novov",
    "o1kf(",
    "oUk1,",
    "oUks,",
    "oUkv,",
    "of()o",
    "of(1)",
    "of(s)",
    "of(v)",
    "ok1o1",
    "ok1os",
    "ok1ov",
    "okkkn",
    "okso1",
    "oksov",
    "okvo1",
    "okvos",
    "okvov",
    "ook1,",
    "ooks,",
    "ookv,",
    "oskf(",
    "ovkf(",
    "s&((f",
    "s&((k",
    "s&(1)",
    "s&(1,",
    "s&(1o",
    "s&(f(",
    "s&(k(",
    "s&(k)",
    "s&(k1",
    "s&(kf",
    "s&(kk",
    "s&(kn",
    "s&(ko",
    "s&(ks",
    "s&(kv",
    "s&(s)",
    "s&(s,",
    "s&(so",
    "s&(v)",
    "s&(v,",
    "s&(vo",
    "s&1",
    "s&1Bf",
    "s&1Uk",
    "s&1c",
    "s&1f(",
    "s&1o(",
    "s&1o1",
    "s&1of",
    "s&1ok",
    "s&1on",
    "s&1oo",
    "s&1os",
    "s&1ov",
    "s&f((",
    "s&f()",
    "s&f(1",
    "s&f(f",
    "s&f(k",
    "s&f(n",
    "s&f(s",
    "s&f(v",
    "s&k&s",
    "s&k&v",
    "s&k(1",
    "s&k(f",
    "s&k(o",
    "s&k(s",
    "s&k(v",
    "s&k1k",
    "s&k1o",
    "s&kUk",
    "s&kc",
    "s&kk1",
    "s&kkv",
    "s&knk",
    "s&ko(",
    "s&ko1",
    "s&kok",
    "s&kos",
    "s&kov",
    "s&kso",
    "s&kvk",
    "s&kvo",
    "s&n&s",
    "s&n&v",
    "s&n()",
    "s&no1",
    "s&nos",
    "s&nov",
    "s&o(1",
    "s&o(k",
    "s&o(s",
    "s&o(v",
    "s&o1o",
    "s&okc",
    "s&oko",
    "s&os",
    "s&oso",
    "s&ov",
    "s&ovo",
    "s&s",
    "s&s:o",
    "s&sBf",
    "s&sU(",
    "s&sUk",
    "s&sc",
    "s&sf(",
    "s&so(",
    "s&so1",
    "s&sof",
    "s&son",
    "s&soo",
    "s&sos",
    "s&sov",
    "s&sso",
    "s&svo",
    "s&v:o",
    "s&vBf",
    "s&vU(",
    "s&vUk",
    "s&vc",
    "s&vf(",
    "s&vo(",
    "s&vo1",
    "s&vof",
    "s&vok",
    "s&von",
    "s&voo",
    "s&vos",
    "s&vov",
    "s&vso",
    "s&vvo",
    "s)&(1",
    "s)&(f",
    "s)&(k",
    "s)&(n",
    "s)&(s",
    "s)&(v",
    "s)&1B",
    "s)&1U",
    "s)&1f",
    "s)&1o",
    "s)&f(",
    "s)&o(",
    "s)&sB",
    "s)&sf",
    "s)&so",
    "s)&vB",
    "s)&vU",
    "s)&vf",
    "s)&vo",
    "s)()s",
    "s)()v",
    "s))&(",
    "s))&1",
    "s))&f",
    "s))&n",
    "s))&o",
    "s))&s",
    "s))&v",
    "s)))&",
    "s))))",
    "s)));",
    "s)))B",
    "s)))U",
    "s)))k",
    "s)))o",
    "s));k",
    "s))B1",
    "s))Bs",
    "s))Bv",
    "s))Uk",
    "s))Un",
    "s))k1",
    "s))kk",
    "s))ks",
    "s))kv",
    "s))o(",
    "s))o1",
    "s))of",
    "s))ok",
    "s))on",
    "s))os",
    "s))ov",
    "s),(1",
    "s),(s",
    "s),(v",
    "s);k&",
    "s);k(",
    "s);kf",
    "s);kk",
    "s);kn",
    "s);ko",
    "s)B1",
    "s)B1&",
    "s)B1c",
    "s)B1o",
    "s)Bs",
    "s)Bs&",
    "s)Bsc",
    "s)Bso",
    "s)Bv",
    "s)Bv&",
    "s)Bvc",
    "s)Bvo",
    "s)U(k",
    "s)Uk(",
    "s)Uk1",
    "s)Ukf",
    "s)Ukk",
    "s)Ukn",
    "s)Uko",
    "s)Uks",
    "s)Ukv",
    "s)Unk",
    "s)k1",
    "s)k1c",
    "s)k1o",
    "s)kks",
    "s)kkv",
    "s)ks",
    "s)ksc",
    "s)kso",
    "s)kv",
    "s)kvc",
    "s)kvo",
    "s)o(1",
    "s)o(k",
    "s)o(n",
    "s)o(s",
    "s)o(v",
    "s)o1B",
    "s)o1f",
    "s)o1k",
    "s)o1o",
    "s)of(",
    "s)ok(",
    "s)ok1",
    "s)oks",
    "s)okv",
    "s)on&",
    "s)os)",
    "s)osB",
    "s)osU",
    "s)osf",
    "s)osk",
    "s)oso",
    "s)ov)",
    "s)ovB",
    "s)ovf",
    "s)ovk",
    "s)ovo",
    "s,(f(",
    "s,(k(",
    "s,(k1",
    "s,(kf",
    "s,(kv",
    "s,1),",
    "s,1)o",
    "s,1B1",
    "s,1Bv",
    "s,1Uk",
    "s,f(1",
    "s,f(v",
    "s,s),",
    "s,v),",
    "s,v)o",
    "s,vB1",
    "s,vBv",
    "s,vUk",
    "s:o1)",
    "s:ov)",
    "s;k&k",
    "s;k((",
    "s;k(1",
    "s;k(o",
    "s;k(s",
    "s;k(v",
    "s;k1,",
    "s;k1o",
    "s;k;",
    "s;k[k",
    "s;k[n",
    "s;kf(",
    "s;kkn",
    "s;kks",
    "s;kkv",
    "s;kn(",
    "s;kn,",
    "s;knc",
    "s;knk",
    "s;knn",
    "s;ko(",
    "s;kok",
    "s;ks,",
    "s;ksc",
    "s;ksk",
    "s;kso",
    "s;kv,",
    "s;kvc",
    "s;kvk",
    "s;kvo",
    "s;n:k",
    "sB1",
    "sB1&s",
    "sB1&v",
    "sB1,1",
    "sB1,n",
    "sB1,v",
    "sB1Uk",
    "sB1c",
    "sB1k1",
    "sB1ks",
    "sB1kv",
    "sB1os",
    "sB1ov",
    "sBf(1",
    "sBf(f",
    "sBf(v",
    "sBk(1",
    "sBk(v",
    "sBn,n",
    "sBnk1",
    "sBnkv",
    "sBs",
    "sBs&s",
    "sBs&v",
    "sBsUk",
    "sBsc",
    "sBsos",
    "sBsov",
    "sBv",
    "sBv&s",
    "sBv&v",
    "sBv,1",
    "sBv,n",
    "sBv,v",
    "sBvUk",
    "sBvc",
    "sBvk1",
    "sBvks",
    "sBvkv",
    "sBvos",
    "sBvov",
    "sU((k",
    "sU(k(",
    "sU(k1",
    "sU(kf",
    "sU(kk",
    "sU(kn",
    "sU(ks",
    "sU(kv",
    "sU1,1",
    "sU1,v",
    "sUc",
    "sUk",
    "sUk(1",
    "sUk(k",
    "sUk(n",
    "sUk(v",
    "sUk1",
    "sUk1&",
    "sUk1,",
    "sUk1c",
    "sUk1f",
    "sUk1k",
    "sUk1n",
    "sUk1o",
    "sUkf",
    "sUkf(",
    "sUkf,",
    "sUkk(",
    "sUkk,",
    "sUkk1",
    "sUkkk",
    "sUkkn",
    "sUkks",
    "sUkkv",
    "sUkn&",
    "sUkn(",
    "sUkn,",
    "sUkn1",
    "sUknc",
    "sUknk",
    "sUkno",
    "sUkns",
    "sUknv",
    "sUko1",
    "sUkok",
    "sUkov",
    "sUks",
    "sUks&",
    "sUks,",
    "sUksc",
    "sUksk",
    "sUkso",
    "sUkv",
    "sUkv&",
    "sUkv,",
    "sUkvc",
    "sUkvf",
    "sUkvk",
    "sUkvn",
    "sUkvo",
    "sUn(k",
    "sUn,1",
    "sUn,v",
    "sUn1,",
    "sUnk(",
    "sUnk1",
    "sUnkf",
    "sUnks",
    "sUnkv",
    "sUno1",
    "sUnos",
    "sUnov",
    "sUnv,",
    "sUon1",
    "sUonv",
    "sUv,1",
    "sUv,v",
    "sc",
    "sf()k",
    "sf(1)",
    "sf(n,",
    "sf(s)",
    "sf(v)",
    "sk)&(",
    "sk)&1",
    "sk)&f",
    "sk)&s",
    "sk)&v",
    "sk);k",
    "sk)B1",
    "sk)Bs",
    "sk)Bv",
    "sk)Uk",
    "sk)Un",
    "sk)k1",
    "sk)kk",
    "sk)ks",
    "sk)kv",
    "sk)o(",
    "sk)o1",
    "sk)of",
    "sk)ok",
    "sk)os",
    "sk)ov",
    "sk1&1",
    "sk1&s",
    "sk1&v",
    "sk1U(",
    "sk1Uk",
    "sk1c",
    "sk1o1",
    "sk1os",
    "sk1ov",
    "skU1,",
    "skUs,",
    "skUv,",
    "skf(1",
    "skf(v",
    "skk(1",
    "skk(v",
    "skks",
    "skksc",
    "skkv",
    "skkvc",
    "sknkn",
    "sks&1",
    "sks&v",
    "sksUk",
    "sksc",
    "skso1",
    "sksos",
    "sksov",
    "skv&1",
    "skv&s",
    "skv&v",
    "skvU(",
    "skvUk",
    "skvc",
    "skvo1",
    "skvos",
    "skvov",
    "sn&f(",
    "sn,f(",
    "snUk1",
    "snUkn",
    "snUkv",
    "snk1c",
    "snkf(",
    "snkvc",
    "sno(s",
    "sno1U",
    "snosU",
    "snovU",
    "so(((",
    "so((1",
    "so((f",
    "so((k",
    "so((s",
    "so((v",
    "so(1)",
    "so(1o",
    "so(f(",
    "so(k(",
    "so(k)",
    "so(k1",
    "so(kf",
    "so(kk",
    "so(kn",
    "so(ko",
    "so(ks",
    "so(kv",
    "so(n)",
    "so(o1",
    "so(os",
    "so(ov",
    "so(s)",
    "so(so",
    "so(v)",
    "so(vo",
    "so1&1",
    "so1&o",
    "so1&s",
    "so1&v",
    "so1)&",
    "so1)o",
    "so1Bf",
    "so1Uk",
    "so1c",
    "so1f(",
    "so1kf",
    "so1o(",
    "so1o1",
    "so1of",
    "so1ok",
    "so1oo",
    "so1os",
    "so1ov",
    "sof()",
    "sof(1",
    "sof(f",
    "sof(k",
    "sof(n",
    "sof(s",
    "sof(v",
    "sok&s",
    "sok&v",
    "sok(1",
    "sok(k",
    "sok(o",
    "sok(s",
    "sok(v",
    "sok1",
    "sok1,",
    "sok1c",
    "sok1k",
    "sok1o",
    "sokUk",
    "sokc",
    "sokf(",
    "sokn,",
    "soknk",
    "soko(",
    "soko1",
    "sokok",
    "sokos",
    "sokov",
    "soks",
    "soks,",
    "soksc",
    "sokso",
    "sokv",
    "sokv,",
    "sokvc",
    "sokvk",
    "sokvo",
    "sonk1",
    "sonks",
    "sonkv",
    "sonos",
    "sonov",
    "sos",
    "sos&(",
    "sos&1",
    "sos&o",
    "sos&s",
    "sos&v",
    "sos:o",
    "sosBf",
    "sosUk",
    "sosc",
    "sosf(",
    "soskf",
    "soso(",
    "soso1",
    "sosof",
    "sosok",
    "sosoo",
    "sosos",
    "sosov",
    "sosso",
    "sosvo",
    "sov",
    "sov&(",
    "sov&1",
    "sov&o",
    "sov&s",
    "sov&v",
    "sov)&",
    "sov)o",
    "sov:o",
    "sovBf",
    "sovUk",
    "sovc",
    "sovf(",
    "sovkf",
    "sovo(",
    "sovo1",
    "sovof",
    "sovok",
    "sovoo",
    "sovos",
    "sovov",
    "sovso",
    "sovvo",
    "v&((f",
    "v&((k",
    "v&(1)",
    "v&(1,",
    "v&(1o",
    "v&(f(",
    "v&(k(",
    "v&(k)",
    "v&(k1",
    "v&(kf",
    "v&(kk",
    "v&(kn",
    "v&(ko",
    "v&(ks",
    "v&(kv",
    "v&(s)",
    "v&(s,",
    "v&(so",
    "v&(v)",
    "v&(v,",
    "v&(vo",
    "v&1Bf",
    "v&1Uk",
    "v&1c",
    "v&1f(",
    "v&1o(",
    "v&1o1",
    "v&1of",
    "v&1ok",
    "v&1on",
    "v&1oo",
    "v&1os",
    "v&1ov",
    "v&f((",
    "v&f()",
    "v&f(1",
    "v&f(f",
    "v&f(k",
    "v&f(n",
    "v&f(s",
    "v&f(v",
    "v&k&s",
    "v&k&v",
    "v&k(1",
    "v&k(f",
    "v&k(o",
    "v&k(s",
    "v&k(v",
    "v&k1k",
    "v&k1o",
    "v&kUk",
    "v&kc",
    "v&kk1",
    "v&kks",
    "v&kkv",
    "v&knk",
    "v&ko(",
    "v&ko1",
    "v&kok",
    "v&kos",
    "v&kov",
    "v&ksk",
    "v&kso",
    "v&kvk",
    "v&kvo",
    "v&n&s",
    "v&n&v",
    "v&n()",
    "v&no1",
    "v&nos",
    "v&nov",
    "v&o(1",
    "v&o(k",
    "v&o(s",
    "v&o(v",
    "v&o1o",
    "v&okc",
    "v&oko",
    "v&os",
    "v&oso",
    "v&ov",
    "v&ovo",
    "v&s:o",
    "v&sBf",
    "v&sU(",
    "v&sUk",
    "v&sc",
    "v&sf(",
    "v&so(",
    "v&so1",
    "v&sof",
    "v&sok",
    "v&son",
    "v&soo",
    "v&sos",
    "v&sov",
    "v&sso",
    "v&svo",
    "v&v:o",
    "v&vBf",
    "v&vU(",
    "v&vUk",
    "v&vc",
    "v&vf(",
    "v&vo(",
    "v&vo1",
    "v&vof",
    "v&vok",
    "v&von",
    "v&voo",
    "v&vos",
    "v&vov",
    "v&vso",
    "v&vvo",
    "v)&(1",
    "v)&(f",
    "v)&(k",
    "v)&(n",
    "v)&(s",
    "v)&(v",
    "v)&1B",
    "v)&1U",
    "v)&1f",
    "v)&1o",
    "v)&f(",
    "v)&o(",
    "v)&sB",
    "v)&sU",
    "v)&sf",
    "v)&so",
    "v)&vB",
    "v)&vU",
    "v)&vf",
    "v)&vo",
    "v)()s",
    "v)()v",
    "v))&(",
    "v))&1",
    "v))&f",
    "v))&n",
    "v))&o",
    "v))&s",
    "v))&v",
    "v)))&",
    "v))))",
    "v)));",
    "v)))B",
    "v)))U",
    "v)))k",
    "v)))o",
    "v));k",
    "v))B1",
    "v))Bs",
    "v))Bv",
    "v))Uk",
    "v))Un",
    "v))k1",
    "v))kk",
    "v))ks",
    "v))kv",
    "v))o(",
    "v))o1",
    "v))of",
    "v))ok",
    "v))on",
    "v))os",
    "v))ov",
    "v),(1",
    "v),(s",
    "v),(v",
    "v);k&",
    "v);k(",
    "v);kf",
    "v);kk",
    "v);kn",
    "v);ko",
    "v)B1",
    "v)B1&",
    "v)B1c",
    "v)B1o",
    "v)Bs",
    "v)Bs&",
    "v)Bsc",
    "v)Bso",
    "v)Bv",
    "v)Bv&",
    "v)Bvc",
    "v)Bvo",
    "v)U(k",
    "v)Uk(",
    "v)Uk1",
    "v)Ukf",
    "v)Ukk",
    "v)Ukn",
    "v)Uko",
    "v)Uks",
    "v)Ukv",
    "v)Unk",
    "v)k1",
    "v)k1c",
    "v)k1o",
    "v)kks",
    "v)kkv",
    "v)ks",
    "v)ksc",
    "v)kso",
    "v)kv",
    "v)kvc",
    "v)kvo",
    "v)o(1",
    "v)o(k",
    "v)o(n",
    "v)o(s",
    "v)o(v",
    "v)o1B",
    "v)o1U",
    "v)o1f",
    "v)o1k",
    "v)o1o",
    "v)of(",
    "v)ok(",
    "v)ok1",
    "v)oks",
    "v)okv",
    "v)on&",
    "v)ono",
    "v)os)",
    "v)osB",
    "v)osU",
    "v)osf",
    "v)osk",
    "v)oso",
    "v)ovB",
    "v)ovU",
    "v)ovf",
    "v)ovk",
    "v)ovo",
    "v,(f(",
    "v,(k(",
    "v,(k1",
    "v,(kf",
    "v,(ks",
    "v,(kv",
    "v,1),",
    "v,1)o",
    "v,1B1",
    "v,1Bs",
    "v,1Bv",
    "v,1Uk",
    "v,f(1",
    "v,f(s",
    "v,f(v",
    "v,s),",
    "v,s)o",
    "v,sB1",
    "v,sBv",
    "v,sUk",
    "v,v),",
    "v,v)o",
    "v,vB1",
    "v,vBs",
    "v,vBv",
    "v,vUk",
    "v:o1)",
    "v:os)",
    "v:ov)",
    "v;k&k",
    "v;k((",
    "v;k(1",
    "v;k(o",
    "v;k(s",
    "v;k(v",
    "v;k1,",
    "v;k1o",
    "v;k;",
    "v;k[k",
    "v;k[n",
    "v;kf(",
    "v;kkn",
    "v;kks",
    "v;kkv",
    "v;kn(",
    "v;kn,",
    "v;knc",
    "v;knk",
    "v;knn",
    "v;ko(",
    "v;kok",
    "v;ks,",
    "v;ksc",
    "v;ksk",
    "v;kso",
    "v;kv,",
    "v;kvc",
    "v;kvk",
    "v;kvo",
    "v;n:k",
    "vB1",
    "vB1&s",
    "vB1&v",
    "vB1,1",
    "vB1,n",
    "vB1,s",
    "vB1,v",
    "vB1Uk",
    "vB1c",
    "vB1k1",
    "vB1ks",
    "vB1kv",
    "vB1os",
    "vB1ov",
    "vBf(1",
    "vBf(f",
    "vBf(s",
    "vBf(v",
    "vBk(1",
    "vBk(s",
    "vBk(v",
    "vBn,n",
    "vBnk1",
    "vBnks",
    "vBnkv",
    "vBs",
    "vBs&s",
    "vBs&v",
    "vBs,1",
    "vBs,n",
    "vBs,v",
    "vBsUk",
    "vBsc",
    "vBsk1",
    "vBsks",
    "vBskv",
    "vBsos",
    "vBsov",
    "vBv",
    "vBv&s",
    "vBv&v",
    "vBv,1",
    "vBv,n",
    "vBv,s",
    "vBv,v",
    "vBvUk",
    "vBvc",
    "vBvk1",
    "vBvks",
    "vBvkv",
    "vBvos",
    "vBvov",
    "vU((k",
    "vU(k(",
    "vU(k1",
    "vU(kf",
    "vU(kk",
    "vU(kn",
    "vU(ks",
    "vU(kv",
    "vU1,1",
    "vU1,s",
    "vU1,v",
    "vUc",
    "vUk",
    "vUk(1",
    "vUk(k",
    "vUk(n",
    "vUk(s",
    "vUk(v",
    "vUk1",
    "vUk1&",
    "vUk1,",
    "vUk1c",
    "vUk1f",
    "vUk1k",
    "vUk1n",
    "vUk1o",
    "vUkf",
    "vUkf(",
    "vUkf,",
    "vUkk(",
    "vUkk,",
    "vUkk1",
    "vUkkk",
    "vUkkn",
    "vUkks",
    "vUkkv",
    "vUkn&",
    "vUkn(",
    "vUkn,",
    "vUkn1",
    "vUknc",
    "vUknk",
    "vUkno",
    "vUkns",
    "vUknv",
    "vUko1",
    "vUkok",
    "vUkos",
    "vUkov",
    "vUks",
    "vUks&",
    "vUks,",
    "vUksc",
    "vUksf",
    "vUksk",
    "vUksn",
    "vUkso",
    "vUkv",
    "vUkv&",
    "vUkv,",
    "vUkvc",
    "vUkvf",
    "vUkvk",
    "vUkvn",
    "vUkvo",
    "vUn(k",
    "vUn,1",
    "vUn,s",
    "vUn,v",
    "vUn1,",
    "vUnk(",
    "vUnk1",
    "vUnkf",
    "vUnks",
    "vUnkv",
    "vUno1",
    "vUnos",
    "vUnov",
    "vUns,",
    "vUnv,",
    "vUon1",
    "vUons",
    "vUonv",
    "vUs,1",
    "vUs,v",
    "vUv,1",
    "vUv,s",
    "vUv,v",
    "vc",
    "vf()k",
    "vf(1)",
    "vf(n,",
    "vf(s)",
    "vf(v)",
    "vk)&(",
    "vk)&1",
    "vk)&f",
    "vk)&s",
    "vk)&v",
    "vk);k",
    "vk)B1",
    "vk)Bs",
    "vk)Bv",
    "vk)Uk",
    "vk)Un",
    "vk)k1",
    "vk)kk",
    "vk)ks",
    "vk)kv",
    "vk)o(",
    "vk)o1",
    "vk)of",
    "vk)ok",
    "vk)os",
    "vk)ov",
    "vk1&1",
    "vk1&s",
    "vk1&v",
    "vk1U(",
    "vk1Uk",
    "vk1c",
    "vk1o1",
    "vk1os",
    "vk1ov",
    "vkU1,",
    "vkUs,",
    "vkUv,",
    "vkf(1",
    "vkf(s",
    "vkf(v",
    "vkk(1",
    "vkk(s",
    "vkk(v",
    "vkks",
    "vkksc",
    "vkkv",
    "vkkvc",
    "vknkn",
    "vks&1",
    "vks&v",
    "vksU(",
    "vksUk",
    "vksc",
    "vkso1",
    "vksos",
    "vksov",
    "vkv&1",
    "vkv&s",
    "vkv&v",
    "vkvU(",
    "vkvUk",
    "vkvc",
    "vkvo1",
    "vkvos",
    "vkvov",
    "vn&f(",
    "vn,f(",
    "vnUk1",
    "vnUkn",
    "vnUks",
    "vnUkv",
    "vnk1c",
    "vnkf(",
    "vnksc",
    "vnkvc",
    "vno1U",
    "vnosU",
    "vnovU",
    "vo(((",
    "vo((1",
    "vo((f",
    "vo((k",
    "vo((s",
    "vo((v",
    "vo(1)",
    "vo(1o",
    "vo(f(",
    "vo(k(",
    "vo(k)",
    "vo(k1",
    "vo(kf",
    "vo(kk",
    "vo(kn",
    "vo(ko",
    "vo(ks",
    "vo(kv",
    "vo(n)",
    "vo(o1",
    "vo(os",
    "vo(ov",
    "vo(s)",
    "vo(so",
    "vo(v)",
    "vo(vo",
    "vo1&1",
    "vo1&o",
    "vo1&s",
    "vo1&v",
    "vo1)&",
    "vo1)o",
    "vo1Bf",
    "vo1Uk",
    "vo1c",
    "vo1f(",
    "vo1kf",
    "vo1o(",
    "vo1o1",
    "vo1of",
    "vo1ok",
    "vo1oo",
    "vo1os",
    "vo1ov",
    "vof()",
    "vof(1",
    "vof(f",
    "vof(k",
    "vof(n",
    "vof(s",
    "vof(v",
    "vok&s",
    "vok&v",
    "vok(1",
    "vok(k",
    "vok(o",
    "vok(s",
    "vok(v",
    "vok1",
    "vok1,",
    "vok1c",
    "vok1k",
    "vok1o",
    "vokUk",
    "vokc",
    "vokf(",
    "vokn,",
    "voknk",
    "voko(",
    "voko1",
    "vokok",
    "vokos",
    "vokov",
    "voks",
    "voks,",
    "voksc",
    "voksk",
    "vokso",
    "vokv",
    "vokv,",
    "vokvc",
    "vokvk",
    "vokvo",
    "vonk1",
    "vonks",
    "vonkv",
    "vono1",
    "vonos",
    "vonov",
    "vos",
    "vos&(",
    "vos&1",
    "vos&o",
    "vos&s",
    "vos&v",
    "vos)&",
    "vos)o",
    "vos:o",
    "vosBf",
    "vosUk",
    "vosc",
    "vosf(",
    "voskf",
    "voso(",
    "voso1",
    "vosof",
    "vosok",
    "vosoo",
    "vosos",
    "vosov",
    "vosso",
    "vosvo",
    "vov",
    "vov&(",
    "vov&1",
    "vov&o",
    "vov&s",
    "vov&v",
    "vov)&",
    "vov)o",
    "vov:o",
    "vovBf",
    "vovUk",
    "vovc",
    "vovf(",
    "vovkf",
    "vovo(",
    "vovo1",
    "vovof",
    "vovok",
    "vovoo",
    "vovos",
    "vovov",
    "vovso",
    "vovvo",
};
static const size_t patmap_sz = 2135;


/* Simple binary search */
int is_sqli_pattern(const char *key)
{
    int left = 0;
    int right = (int)patmap_sz - 1;

    while (left <= right) {
        int pos = (left + right) / 2;
        int cmp = strcmp(patmap[pos], key);
        if (cmp == 0) {
            return 1; /* TRUE */
        } else if (cmp < 0) {
            left = pos + 1;
        } else {
            right = pos - 1;
        }
    }
    return 0; /* FALSE */
}

#endif
-
-
- -
-
- - - - -
-
-
- - - - -
-
-
-
- - -
- - - - - -
-
-
- -
-
-
-
-
-
-
- - - - - - -
-
- - - -
- - Something went wrong with that request. Please try again. - -
- - - - - - - - +#ifndef _SQLPARSE_FINGERPRINTS_H +#define _SQLPARSE_FINGERPRINTS_H + +static const char* patmap[] = { + "&1o1U", + "&1osU", + "&1ovU", + "&f()o", + "&f(1)", + "&f(1o", + "&f(s)", + "&f(v)", + "&so1U", + "&sovU", + "&vo1U", + "&vosU", + "&vovU", + "1&((f", + "1&((k", + "1&(1)", + "1&(1,", + "1&(1o", + "1&(f(", + "1&(k(", + "1&(k1", + "1&(kf", + "1&(kk", + "1&(kn", + "1&(ko", + "1&(ks", + "1&(kv", + "1&(s)", + "1&(s,", + "1&(so", + "1&(v)", + "1&(v,", + "1&(vo", + "1&1", + "1&1Bf", + "1&1Uk", + "1&1c", + "1&1f(", + "1&1o(", + "1&1o1", + "1&1of", + "1&1ok", + "1&1on", + "1&1oo", + "1&1os", + "1&1ov", + "1&f((", + "1&f()", + "1&f(1", + "1&f(f", + "1&f(k", + "1&f(n", + "1&f(s", + "1&f(v", + "1&k(1", + "1&k(f", + "1&k(s", + "1&k(v", + "1&k1k", + "1&kUk", + "1&kk1", + "1&kks", + "1&kkv", + "1&ksk", + "1&kvk", + "1&n()", + "1&no1", + "1&nos", + "1&nov", + "1&o(1", + "1&o(s", + "1&o(v", + "1&o1o", + "1&oso", + "1&ovo", + "1&sBf", + "1&sU(", + "1&sUk", + "1&sf(", + "1&so(", + "1&so1", + "1&sof", + "1&sok", + "1&son", + "1&soo", + "1&sos", + "1&sov", + "1&vBf", + "1&vU(", + "1&vUk", + "1&vf(", + "1&vo(", + "1&vo1", + "1&vof", + "1&vok", + "1&von", + "1&voo", + "1&vos", + "1&vov", + "1)&(1", + "1)&(f", + "1)&(k", + "1)&(n", + "1)&(s", + "1)&(v", + "1)&1B", + "1)&1U", + "1)&1f", + "1)&1o", + "1)&f(", + "1)&o(", + "1)&sB", + "1)&sU", + "1)&sf", + "1)&so", + "1)&vB", + "1)&vU", + "1)&vf", + "1)&vo", + "1)()s", + "1)()v", + "1))&(", + "1))&1", + "1))&f", + "1))&o", + "1))&s", + "1))&v", + "1)))&", + "1))))", + "1)));", + "1)))B", + "1)))U", + "1)))k", + "1)))o", + "1));k", + "1))B1", + "1))Bs", + "1))Bv", + "1))Uk", + "1))Un", + "1))k1", + "1))kk", + "1))ks", + "1))kv", + "1))o(", + "1))o1", + "1))of", + "1))ok", + "1))on", + "1))os", + "1))ov", + "1),(1", + "1),(s", + "1),(v", + "1);k&", + "1);k(", + "1);kf", + "1);kk", + "1);kn", + "1);ko", + "1)B1", + "1)B1&", + "1)B1c", + "1)B1o", + "1)Bs", + "1)Bs&", + "1)Bsc", + "1)Bso", + "1)Bv", + "1)Bv&", + "1)Bvc", + "1)Bvo", + "1)U(k", + "1)Uk(", + "1)Uk1", + "1)Ukf", + "1)Ukk", + "1)Ukn", + "1)Uko", + "1)Uks", + "1)Ukv", + "1)Unk", + "1)k1", + "1)k1c", + "1)k1o", + "1)kks", + "1)kkv", + "1)knk", + "1)ks", + "1)ksc", + "1)kso", + "1)kv", + "1)kvc", + "1)kvo", + "1)o(1", + "1)o(k", + "1)o(n", + "1)o(s", + "1)o(v", + "1)o1)", + "1)o1B", + "1)o1U", + "1)o1f", + "1)o1k", + "1)o1o", + "1)of(", + "1)ok(", + "1)ok1", + "1)oks", + "1)okv", + "1)on&", + "1)ono", + "1)os)", + "1)osB", + "1)osU", + "1)osf", + "1)osk", + "1)oso", + "1)ov)", + "1)ovB", + "1)ovU", + "1)ovf", + "1)ovk", + "1)ovo", + "1,(f(", + "1,(k(", + "1,(k1", + "1,(kf", + "1,(ks", + "1,(kv", + "1,1),", + "1,1)o", + "1,1B1", + "1,1Bs", + "1,1Bv", + "1,1Uk", + "1,f(1", + "1,f(s", + "1,f(v", + "1,s),", + "1,s)o", + "1,sB1", + "1,sBv", + "1,sUk", + "1,v),", + "1,v)o", + "1,vB1", + "1,vBs", + "1,vBv", + "1,vUk", + "1;k&k", + "1;k((", + "1;k(1", + "1;k(o", + "1;k(s", + "1;k(v", + "1;k1,", + "1;kf(", + "1;kks", + "1;kkv", + "1;kn(", + "1;kn,", + "1;knc", + "1;ko(", + "1;kok", + "1;ks,", + "1;kv,", + "1B1", + "1B1,1", + "1B1,n", + "1B1,s", + "1B1,v", + "1B1Uk", + "1B1c", + "1B1k1", + "1B1ks", + "1B1kv", + "1Bf(1", + "1Bf(f", + "1Bf(s", + "1Bf(v", + "1Bk(1", + "1Bk(s", + "1Bk(v", + "1Bn,n", + "1Bnk1", + "1Bnks", + "1Bnkv", + "1Bs", + "1Bs,1", + "1Bs,n", + "1Bs,v", + "1BsUk", + "1Bsc", + "1Bsk1", + "1Bsks", + "1Bskv", + "1Bv", + "1Bv,1", + "1Bv,n", + "1Bv,s", + "1Bv,v", + "1BvUk", + "1Bvc", + "1Bvk1", + "1Bvks", + "1Bvkv", + "1U", + "1U((k", + "1U(k1", + "1U(kf", + "1U(kn", + "1U(ks", + "1U(kv", + "1U1,1", + "1U1,s", + "1U1,v", + "1Uc", + "1Uk", + "1Uk(1", + "1Uk(k", + "1Uk(n", + "1Uk(s", + "1Uk(v", + "1Uk1", + "1Uk1,", + "1Uk1c", + "1Uk1f", + "1Uk1k", + "1Uk1n", + "1Uk1o", + "1Ukf", + "1Ukf(", + "1Ukf,", + "1Ukk(", + "1Ukk,", + "1Ukk1", + "1Ukkk", + "1Ukkn", + "1Ukks", + "1Ukkv", + "1Ukn&", + "1Ukn(", + "1Ukn,", + "1Ukn1", + "1Uknc", + "1Uknk", + "1Ukno", + "1Ukns", + "1Uknv", + "1Uko1", + "1Ukok", + "1Ukos", + "1Ukov", + "1Uks", + "1Uks,", + "1Uksc", + "1Uksf", + "1Uksk", + "1Uksn", + "1Ukso", + "1Ukv", + "1Ukv,", + "1Ukvc", + "1Ukvf", + "1Ukvk", + "1Ukvn", + "1Ukvo", + "1Un,1", + "1Un,s", + "1Un,v", + "1Un1,", + "1Unk(", + "1Unk1", + "1Unkf", + "1Unks", + "1Unkv", + "1Uns,", + "1Unv,", + "1Uon1", + "1Uons", + "1Uonv", + "1Us,1", + "1Us,v", + "1Uv,1", + "1Uv,s", + "1Uv,v", + "1c", + "1f()k", + "1k1U(", + "1k1Uk", + "1k1c", + "1kU1,", + "1kUs,", + "1kUv,", + "1kf(1", + "1kf(s", + "1kf(v", + "1kk(1", + "1kk(s", + "1kk(v", + "1kksc", + "1kkvc", + "1knkn", + "1kno1", + "1kokn", + "1ksU(", + "1ksUk", + "1ksc", + "1kvU(", + "1kvUk", + "1kvc", + "1n&f(", + "1n)Uk", + "1nUk1", + "1nUkn", + "1nUks", + "1nUkv", + "1nk1c", + "1nkf(", + "1nksc", + "1nkvc", + "1o(((", + "1o((1", + "1o((f", + "1o((s", + "1o((v", + "1o(1)", + "1o(1o", + "1o(f(", + "1o(k(", + "1o(k1", + "1o(kf", + "1o(kn", + "1o(ks", + "1o(kv", + "1o(n)", + "1o(o1", + "1o(os", + "1o(s)", + "1o(so", + "1o(v)", + "1o(vo", + "1o1)&", + "1o1)o", + "1o1Bf", + "1o1Uk", + "1o1f(", + "1o1kf", + "1o1o(", + "1o1o1", + "1o1of", + "1o1oo", + "1o1os", + "1o1ov", + "1of()", + "1of(1", + "1of(f", + "1of(n", + "1of(s", + "1of(v", + "1ok(1", + "1ok(k", + "1ok(s", + "1ok(v", + "1ok)U", + "1ok)o", + "1ok1", + "1ok1,", + "1ok1c", + "1ok1k", + "1okUk", + "1okf(", + "1oks", + "1oks,", + "1oksc", + "1oksk", + "1okv", + "1okv,", + "1okvc", + "1okvk", + "1onov", + "1os)&", + "1os)U", + "1os)o", + "1osBf", + "1osUk", + "1osf(", + "1oskf", + "1oso(", + "1oso1", + "1osof", + "1osoo", + "1osos", + "1osov", + "1ov)&", + "1ov)U", + "1ov)o", + "1ovBf", + "1ovUk", + "1ovf(", + "1ovkf", + "1ovo(", + "1ovo1", + "1ovof", + "1ovoo", + "1ovos", + "1ovov", + ";kknc", + "Uk1,1", + "Uk1,f", + "Uk1,n", + "Uk1,s", + "Uk1,v", + "Ukkkn", + "Uks,1", + "Uks,f", + "Uks,n", + "Uks,v", + "Ukv,1", + "Ukv,f", + "Ukv,n", + "Ukv,s", + "Ukv,v", + "f((k(", + "f((kf", + "f()&f", + "f()of", + "f(1)&", + "f(1)U", + "f(1)o", + "f(1,1", + "f(1,f", + "f(1,s", + "f(1,v", + "f(1o1", + "f(1os", + "f(1ov", + "f(f()", + "f(f(1", + "f(f(f", + "f(f(s", + "f(f(v", + "f(k()", + "f(k,(", + "f(k,n", + "f(n()", + "f(s)&", + "f(s)U", + "f(s)o", + "f(s,1", + "f(s,f", + "f(s,v", + "f(so1", + "f(sov", + "f(v)&", + "f(v)U", + "f(v)o", + "f(v,1", + "f(v,f", + "f(v,s", + "f(v,v", + "f(vo1", + "f(vos", + "f(vov", + "k()ok", + "k(1)U", + "k(ok(", + "k(s)U", + "k(sv)", + "k(v)U", + "k(vs)", + "k(vv)", + "k1,1,", + "k1,1c", + "k1,1k", + "k1,f(", + "k1,n,", + "k1,s,", + "k1,sc", + "k1,sk", + "k1,v,", + "k1,vc", + "k1,vk", + "k1k(k", + "k1o(s", + "k1o(v", + "k;non", + "kf(1)", + "kf(1,", + "kf(f(", + "kf(n,", + "kf(o)", + "kf(s)", + "kf(s,", + "kf(s:", + "kf(v)", + "kf(v,", + "kf(v:", + "kk(f(", + "kk1f(", + "kk1fn", + "kk1kk", + "kk1nk", + "kk1sk", + "kk1sn", + "kk1vk", + "kk1vn", + "kksf(", + "kksfn", + "kkskk", + "kksnk", + "kksvk", + "kksvn", + "kkvf(", + "kkvfn", + "kkvkk", + "kkvnk", + "kkvsk", + "kkvsn", + "kkvvk", + "kkvvn", + "kn1kk", + "kn1sk", + "kn1sn", + "kn1vk", + "kn1vn", + "knk(k", + "knskk", + "knsvk", + "knsvn", + "knvkk", + "knvsk", + "knvsn", + "knvvk", + "knvvn", + "ko(k(", + "ko(kf", + "kok(k", + "ks)", + "ks,1,", + "ks,1c", + "ks,1k", + "ks,f(", + "ks,v,", + "ks,vc", + "ks,vk", + "ksf(1", + "ksf(v", + "ksk(1", + "ksk(k", + "ksk(v", + "kso(s", + "kso(v", + "kv)", + "kv,1,", + "kv,1c", + "kv,1k", + "kv,f(", + "kv,s,", + "kv,sc", + "kv,sk", + "kv,v,", + "kv,vc", + "kv,vk", + "kvf(1", + "kvf(s", + "kvf(v", + "kvk(1", + "kvk(k", + "kvk(s", + "kvk(v", + "kvo(s", + "kvo(v", + "n&(1)", + "n&(1,", + "n&(k1", + "n&(ks", + "n&(kv", + "n&(o1", + "n&(os", + "n&(ov", + "n&(s)", + "n&(s,", + "n&(v)", + "n&(v,", + "n&1Bf", + "n&1f(", + "n&1o(", + "n&1o1", + "n&1of", + "n&1oo", + "n&1os", + "n&1ov", + "n&f(1", + "n&f(f", + "n&f(s", + "n&f(v", + "n&k(1", + "n&k(s", + "n&k(v", + "n&o1o", + "n&oso", + "n&ovo", + "n&sf(", + "n&so(", + "n&so1", + "n&sof", + "n&soo", + "n&sov", + "n&vf(", + "n&vo(", + "n&vo1", + "n&vof", + "n&voo", + "n&vos", + "n&vov", + "n)&(k", + "n)&1f", + "n)&1o", + "n)&f(", + "n)&sf", + "n)&so", + "n)&vf", + "n)&vo", + "n))&(", + "n))&1", + "n))&f", + "n))&s", + "n))&v", + "n)))&", + "n)));", + "n)))k", + "n)))o", + "n));k", + "n))kk", + "n))o(", + "n))o1", + "n))of", + "n))ok", + "n))os", + "n))ov", + "n);k&", + "n);k(", + "n);kf", + "n);kk", + "n);kn", + "n);ko", + "n)k1o", + "n)kks", + "n)kkv", + "n)kso", + "n)kvo", + "n)o(k", + "n)o1&", + "n)o1f", + "n)o1o", + "n)of(", + "n)ok(", + "n)os&", + "n)osf", + "n)oso", + "n)ov&", + "n)ovf", + "n)ovo", + "n,(f(", + "n,(k(", + "n,(k1", + "n,(kf", + "n,(ks", + "n,(kv", + "n,f(1", + "n,f(s", + "n,f(v", + "n:o1U", + "n:osU", + "n:ovU", + "n;k&k", + "n;k((", + "n;k(1", + "n;k(s", + "n;k(v", + "n;kf(", + "n;kks", + "n;kkv", + "n;kn(", + "n;ko(", + "n;kok", + "nUk(k", + "nUk1,", + "nUkf(", + "nUkn,", + "nUks,", + "nUkv,", + "nUnk(", + "nk1Uk", + "nk1o1", + "nkf(1", + "nkf(s", + "nkf(v", + "nkksc", + "nkkvc", + "nksUk", + "nkvUk", + "nnn)U", + "nno1U", + "nnosU", + "nnovU", + "no(k1", + "no(ks", + "no(kv", + "no(o1", + "no(os", + "no(ov", + "no1&1", + "no1&s", + "no1&v", + "no1Uk", + "no1f(", + "no1o(", + "no1of", + "no1oo", + "no1os", + "no1ov", + "nof(1", + "nof(s", + "nof(v", + "nok(f", + "nok(k", + "nok(s", + "nok(v", + "nono1", + "nos&1", + "nos&v", + "nosUk", + "nosf(", + "noso(", + "noso1", + "nosof", + "nosoo", + "nosov", + "nov&1", + "nov&s", + "nov&v", + "novUk", + "novf(", + "novo(", + "novo1", + "novof", + "novoo", + "novos", + "novov", + "o1kf(", + "oUk1,", + "oUks,", + "oUkv,", + "of()o", + "of(1)", + "of(s)", + "of(v)", + "ok1o1", + "ok1os", + "ok1ov", + "okkkn", + "okso1", + "oksov", + "okvo1", + "okvos", + "okvov", + "ook1,", + "ooks,", + "ookv,", + "oskf(", + "ovkf(", + "s&((f", + "s&((k", + "s&(1)", + "s&(1,", + "s&(1o", + "s&(f(", + "s&(k(", + "s&(k)", + "s&(k1", + "s&(kf", + "s&(kk", + "s&(kn", + "s&(ko", + "s&(ks", + "s&(kv", + "s&(s)", + "s&(s,", + "s&(so", + "s&(v)", + "s&(v,", + "s&(vo", + "s&1", + "s&1Bf", + "s&1Uk", + "s&1c", + "s&1f(", + "s&1o(", + "s&1o1", + "s&1of", + "s&1ok", + "s&1on", + "s&1oo", + "s&1os", + "s&1ov", + "s&f((", + "s&f()", + "s&f(1", + "s&f(f", + "s&f(k", + "s&f(n", + "s&f(s", + "s&f(v", + "s&k&s", + "s&k&v", + "s&k(1", + "s&k(f", + "s&k(o", + "s&k(s", + "s&k(v", + "s&k1k", + "s&k1o", + "s&kUk", + "s&kc", + "s&kk1", + "s&kkv", + "s&knk", + "s&ko(", + "s&ko1", + "s&kok", + "s&kos", + "s&kov", + "s&kso", + "s&kvk", + "s&kvo", + "s&n&s", + "s&n&v", + "s&n()", + "s&no1", + "s&nos", + "s&nov", + "s&o(1", + "s&o(k", + "s&o(s", + "s&o(v", + "s&o1o", + "s&okc", + "s&oko", + "s&os", + "s&oso", + "s&ov", + "s&ovo", + "s&s", + "s&s:o", + "s&sBf", + "s&sU(", + "s&sUk", + "s&sc", + "s&sf(", + "s&so(", + "s&so1", + "s&sof", + "s&son", + "s&soo", + "s&sos", + "s&sov", + "s&sso", + "s&svo", + "s&v:o", + "s&vBf", + "s&vU(", + "s&vUk", + "s&vc", + "s&vf(", + "s&vo(", + "s&vo1", + "s&vof", + "s&vok", + "s&von", + "s&voo", + "s&vos", + "s&vov", + "s&vso", + "s&vvo", + "s)&(1", + "s)&(f", + "s)&(k", + "s)&(n", + "s)&(s", + "s)&(v", + "s)&1B", + "s)&1U", + "s)&1f", + "s)&1o", + "s)&f(", + "s)&o(", + "s)&sB", + "s)&sf", + "s)&so", + "s)&vB", + "s)&vU", + "s)&vf", + "s)&vo", + "s)()s", + "s)()v", + "s))&(", + "s))&1", + "s))&f", + "s))&n", + "s))&o", + "s))&s", + "s))&v", + "s)))&", + "s))))", + "s)));", + "s)))B", + "s)))U", + "s)))k", + "s)))o", + "s));k", + "s))B1", + "s))Bs", + "s))Bv", + "s))Uk", + "s))Un", + "s))k1", + "s))kk", + "s))ks", + "s))kv", + "s))o(", + "s))o1", + "s))of", + "s))ok", + "s))on", + "s))os", + "s))ov", + "s),(1", + "s),(s", + "s),(v", + "s);k&", + "s);k(", + "s);kf", + "s);kk", + "s);kn", + "s);ko", + "s)B1", + "s)B1&", + "s)B1c", + "s)B1o", + "s)Bs", + "s)Bs&", + "s)Bsc", + "s)Bso", + "s)Bv", + "s)Bv&", + "s)Bvc", + "s)Bvo", + "s)U(k", + "s)Uk(", + "s)Uk1", + "s)Ukf", + "s)Ukk", + "s)Ukn", + "s)Uko", + "s)Uks", + "s)Ukv", + "s)Unk", + "s)k1", + "s)k1c", + "s)k1o", + "s)kks", + "s)kkv", + "s)ks", + "s)ksc", + "s)kso", + "s)kv", + "s)kvc", + "s)kvo", + "s)o(1", + "s)o(k", + "s)o(n", + "s)o(s", + "s)o(v", + "s)o1B", + "s)o1f", + "s)o1k", + "s)o1o", + "s)of(", + "s)ok(", + "s)ok1", + "s)oks", + "s)okv", + "s)on&", + "s)os)", + "s)osB", + "s)osU", + "s)osf", + "s)osk", + "s)oso", + "s)ov)", + "s)ovB", + "s)ovf", + "s)ovk", + "s)ovo", + "s,(f(", + "s,(k(", + "s,(k1", + "s,(kf", + "s,(kv", + "s,1),", + "s,1)o", + "s,1B1", + "s,1Bv", + "s,1Uk", + "s,f(1", + "s,f(v", + "s,s),", + "s,v),", + "s,v)o", + "s,vB1", + "s,vBv", + "s,vUk", + "s:o1)", + "s:ov)", + "s;k&k", + "s;k((", + "s;k(1", + "s;k(o", + "s;k(s", + "s;k(v", + "s;k1,", + "s;k1o", + "s;k;", + "s;k[k", + "s;k[n", + "s;kf(", + "s;kkn", + "s;kks", + "s;kkv", + "s;kn(", + "s;kn,", + "s;knc", + "s;knk", + "s;knn", + "s;ko(", + "s;kok", + "s;ks,", + "s;ksc", + "s;ksk", + "s;kso", + "s;kv,", + "s;kvc", + "s;kvk", + "s;kvo", + "s;n:k", + "sB1", + "sB1&s", + "sB1&v", + "sB1,1", + "sB1,n", + "sB1,v", + "sB1Uk", + "sB1c", + "sB1k1", + "sB1ks", + "sB1kv", + "sB1os", + "sB1ov", + "sBf(1", + "sBf(f", + "sBf(v", + "sBk(1", + "sBk(v", + "sBn,n", + "sBnk1", + "sBnkv", + "sBs", + "sBs&s", + "sBs&v", + "sBsUk", + "sBsc", + "sBsos", + "sBsov", + "sBv", + "sBv&s", + "sBv&v", + "sBv,1", + "sBv,n", + "sBv,v", + "sBvUk", + "sBvc", + "sBvk1", + "sBvks", + "sBvkv", + "sBvos", + "sBvov", + "sU((k", + "sU(k(", + "sU(k1", + "sU(kf", + "sU(kk", + "sU(kn", + "sU(ks", + "sU(kv", + "sU1,1", + "sU1,v", + "sUc", + "sUk", + "sUk(1", + "sUk(k", + "sUk(n", + "sUk(v", + "sUk1", + "sUk1&", + "sUk1,", + "sUk1c", + "sUk1f", + "sUk1k", + "sUk1n", + "sUk1o", + "sUkf", + "sUkf(", + "sUkf,", + "sUkk(", + "sUkk,", + "sUkk1", + "sUkkk", + "sUkkn", + "sUkks", + "sUkkv", + "sUkn&", + "sUkn(", + "sUkn,", + "sUkn1", + "sUknc", + "sUknk", + "sUkno", + "sUkns", + "sUknv", + "sUko1", + "sUkok", + "sUkov", + "sUks", + "sUks&", + "sUks,", + "sUksc", + "sUksk", + "sUkso", + "sUkv", + "sUkv&", + "sUkv,", + "sUkvc", + "sUkvf", + "sUkvk", + "sUkvn", + "sUkvo", + "sUn(k", + "sUn,1", + "sUn,v", + "sUn1,", + "sUnk(", + "sUnk1", + "sUnkf", + "sUnks", + "sUnkv", + "sUno1", + "sUnos", + "sUnov", + "sUnv,", + "sUon1", + "sUonv", + "sUv,1", + "sUv,v", + "sc", + "sf()k", + "sf(1)", + "sf(n,", + "sf(s)", + "sf(v)", + "sk)&(", + "sk)&1", + "sk)&f", + "sk)&s", + "sk)&v", + "sk);k", + "sk)B1", + "sk)Bs", + "sk)Bv", + "sk)Uk", + "sk)Un", + "sk)k1", + "sk)kk", + "sk)ks", + "sk)kv", + "sk)o(", + "sk)o1", + "sk)of", + "sk)ok", + "sk)os", + "sk)ov", + "sk1&1", + "sk1&s", + "sk1&v", + "sk1U(", + "sk1Uk", + "sk1c", + "sk1o1", + "sk1os", + "sk1ov", + "skU1,", + "skUs,", + "skUv,", + "skf(1", + "skf(v", + "skk(1", + "skk(v", + "skks", + "skksc", + "skkv", + "skkvc", + "sknkn", + "sks&1", + "sks&v", + "sksUk", + "sksc", + "skso1", + "sksos", + "sksov", + "skv&1", + "skv&s", + "skv&v", + "skvU(", + "skvUk", + "skvc", + "skvo1", + "skvos", + "skvov", + "sn&f(", + "sn,f(", + "snUk1", + "snUkn", + "snUkv", + "snk1c", + "snkf(", + "snkvc", + "sno(s", + "sno1U", + "snosU", + "snovU", + "so(((", + "so((1", + "so((f", + "so((k", + "so((s", + "so((v", + "so(1)", + "so(1o", + "so(f(", + "so(k(", + "so(k)", + "so(k1", + "so(kf", + "so(kk", + "so(kn", + "so(ko", + "so(ks", + "so(kv", + "so(n)", + "so(o1", + "so(os", + "so(ov", + "so(s)", + "so(so", + "so(v)", + "so(vo", + "so1&1", + "so1&o", + "so1&s", + "so1&v", + "so1)&", + "so1)o", + "so1Bf", + "so1Uk", + "so1c", + "so1f(", + "so1kf", + "so1o(", + "so1o1", + "so1of", + "so1ok", + "so1oo", + "so1os", + "so1ov", + "sof()", + "sof(1", + "sof(f", + "sof(k", + "sof(n", + "sof(s", + "sof(v", + "sok&s", + "sok&v", + "sok(1", + "sok(k", + "sok(o", + "sok(s", + "sok(v", + "sok1", + "sok1,", + "sok1c", + "sok1k", + "sok1o", + "sokUk", + "sokc", + "sokf(", + "sokn,", + "soknk", + "soko(", + "soko1", + "sokok", + "sokos", + "sokov", + "soks", + "soks,", + "soksc", + "sokso", + "sokv", + "sokv,", + "sokvc", + "sokvk", + "sokvo", + "sonk1", + "sonks", + "sonkv", + "sonos", + "sonov", + "sos", + "sos&(", + "sos&1", + "sos&o", + "sos&s", + "sos&v", + "sos:o", + "sosBf", + "sosUk", + "sosc", + "sosf(", + "soskf", + "soso(", + "soso1", + "sosof", + "sosok", + "sosoo", + "sosos", + "sosov", + "sosso", + "sosvo", + "sov", + "sov&(", + "sov&1", + "sov&o", + "sov&s", + "sov&v", + "sov)&", + "sov)o", + "sov:o", + "sovBf", + "sovUk", + "sovc", + "sovf(", + "sovkf", + "sovo(", + "sovo1", + "sovof", + "sovok", + "sovoo", + "sovos", + "sovov", + "sovso", + "sovvo", + "v&((f", + "v&((k", + "v&(1)", + "v&(1,", + "v&(1o", + "v&(f(", + "v&(k(", + "v&(k)", + "v&(k1", + "v&(kf", + "v&(kk", + "v&(kn", + "v&(ko", + "v&(ks", + "v&(kv", + "v&(s)", + "v&(s,", + "v&(so", + "v&(v)", + "v&(v,", + "v&(vo", + "v&1Bf", + "v&1Uk", + "v&1c", + "v&1f(", + "v&1o(", + "v&1o1", + "v&1of", + "v&1ok", + "v&1on", + "v&1oo", + "v&1os", + "v&1ov", + "v&f((", + "v&f()", + "v&f(1", + "v&f(f", + "v&f(k", + "v&f(n", + "v&f(s", + "v&f(v", + "v&k&s", + "v&k&v", + "v&k(1", + "v&k(f", + "v&k(o", + "v&k(s", + "v&k(v", + "v&k1k", + "v&k1o", + "v&kUk", + "v&kc", + "v&kk1", + "v&kks", + "v&kkv", + "v&knk", + "v&ko(", + "v&ko1", + "v&kok", + "v&kos", + "v&kov", + "v&ksk", + "v&kso", + "v&kvk", + "v&kvo", + "v&n&s", + "v&n&v", + "v&n()", + "v&no1", + "v&nos", + "v&nov", + "v&o(1", + "v&o(k", + "v&o(s", + "v&o(v", + "v&o1o", + "v&okc", + "v&oko", + "v&os", + "v&oso", + "v&ov", + "v&ovo", + "v&s:o", + "v&sBf", + "v&sU(", + "v&sUk", + "v&sc", + "v&sf(", + "v&so(", + "v&so1", + "v&sof", + "v&sok", + "v&son", + "v&soo", + "v&sos", + "v&sov", + "v&sso", + "v&svo", + "v&v:o", + "v&vBf", + "v&vU(", + "v&vUk", + "v&vc", + "v&vf(", + "v&vo(", + "v&vo1", + "v&vof", + "v&vok", + "v&von", + "v&voo", + "v&vos", + "v&vov", + "v&vso", + "v&vvo", + "v)&(1", + "v)&(f", + "v)&(k", + "v)&(n", + "v)&(s", + "v)&(v", + "v)&1B", + "v)&1U", + "v)&1f", + "v)&1o", + "v)&f(", + "v)&o(", + "v)&sB", + "v)&sU", + "v)&sf", + "v)&so", + "v)&vB", + "v)&vU", + "v)&vf", + "v)&vo", + "v)()s", + "v)()v", + "v))&(", + "v))&1", + "v))&f", + "v))&n", + "v))&o", + "v))&s", + "v))&v", + "v)))&", + "v))))", + "v)));", + "v)))B", + "v)))U", + "v)))k", + "v)))o", + "v));k", + "v))B1", + "v))Bs", + "v))Bv", + "v))Uk", + "v))Un", + "v))k1", + "v))kk", + "v))ks", + "v))kv", + "v))o(", + "v))o1", + "v))of", + "v))ok", + "v))on", + "v))os", + "v))ov", + "v),(1", + "v),(s", + "v),(v", + "v);k&", + "v);k(", + "v);kf", + "v);kk", + "v);kn", + "v);ko", + "v)B1", + "v)B1&", + "v)B1c", + "v)B1o", + "v)Bs", + "v)Bs&", + "v)Bsc", + "v)Bso", + "v)Bv", + "v)Bv&", + "v)Bvc", + "v)Bvo", + "v)U(k", + "v)Uk(", + "v)Uk1", + "v)Ukf", + "v)Ukk", + "v)Ukn", + "v)Uko", + "v)Uks", + "v)Ukv", + "v)Unk", + "v)k1", + "v)k1c", + "v)k1o", + "v)kks", + "v)kkv", + "v)ks", + "v)ksc", + "v)kso", + "v)kv", + "v)kvc", + "v)kvo", + "v)o(1", + "v)o(k", + "v)o(n", + "v)o(s", + "v)o(v", + "v)o1B", + "v)o1U", + "v)o1f", + "v)o1k", + "v)o1o", + "v)of(", + "v)ok(", + "v)ok1", + "v)oks", + "v)okv", + "v)on&", + "v)ono", + "v)os)", + "v)osB", + "v)osU", + "v)osf", + "v)osk", + "v)oso", + "v)ovB", + "v)ovU", + "v)ovf", + "v)ovk", + "v)ovo", + "v,(f(", + "v,(k(", + "v,(k1", + "v,(kf", + "v,(ks", + "v,(kv", + "v,1),", + "v,1)o", + "v,1B1", + "v,1Bs", + "v,1Bv", + "v,1Uk", + "v,f(1", + "v,f(s", + "v,f(v", + "v,s),", + "v,s)o", + "v,sB1", + "v,sBv", + "v,sUk", + "v,v),", + "v,v)o", + "v,vB1", + "v,vBs", + "v,vBv", + "v,vUk", + "v:o1)", + "v:os)", + "v:ov)", + "v;k&k", + "v;k((", + "v;k(1", + "v;k(o", + "v;k(s", + "v;k(v", + "v;k1,", + "v;k1o", + "v;k;", + "v;k[k", + "v;k[n", + "v;kf(", + "v;kkn", + "v;kks", + "v;kkv", + "v;kn(", + "v;kn,", + "v;knc", + "v;knk", + "v;knn", + "v;ko(", + "v;kok", + "v;ks,", + "v;ksc", + "v;ksk", + "v;kso", + "v;kv,", + "v;kvc", + "v;kvk", + "v;kvo", + "v;n:k", + "vB1", + "vB1&s", + "vB1&v", + "vB1,1", + "vB1,n", + "vB1,s", + "vB1,v", + "vB1Uk", + "vB1c", + "vB1k1", + "vB1ks", + "vB1kv", + "vB1os", + "vB1ov", + "vBf(1", + "vBf(f", + "vBf(s", + "vBf(v", + "vBk(1", + "vBk(s", + "vBk(v", + "vBn,n", + "vBnk1", + "vBnks", + "vBnkv", + "vBs", + "vBs&s", + "vBs&v", + "vBs,1", + "vBs,n", + "vBs,v", + "vBsUk", + "vBsc", + "vBsk1", + "vBsks", + "vBskv", + "vBsos", + "vBsov", + "vBv", + "vBv&s", + "vBv&v", + "vBv,1", + "vBv,n", + "vBv,s", + "vBv,v", + "vBvUk", + "vBvc", + "vBvk1", + "vBvks", + "vBvkv", + "vBvos", + "vBvov", + "vU((k", + "vU(k(", + "vU(k1", + "vU(kf", + "vU(kk", + "vU(kn", + "vU(ks", + "vU(kv", + "vU1,1", + "vU1,s", + "vU1,v", + "vUc", + "vUk", + "vUk(1", + "vUk(k", + "vUk(n", + "vUk(s", + "vUk(v", + "vUk1", + "vUk1&", + "vUk1,", + "vUk1c", + "vUk1f", + "vUk1k", + "vUk1n", + "vUk1o", + "vUkf", + "vUkf(", + "vUkf,", + "vUkk(", + "vUkk,", + "vUkk1", + "vUkkk", + "vUkkn", + "vUkks", + "vUkkv", + "vUkn&", + "vUkn(", + "vUkn,", + "vUkn1", + "vUknc", + "vUknk", + "vUkno", + "vUkns", + "vUknv", + "vUko1", + "vUkok", + "vUkos", + "vUkov", + "vUks", + "vUks&", + "vUks,", + "vUksc", + "vUksf", + "vUksk", + "vUksn", + "vUkso", + "vUkv", + "vUkv&", + "vUkv,", + "vUkvc", + "vUkvf", + "vUkvk", + "vUkvn", + "vUkvo", + "vUn(k", + "vUn,1", + "vUn,s", + "vUn,v", + "vUn1,", + "vUnk(", + "vUnk1", + "vUnkf", + "vUnks", + "vUnkv", + "vUno1", + "vUnos", + "vUnov", + "vUns,", + "vUnv,", + "vUon1", + "vUons", + "vUonv", + "vUs,1", + "vUs,v", + "vUv,1", + "vUv,s", + "vUv,v", + "vc", + "vf()k", + "vf(1)", + "vf(n,", + "vf(s)", + "vf(v)", + "vk)&(", + "vk)&1", + "vk)&f", + "vk)&s", + "vk)&v", + "vk);k", + "vk)B1", + "vk)Bs", + "vk)Bv", + "vk)Uk", + "vk)Un", + "vk)k1", + "vk)kk", + "vk)ks", + "vk)kv", + "vk)o(", + "vk)o1", + "vk)of", + "vk)ok", + "vk)os", + "vk)ov", + "vk1&1", + "vk1&s", + "vk1&v", + "vk1U(", + "vk1Uk", + "vk1c", + "vk1o1", + "vk1os", + "vk1ov", + "vkU1,", + "vkUs,", + "vkUv,", + "vkf(1", + "vkf(s", + "vkf(v", + "vkk(1", + "vkk(s", + "vkk(v", + "vkks", + "vkksc", + "vkkv", + "vkkvc", + "vknkn", + "vks&1", + "vks&v", + "vksU(", + "vksUk", + "vksc", + "vkso1", + "vksos", + "vksov", + "vkv&1", + "vkv&s", + "vkv&v", + "vkvU(", + "vkvUk", + "vkvc", + "vkvo1", + "vkvos", + "vkvov", + "vn&f(", + "vn,f(", + "vnUk1", + "vnUkn", + "vnUks", + "vnUkv", + "vnk1c", + "vnkf(", + "vnksc", + "vnkvc", + "vno1U", + "vnosU", + "vnovU", + "vo(((", + "vo((1", + "vo((f", + "vo((k", + "vo((s", + "vo((v", + "vo(1)", + "vo(1o", + "vo(f(", + "vo(k(", + "vo(k)", + "vo(k1", + "vo(kf", + "vo(kk", + "vo(kn", + "vo(ko", + "vo(ks", + "vo(kv", + "vo(n)", + "vo(o1", + "vo(os", + "vo(ov", + "vo(s)", + "vo(so", + "vo(v)", + "vo(vo", + "vo1&1", + "vo1&o", + "vo1&s", + "vo1&v", + "vo1)&", + "vo1)o", + "vo1Bf", + "vo1Uk", + "vo1c", + "vo1f(", + "vo1kf", + "vo1o(", + "vo1o1", + "vo1of", + "vo1ok", + "vo1oo", + "vo1os", + "vo1ov", + "vof()", + "vof(1", + "vof(f", + "vof(k", + "vof(n", + "vof(s", + "vof(v", + "vok&s", + "vok&v", + "vok(1", + "vok(k", + "vok(o", + "vok(s", + "vok(v", + "vok1", + "vok1,", + "vok1c", + "vok1k", + "vok1o", + "vokUk", + "vokc", + "vokf(", + "vokn,", + "voknk", + "voko(", + "voko1", + "vokok", + "vokos", + "vokov", + "voks", + "voks,", + "voksc", + "voksk", + "vokso", + "vokv", + "vokv,", + "vokvc", + "vokvk", + "vokvo", + "vonk1", + "vonks", + "vonkv", + "vono1", + "vonos", + "vonov", + "vos", + "vos&(", + "vos&1", + "vos&o", + "vos&s", + "vos&v", + "vos)&", + "vos)o", + "vos:o", + "vosBf", + "vosUk", + "vosc", + "vosf(", + "voskf", + "voso(", + "voso1", + "vosof", + "vosok", + "vosoo", + "vosos", + "vosov", + "vosso", + "vosvo", + "vov", + "vov&(", + "vov&1", + "vov&o", + "vov&s", + "vov&v", + "vov)&", + "vov)o", + "vov:o", + "vovBf", + "vovUk", + "vovc", + "vovf(", + "vovkf", + "vovo(", + "vovo1", + "vovof", + "vovok", + "vovoo", + "vovos", + "vovov", + "vovso", + "vovvo", +}; +static const size_t patmap_sz = 2135; + + +/* Simple binary search */ +int is_sqli_pattern(const char *key) +{ + int left = 0; + int right = (int)patmap_sz - 1; + + while (left <= right) { + int pos = (left + right) / 2; + int cmp = strcmp(patmap[pos], key); + if (cmp == 0) { + return 1; /* TRUE */ + } else if (cmp < 0) { + left = pos + 1; + } else { + right = pos - 1; + } + } + return 0; /* FALSE */ +} +#endif diff --git a/apache2/libinjection/sqlparse.c b/apache2/libinjection/sqlparse.c index 5a5899c1..ba9e6e4a 100644 --- a/apache2/libinjection/sqlparse.c +++ b/apache2/libinjection/sqlparse.c @@ -1,1838 +1,1062 @@ - - - - - - - - - ModSecurity/apache2/libinjection/sqlparse.c at da961d4c1535d2131c1733258b3f809feeabadf5 · client9/ModSecurity · GitHub - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - -
- -
- - - - - - - -
-
- -
-
-
- - - - - -

- public - - - / - ModSecurity - - forked from SpiderLabs/ModSecurity - -

-
- - - - -
- - - - - - -
- - -
- - - tree: - da961d4c15 - - -
- -
-
- Switch branches/tags - -
- -
-
- -
-
- -
-
- -
- -
- -
- - master -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
Nothing to show
-
- - -
-
- -
- - 2.7.3 -
-
- - 2.7.2 -
-
- - 2.7.1 -
-
- -
Nothing to show
- -
- -
-
-
- -
- - - -
- - - - - - - -
-
- -
- - - - - - - -
-
- - - - - - - - - -
- - - - - - - -
- - -
- -
-
- -
-
-
-
- - file - 1063 lines (941 sloc) - 29.044 kb -
-
-
- Edit - Raw - Blame - History -
-
- -
-
- - - - - -
- 1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303 -304 -305 -306 -307 -308 -309 -310 -311 -312 -313 -314 -315 -316 -317 -318 -319 -320 -321 -322 -323 -324 -325 -326 -327 -328 -329 -330 -331 -332 -333 -334 -335 -336 -337 -338 -339 -340 -341 -342 -343 -344 -345 -346 -347 -348 -349 -350 -351 -352 -353 -354 -355 -356 -357 -358 -359 -360 -361 -362 -363 -364 -365 -366 -367 -368 -369 -370 -371 -372 -373 -374 -375 -376 -377 -378 -379 -380 -381 -382 -383 -384 -385 -386 -387 -388 -389 -390 -391 -392 -393 -394 -395 -396 -397 -398 -399 -400 -401 -402 -403 -404 -405 -406 -407 -408 -409 -410 -411 -412 -413 -414 -415 -416 -417 -418 -419 -420 -421 -422 -423 -424 -425 -426 -427 -428 -429 -430 -431 -432 -433 -434 -435 -436 -437 -438 -439 -440 -441 -442 -443 -444 -445 -446 -447 -448 -449 -450 -451 -452 -453 -454 -455 -456 -457 -458 -459 -460 -461 -462 -463 -464 -465 -466 -467 -468 -469 -470 -471 -472 -473 -474 -475 -476 -477 -478 -479 -480 -481 -482 -483 -484 -485 -486 -487 -488 -489 -490 -491 -492 -493 -494 -495 -496 -497 -498 -499 -500 -501 -502 -503 -504 -505 -506 -507 -508 -509 -510 -511 -512 -513 -514 -515 -516 -517 -518 -519 -520 -521 -522 -523 -524 -525 -526 -527 -528 -529 -530 -531 -532 -533 -534 -535 -536 -537 -538 -539 -540 -541 -542 -543 -544 -545 -546 -547 -548 -549 -550 -551 -552 -553 -554 -555 -556 -557 -558 -559 -560 -561 -562 -563 -564 -565 -566 -567 -568 -569 -570 -571 -572 -573 -574 -575 -576 -577 -578 -579 -580 -581 -582 -583 -584 -585 -586 -587 -588 -589 -590 -591 -592 -593 -594 -595 -596 -597 -598 -599 -600 -601 -602 -603 -604 -605 -606 -607 -608 -609 -610 -611 -612 -613 -614 -615 -616 -617 -618 -619 -620 -621 -622 -623 -624 -625 -626 -627 -628 -629 -630 -631 -632 -633 -634 -635 -636 -637 -638 -639 -640 -641 -642 -643 -644 -645 -646 -647 -648 -649 -650 -651 -652 -653 -654 -655 -656 -657 -658 -659 -660 -661 -662 -663 -664 -665 -666 -667 -668 -669 -670 -671 -672 -673 -674 -675 -676 -677 -678 -679 -680 -681 -682 -683 -684 -685 -686 -687 -688 -689 -690 -691 -692 -693 -694 -695 -696 -697 -698 -699 -700 -701 -702 -703 -704 -705 -706 -707 -708 -709 -710 -711 -712 -713 -714 -715 -716 -717 -718 -719 -720 -721 -722 -723 -724 -725 -726 -727 -728 -729 -730 -731 -732 -733 -734 -735 -736 -737 -738 -739 -740 -741 -742 -743 -744 -745 -746 -747 -748 -749 -750 -751 -752 -753 -754 -755 -756 -757 -758 -759 -760 -761 -762 -763 -764 -765 -766 -767 -768 -769 -770 -771 -772 -773 -774 -775 -776 -777 -778 -779 -780 -781 -782 -783 -784 -785 -786 -787 -788 -789 -790 -791 -792 -793 -794 -795 -796 -797 -798 -799 -800 -801 -802 -803 -804 -805 -806 -807 -808 -809 -810 -811 -812 -813 -814 -815 -816 -817 -818 -819 -820 -821 -822 -823 -824 -825 -826 -827 -828 -829 -830 -831 -832 -833 -834 -835 -836 -837 -838 -839 -840 -841 -842 -843 -844 -845 -846 -847 -848 -849 -850 -851 -852 -853 -854 -855 -856 -857 -858 -859 -860 -861 -862 -863 -864 -865 -866 -867 -868 -869 -870 -871 -872 -873 -874 -875 -876 -877 -878 -879 -880 -881 -882 -883 -884 -885 -886 -887 -888 -889 -890 -891 -892 -893 -894 -895 -896 -897 -898 -899 -900 -901 -902 -903 -904 -905 -906 -907 -908 -909 -910 -911 -912 -913 -914 -915 -916 -917 -918 -919 -920 -921 -922 -923 -924 -925 -926 -927 -928 -929 -930 -931 -932 -933 -934 -935 -936 -937 -938 -939 -940 -941 -942 -943 -944 -945 -946 -947 -948 -949 -950 -951 -952 -953 -954 -955 -956 -957 -958 -959 -960 -961 -962 -963 -964 -965 -966 -967 -968 -969 -970 -971 -972 -973 -974 -975 -976 -977 -978 -979 -980 -981 -982 -983 -984 -985 -986 -987 -988 -989 -990 -991 -992 -993 -994 -995 -996 -997 -998 -999 -1000 -1001 -1002 -1003 -1004 -1005 -1006 -1007 -1008 -1009 -1010 -1011 -1012 -1013 -1014 -1015 -1016 -1017 -1018 -1019 -1020 -1021 -1022 -1023 -1024 -1025 -1026 -1027 -1028 -1029 -1030 -1031 -1032 -1033 -1034 -1035 -1036 -1037 -1038 -1039 -1040 -1041 -1042 -1043 -1044 -1045 -1046 -1047 -1048 -1049 -1050 -1051 -1052 -1053 -1054 -1055 -1056 -1057 -1058 -1059 -1060 -1061 -1062 - - -
/**
* Copyright 2012,2013 Nick Galbreath
* nickg@client9.com
* BSD License -- see COPYING.txt for details
*
* (setq-default indent-tabs-mode nil)
* (setq c-default-style "k&r"
* c-basic-offset 4)
* indent -kr -nut
*/

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <assert.h>

#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif

#if 0
#define FOLD_DEBUG printf("%d: Fold state = %d, current=%c, last=%c\n", __LINE__, sf->fold_state, current->type, last->type == CHAR_NULL ? '~': last->type)
#else
#define FOLD_DEBUG
#endif

// order is important here
#include "sqlparse_private.h"
#include "sqlparse_data.h"

// memmem is a linux function
// may not exist in Windows, and doesn't exist
// in Mac OS X < 10.8 and FreeBSD < 6.0
// Define our own. Modified to use 'const char*'
// instead of (void *)
//

/*-
* Copyright (c) 2005 Pascal Gloor <pascal.gloor@spale.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
const char *
my_memmem(const char *cl, size_t l_len, const char *cs, size_t s_len)
{
    register const char *cur, *last;

    /* we need something to compare */
    if (l_len == 0 || s_len == 0)
        return NULL;

    /* "s" must be smaller or equal to "l" */
    if (l_len < s_len)
        return NULL;

    /* special case where s_len == 1 */
    if (s_len == 1)
        return (const char*) memchr(cl, (int)*cs, l_len);

    /* the last position where its possible to find "s" in "l" */
    last = cl + l_len - s_len;

    for (cur = cl; cur <= last; cur++)
        if (cur[0] == cs[0] && memcmp(cur, cs, s_len) == 0)
            return cur;

    return NULL;
}


size_t strlenspn(const char *s, size_t len, const char *accept)
{
    size_t i;
    for (i = 0; i < len; ++i) {
        /* likely we can do better by inlining this function
* but this works for now
*/
        if (strchr(accept, s[i]) == NULL) {
            return i;
        }
    }
    return len;
}

/*
* ASCII case insenstive compare only!
*/
int cstrcasecmp(const char *a, const char *b)
{
    int ca, cb;

    do {
        ca = *a++ & 0xff;
        cb = *b++ & 0xff;
        if (ca >= 'a' && ca <= 'z')
            ca -= 0x20;
        if (cb >= 'a' && cb <= 'z')
            cb -= 0x20;
    } while (ca == cb && ca != '\0');

    return ca - cb;
}

int streq(const char *a, const char *b)
{
    return cstrcasecmp(a, b) == 0;
}

void st_clear(stoken_t * st)
{
    st->type = CHAR_NULL;
    st->str_open = CHAR_NULL;
    st->str_close = CHAR_NULL;
    st->val[0] = CHAR_NULL;
}

int st_is_empty(const stoken_t * st)
{
    return st->type == CHAR_NULL;
}

void st_assign_char(stoken_t * st, const char stype, const char value)
{
    st->type = stype;
    st->val[0] = value;
    st->val[1] = CHAR_NULL;
}

void st_assign(stoken_t * st, const char stype, const char *value,
               size_t len)
{
    size_t last = len < (ST_MAX_SIZE - 1) ? len : (ST_MAX_SIZE - 1);
    st->type = stype;
    strncpy(st->val, value, last);
    st->val[last] = CHAR_NULL;
}

void st_assign_cstr(stoken_t * st, const char stype, const char *value)
{
    st->type = stype;
    strncpy(st->val, value, ST_MAX_SIZE - 1);
    st->val[ST_MAX_SIZE - 1] = CHAR_NULL;
}

int st_equals_cstr(const stoken_t * st, const char stype,
                    const char *value)
{
    return st->type == stype && !cstrcasecmp(value, st->val);
}

void st_copy(stoken_t * dest, const stoken_t * src)
{
    memcpy(dest, src, sizeof(stoken_t));
}

const char *bsearch_cstrcase(const char *key, const char *base[], size_t nmemb)
{
    int left = 0;
    int right = (int) nmemb - 1;

    while (left <= right) {
        int pos = (left + right) / 2;
        int cmp = cstrcasecmp(base[pos], key);
        if (cmp == 0) {
            return base[pos];
        } else if (cmp < 0) {
            left = pos + 1;
        } else {
            right = pos - 1;
        }
    }
    return NULL;
}

const char *bsearch_cstr(const char *key, const char *base[], size_t nmemb)
{
    int left = 0;
    int right = (int) nmemb - 1;

    while (left <= right) {
        int pos = (left + right) / 2;
        int cmp = strcmp(base[pos], key);
        if (cmp == 0) {
            return base[pos];
        } else if (cmp < 0) {
            left = pos + 1;
        } else {
            right = pos - 1;
        }
    }
    return NULL;
}

char bsearch_keyword_type(const char *key, const keyword_t * keywords,
                          size_t numb)
{
    int left = 0;
    int right = (int) numb - 1;

    while (left <= right) {
        int pos = (left + right) / 2;
        int cmp = cstrcasecmp(keywords[pos].word, key);
        if (cmp == 0) {
            return keywords[pos].type;
        } else if (cmp < 0) {
            left = pos + 1;
        } else {
            right = pos - 1;
        }
    }
    return CHAR_NULL;
}

int is_operator2(const char *key)
{
    return bsearch_cstrcase(key, operators2, operators2_sz) != NULL;
}

int st_is_multiword_start(const stoken_t * st)
{
    return bsearch_cstrcase(st->val,
                        multikeywords_start,
                        multikeywords_start_sz) != NULL;
}

int st_is_unary_op(const stoken_t * st)
{
    return (st->type == 'o' && !(strcmp(st->val, "+") &&
                                 strcmp(st->val, "-") &&
                                 strcmp(st->val, "!") &&
                                 strcmp(st->val, "!!") &&
                                 cstrcasecmp(st->val, "NOT") &&
                                 strcmp(st->val, "~")));
}

int st_is_arith_op(const stoken_t * st)
{
    return (st->type == 'o' && !(strcmp(st->val, "-") &&
                                 strcmp(st->val, "+") &&
                                 strcmp(st->val, "~") &&
                                 strcmp(st->val, "!") &&
                                 strcmp(st->val, "/") &&
                                 strcmp(st->val, "%") &&
                                 strcmp(st->val, "*") &&
                                 strcmp(st->val, "|") &&
                                 strcmp(st->val, "&") &&
                                 cstrcasecmp(st->val, "MOD") &&
                                 cstrcasecmp(st->val, "DIV")));
}

size_t parse_white(sfilter * sf)
{
    return sf->pos + 1;
}

size_t parse_operator1(sfilter * sf)
{
    stoken_t *current = &sf->syntax_current;
    const char *cs = sf->s;
    size_t pos = sf->pos;

    st_assign_char(current, 'o', cs[pos]);
    return pos + 1;
}

size_t parse_other(sfilter * sf)
{
    stoken_t *current = &sf->syntax_current;
    const char *cs = sf->s;
    size_t pos = sf->pos;

    st_assign_char(current, '?', cs[pos]);
    return pos + 1;
}

size_t parse_char(sfilter * sf)
{
    stoken_t *current = &sf->syntax_current;
    const char *cs = sf->s;
    size_t pos = sf->pos;

    st_assign_char(current, cs[pos], cs[pos]);
    return pos + 1;
}

size_t parse_eol_comment(sfilter * sf)
{
    stoken_t *current = &sf->syntax_current;
    const char *cs = sf->s;
    const size_t slen = sf->slen;
    size_t pos = sf->pos;

    const char *endpos =
        (const char *) memchr((const void *) (cs + pos), '\n', slen - pos);
    if (endpos == NULL) {
        st_assign_cstr(current, 'c', cs + pos);
        return slen;
    } else {
        st_assign(current, 'c', cs + pos, endpos - cs - pos);
        return (endpos - cs) + 1;
    }
}

size_t parse_dash(sfilter * sf)
{
    stoken_t *current = &sf->syntax_current;
    const char *cs = sf->s;
    const size_t slen = sf->slen;
    size_t pos = sf->pos;


    size_t pos1 = pos + 1;
    if (pos1 < slen && cs[pos1] == '-') {
        return parse_eol_comment(sf);
    } else {
        st_assign_char(current, 'o', '-');
        return pos1;
    }
}

size_t is_mysql_comment(const char *cs, const size_t len, size_t pos)
{
    size_t i;

    if (pos + 2 >= len) {
        return 0;
    }
    if (cs[pos + 2] != '!') {
        return 0;
    }
    // this is a mysql comment
    // got "/*!"
    if (pos + 3 >= len) {
        return 3;
    }

    if (!isdigit(cs[pos + 3])) {
        return 3;
    }
    // handle odd case of /*!0SELECT
    if (!isdigit(cs[pos + 4])) {
        return 4;
    }

    if (pos + 7 >= len) {
        return 4;
    }

    for (i = pos + 5; i <= pos + 7; ++i) {
        if (!isdigit(cs[i])) {
            return 3;
        }
    }
    return 8;
}

size_t parse_slash(sfilter * sf)
{
    stoken_t *current = &sf->syntax_current;
    const char *cs = sf->s;
    const size_t slen = sf->slen;
    size_t pos = sf->pos;
    const char* cur = cs + pos;

    size_t pos1 = pos + 1;
    if (pos1 == slen || cs[pos1] != '*') {
        return parse_operator1(sf);
    }

    size_t inc = is_mysql_comment(cs, slen, pos);
    if (inc == 0) {

        // skip over initial '/*'
        const char *ptr =
            (const char *) my_memmem(cur + 2, slen - (pos + 2), "*/", 2);
        if (ptr == NULL) {
            // unterminated comment
            st_assign_cstr(current, 'c', cs + pos);
            return slen;
        } else {
            // postgresql allows nested comments which makes
            // this is incompatible with parsing so
            // if we find a '/*' inside the coment, then
            // make a new token.
            char ctype = 'c';
            const size_t clen = (ptr + 2) - (cur);
            if (my_memmem(cur + 2, ptr - (cur + 2), "/*", 2) !=
                NULL) {
                ctype = 'X';
            }
            st_assign(current, ctype, cs + pos, clen);

            return pos + clen;
        }
    } else {
        // MySQL Comment
        sf->in_comment = TRUE;
        st_clear(current);
        return pos + inc;
    }
}

size_t parse_backslash(sfilter * sf)
{
    stoken_t *current = &sf->syntax_current;
    const char *cs = sf->s;
    const size_t slen = sf->slen;
    size_t pos = sf->pos;

    if (pos + 1 < slen && cs[pos + 1] == 'N') {
        st_assign_cstr(current, '1', "NULL");
        return pos + 2;
    } else {
        return parse_other(sf);
    }
}

size_t parse_operator2(sfilter * sf)
{
    stoken_t *current = &sf->syntax_current;
    const char *cs = sf->s;
    const size_t slen = sf->slen;
    size_t pos = sf->pos;

    if (pos + 1 >= slen) {
        return parse_operator1(sf);
    }
    char op2[3] = { cs[pos], cs[pos + 1], CHAR_NULL };

    // Special Hack for MYSQL style comments
    // instead of turning:
    // /*! FOO */ into FOO by rewriting the string, we
    // turn it into FOO */ and ignore the ending comment
    if (sf->in_comment && op2[0] == '*' && op2[1] == '/') {
        sf->in_comment = FALSE;
        st_clear(current);
        return pos + 2;
    } else if (pos + 2 < slen && op2[0] == '<' && op2[1] == '='
               && cs[pos + 2] == '>') {
        // special 3-char operator

        st_assign_cstr(current, 'o', "<=>");
        return pos + 3;
    } else if (is_operator2(op2)) {
        if (streq(op2, "&&") || streq(op2, "||")) {
            st_assign_cstr(current, '&', op2);
        } else {
            // normal 2 char operator
            st_assign_cstr(current, 'o', op2);
        }
        return pos + 2;
    } else {
        // must be a single char operator
        return parse_operator1(sf);
    }
}

size_t parse_string_core(const char *cs, const size_t len, size_t pos,
                         stoken_t * st, char delim, size_t offset)
{
    // offset is to skip the perhaps first quote char
    const char *qpos =
        (const char *) memchr((const void *) (cs + pos + offset), delim,
                              len - pos - offset);

    // then keep string open/close info
    if (offset == 1) {
        // this is real quote
        st->str_open = delim;
    } else {
        // this was a simulated quote
        st->str_open = CHAR_NULL;
    }

    while (TRUE) {
        if (qpos == NULL) {
            // string ended with no trailing quote
            // assign what we have
            st_assign_cstr(st, 's', cs + pos + offset);
            st->str_close = CHAR_NULL;
            return len;
        } else if (*(qpos - 1) != '\\') {
            // ending quote is not escaped.. copy and end
            st_assign(st, 's', cs + pos + offset,
                      qpos - (cs + pos + offset));
            st->str_close = delim;
            return qpos - cs + 1;
        } else {
            qpos =
                (const char *) memchr((const void *) (qpos + 1), delim,
                                      (cs + len) - (qpos + 1));
        }
    }
}

/**
* Used when first char is a ' or "
*/
size_t parse_string(sfilter * sf)
{
    stoken_t *current = &sf->syntax_current;
    const char *cs = sf->s;
    const size_t slen = sf->slen;
    size_t pos = sf->pos;

    // assert cs[pos] == single or double quote
    return parse_string_core(cs, slen, pos, current, cs[pos], 1);
}

size_t parse_word(sfilter * sf)
{
    stoken_t *current = &sf->syntax_current;
    const char *cs = sf->s;
    size_t pos = sf->pos;

    size_t slen =
        strlenspn(cs + pos, sf->slen - pos,
                  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.$");

    st_assign(current, 'n', cs + pos, slen);
    if (slen < ST_MAX_SIZE) {
        char ch = bsearch_keyword_type(current->val, sql_keywords,
                                       sql_keywords_sz);
        if (ch == CHAR_NULL) {
            ch = 'n';
        }
        current->type = ch;
    }
    return pos + slen;
}

size_t parse_var(sfilter * sf)
{
    stoken_t *current = &sf->syntax_current;
    const char *cs = sf->s;
    const size_t slen = sf->slen;
    size_t pos = sf->pos;

    size_t pos1 = pos + 1;

    // move past optional other '@'
    if (pos1 < slen && cs[pos1] == '@') {
        pos1 += 1;
    }

    size_t xlen =
        strlenspn(cs + pos1, slen - pos1,
                  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.$");
    if (xlen == 0) {
        st_assign(current, 'v', cs + pos, (pos1 - pos));
        return pos1;
    } else {
        st_assign(current, 'v', cs + pos, xlen + (pos1 - pos));
        return pos1 + xlen;
    }
}

size_t parse_number(sfilter * sf)
{
    stoken_t *current = &sf->syntax_current;
    const char *cs = sf->s;
    const size_t slen = sf->slen;
    size_t pos = sf->pos;

    if (pos + 1 < slen && cs[pos] == '0' && (cs[pos + 1] == 'X' || cs[pos + 1] == 'x')) {
        // TBD compare if isxdigit
        size_t xlen =
            strlenspn(cs + pos + 2, slen - pos - 2, "0123456789ABCDEFabcdef");
        if (xlen == 0) {
            st_assign_cstr(current, 'n', "0X");
            return pos + 2;
        } else {
            st_assign(current, '1', cs + pos, 2 + xlen);
            return pos + 2 + xlen;
        }
    }
    size_t start = pos;

    while (isdigit(cs[pos])) {
        pos += 1;
    }
    if (cs[pos] == '.') {
        pos += 1;
        while (pos < slen && isdigit(cs[pos])) {
            pos += 1;
        }
        if (pos - start == 1) {
            st_assign_char(current, 'n', '.');
            return pos;
        }
    }

    if (cs[pos] == 'E' || cs[pos] == 'e') {
        pos += 1;
        if (pos < slen && (cs[pos] == '+' || cs[pos] == '-')) {
            pos += 1;
        }
        while (isdigit(cs[pos])) {
            pos += 1;
        }
    } else if (isalpha(cs[pos])) {
        // oh no, we have something like '6FOO'
        // use microsoft style parsing and take just
        // the number part and leave the rest to be
        // parsed later
        st_assign(current, '1', cs + start, pos - start);
        return pos;
    }

    st_assign(current, '1', cs + start, pos - start);
    return pos;
}

int parse_token(sfilter * sf)
{
    stoken_t *current = &sf->syntax_current;
    const char *s = sf->s;
    const size_t slen = sf->slen;
    size_t *pos = &sf->pos;

    st_clear(current);

    if (*pos == 0 && sf->delim != CHAR_NULL) {
        *pos = parse_string_core(s, slen, 0, current, sf->delim, 0);
        return TRUE;
    }

    while (*pos < slen) {
        const int ch = (int) (s[*pos]);
        if (ch < 0 || ch > 127) {
            *pos += 1;
            continue;
        }
        pt2Function fnptr = char_parse_map[ch];
        *pos = (*fnptr) (sf);
        if (current->type != CHAR_NULL) {
            return TRUE;
        }
    }
    return FALSE;
}

void sfilter_reset(sfilter * sf, const char *s, size_t len)
{
    memset(sf, 0, sizeof(sfilter));
    sf->s = s;
    sf->slen = len;
}

int syntax_merge_words(stoken_t * a, stoken_t * b)
{
    if (!
        (a->type == 'k' || a->type == 'n' || a->type == 'o'
         || a->type == 'U')) {
        return FALSE;
    }

    size_t sz1 = strlen(a->val);
    size_t sz2 = strlen(b->val);
    size_t sz3 = sz1 + sz2 + 1;
    if (sz3 >= ST_MAX_SIZE) {
        return FALSE;
    }
    // oddly annoying last.val + ' ' + current.val
    char tmp[ST_MAX_SIZE];
    memcpy(tmp, a->val, sz1);
    tmp[sz1] = ' ';
    memcpy(tmp + sz1 + 1, b->val, sz2);
    tmp[sz3] = CHAR_NULL;

    char ch = bsearch_keyword_type(tmp, multikeywords, multikeywords_sz);
    if (ch != CHAR_NULL) {
        // -1, don't copy the null byte
        st_assign(a, ch, tmp, sz3);
        return TRUE;
    } else {
        return FALSE;
    }
}

int sqli_tokenize(sfilter * sf, stoken_t * sout)
{
    stoken_t *last = &sf->syntax_last;
    stoken_t *current = &sf->syntax_current;

    while (parse_token(sf)) {
        char ttype = current->type;
        if (ttype == 'c') {
            st_copy(&sf->syntax_comment, current);
            continue;
        }
        st_clear(&sf->syntax_comment);

        //
        // If we don't have a saved token
        //
        if (last->type == CHAR_NULL) {
            switch (ttype) {

                // items that have special needs
            case 's':
                st_copy(last, current);
                continue;
            case 'n':
            case 'k':
            case 'U':
            case '&':
            case 'o':
                if (st_is_multiword_start(current)) {
                    st_copy(last, current);
                    continue;
                } else if (current->type == 'o' || current->type == '&') {
                    //} else if (st_is_unary_op(current)) {
                    st_copy(last, current);
                    continue;
                } else {
                    // copy to out
                    st_copy(sout, current);
                    return TRUE;
                }
            default:
                // copy to out
                st_copy(sout, current);
                return TRUE;
            }
        }
        //
        // We have a saved token
        //

        switch (ttype) {
        case 's':
            if (last->type == 's') {
                // "FOO" "BAR" == "FOO" (skip second string)
                continue;
            } else {
                st_copy(sout, last);
                st_copy(last, current);
                return TRUE;
            }
            break;

        case 'o':
            // first case to handle "IS" + "NOT"
            if (syntax_merge_words(last, current)) {
                continue;
            } else if (st_is_unary_op(current)
                       && (last->type == 'o' || last->type == '&'
                           || last->type == 'U')) {
                // if an operator is followed by a unary operator, skip it.
                // 1, + ==> "+" is not unary, it's arithmetic
                // AND, + ==> "+" is unary
                continue;
            } else {
                // no match
                st_copy(sout, last);
                st_copy(last, current);
                return TRUE;
            }
            break;

        case 'n':
        case 'k':
            if (syntax_merge_words(last, current)) {
                continue;
            } else {
                // total no match
                st_copy(sout, last);
                st_copy(last, current);
                return TRUE;
            }
            break;

        default:
            // fix up for ambigous "IN"
            // handle case where IN is typically a function
            // but used in compound "IN BOOLEAN MODE" jive
            if (last->type == 'n' && !cstrcasecmp(last->val, "IN")) {
                st_copy(last, current);
                st_assign_cstr(sout, 'f', "IN");
                return TRUE;
            } else {
                // no match at all
                st_copy(sout, last);
                st_copy(last, current);
                return TRUE;
            }
            break;
        }
    }

    // final cleanup
    if (last->type) {
        st_copy(sout, last);
        st_clear(last);
        return TRUE;
    } else if (sf->syntax_comment.type) {
        st_copy(sout, &sf->syntax_comment);
        st_clear(&sf->syntax_comment);
        return TRUE;
    } else {
        return FALSE;
    }
}

int filter_fold(sfilter * sf, stoken_t * sout)
{
    stoken_t *last = &sf->fold_last;
    stoken_t *current = &sf->fold_current;

    if (sf->fold_state == 4 && !st_is_empty(last)) {
        st_copy(sout, last);
        sf->fold_state = 2;
        st_clear(last);
        return TRUE;
    }

    while (sqli_tokenize(sf, current)) {
        // 0 = start of statement
        // skip ( and unary ops
        if (sf->fold_state == 0) {
            if (current->type == '(') {
                continue;
            }
            if (st_is_unary_op(current)) {
                continue;
            }
            sf->fold_state = 1;
        }

        if (st_is_empty(last)) {
            FOLD_DEBUG;
            if (current->type == '1' || current->type == 'n'
                || current->type == '(') {
                sf->fold_state = 2;
                st_copy(last, current);
            }
            st_copy(sout, current);
            return TRUE;
        } else if (last->type == '(' && st_is_unary_op(current)) {
            // similar to beginning of statement
            // an opening '(' resets state, and we should skip all
            // unary operators
            continue;
        } else if (last->type == '(' && current->type == '(') {
            // if we get another '(' after another
            // emit 1, but keep state
            st_copy(sout, current);
            return TRUE;
        } else if ((last->type == '1' || last->type == 'n')
                   && st_is_arith_op(current)) {
            FOLD_DEBUG;
            st_copy(last, current);
        } else if (last->type == 'o'
                   && (current->type == '1' || current->type == 'n')) {
            FOLD_DEBUG;
            st_copy(last, current);
        } else {
            if (sf->fold_state == 2) {
                if (last->type != '1' && last->type != '('
                    && last->type != 'n') {
                    FOLD_DEBUG;
                    st_copy(sout, last);
                    st_copy(last, current);
                    sf->fold_state = 4;
                } else {
                    FOLD_DEBUG;
                    st_copy(sout, current);
                    st_clear(last);
                }
                return TRUE;
            } else {
                if (last->type == 'o') {
                    st_copy(sout, last);
                    st_copy(last, current);
                    sf->fold_state = 4;
                } else {
                    sf->fold_state = 2;
                    st_copy(sout, current);
                    st_clear(last);
                }
                return TRUE;
            }
        }
    }

    if (!st_is_empty(last)) {
        if (st_is_arith_op(last)) {
            st_copy(sout, last);
            st_clear(last);
            return TRUE;
        } else {
            st_clear(last);
        }
    }

    return FALSE;
}

int is_string_sqli(sfilter * sql_state, const char *s, size_t slen,
                    const char delim, ptr_fingerprints_fn fn)
{
    sfilter_reset(sql_state, s, slen);
    sql_state->delim = delim;

    int all_done = 0;
    int tlen = 0;
    while (tlen < MAX_TOKENS) {
        all_done = filter_fold(sql_state, &(sql_state->tokenvec[tlen]));
        if (!all_done) {
            break;
        }

        sql_state->pat[tlen] = sql_state->tokenvec[tlen].type;
        tlen += 1;
    }
    sql_state->pat[tlen] = CHAR_NULL;

    // if token 5 (last) looks like a functino word (such as ABS or ASCII)
    // then check token 6 to see if it's a "(".
    // if NOT then, it's not a function.

    if (tlen == MAX_TOKENS && !all_done
        && sql_state->pat[MAX_TOKENS - 1] == 'f') {

        stoken_t tmp;
        all_done = filter_fold(sql_state, &tmp);
        if (!all_done && tmp.type != '(') {
            sql_state->reason = __LINE__;
            return FALSE;
        }
    }
    // check for 'X' in pattern
    // this means parsing could not be done
    // accurately due to pgsql's double comments
    // or other syntax that isn't consistent
    // should be very rare false positive
    if (strchr(sql_state->pat, 'X')) {
        return TRUE;
    }

    int patmatch = fn(sql_state->pat);

    if (!patmatch) {
        sql_state->reason = __LINE__;
        return FALSE;
    }
    switch (tlen) {
    case 2:{
            // if 'comment' is '#' ignore.. too many FP
            if (sql_state->tokenvec[1].val[0] == '#') {
                sql_state->reason = __LINE__;
                return FALSE;
            }
            // detect obvious sqli scans.. many people put '--' in plain text
            // so only detect if input ends with '--', e.g. 1-- but not 1-- foo
            if ((strlen(sql_state->tokenvec[1].val) > 2)
                && sql_state->tokenvec[1].val[0] == '-') {
                sql_state->reason = __LINE__;
                return FALSE;
            }
            break;
        }
    case 3:{
            // ...foo' + 'bar...
            // no opening quote, no closing quote
            // and each string has data
            if (streq(sql_state->pat, "sos")
                || streq(sql_state->pat, "s&s")) {
                if ((sql_state->tokenvec[0].str_open == CHAR_NULL)
                    && (sql_state->tokenvec[2].str_close == CHAR_NULL)) {

                    // if ....foo" + "bar....
                    return TRUE;
                } else {
                    // not sqli
                    sql_state->reason = __LINE__;
                    return FALSE;
                }
                break;
            }
        } /* case 3 */
    } /* end switch */
    return TRUE;
}

int is_sqli(sfilter * sql_state, const char *s, size_t slen,
            ptr_fingerprints_fn fn)
{

    if (slen == 0) {
        return FALSE;
    }

    if (is_string_sqli(sql_state, s, slen, CHAR_NULL, fn)) {
        return TRUE;
    }

    if (memchr(s, CHAR_SINGLE, slen)
        && is_string_sqli(sql_state, s, slen, CHAR_SINGLE, fn)) {
        return TRUE;
    }

    if (memchr(s, CHAR_DOUBLE, slen)
        && is_string_sqli(sql_state, s, slen, CHAR_DOUBLE, fn)) {
        return TRUE;
    }

    return FALSE;
}

/*
not used yet

// [('o', 228), ('k', 220), ('1', 217), (')', 157), ('(', 156), ('s', 154), ('n', 77), ('f', 73), (';', 59), (',', 35), ('v', 17), ('c', 15),
int char2int(char c)
{
const char *map = "ok1()snf;,";
const char *pos = strchr(map, c);
if (pos == NULL) {
return 15;
} else {
return (int) (pos - map) + 1;
}
}

unsigned long long pat2int(const char *pat)
{
unsigned long long val = 0;
while (*pat) {
val = (val << 4) + char2int(*pat);
pat += 1;
}
return val;
}
*/
-
-
- -
-
- - - - -
-
-
- - - - -
-
-
-
- - -
- - - - - -
-
-
- -
-
-
-
-
-
-
- - - - - - -
-
- - - -
- - Something went wrong with that request. Please try again. - -
- - - - - - - - +/** + * Copyright 2012,2013 Nick Galbreath + * nickg@client9.com + * BSD License -- see COPYING.txt for details + * + * (setq-default indent-tabs-mode nil) + * (setq c-default-style "k&r" + * c-basic-offset 4) + * indent -kr -nut + */ + +#include +#include +#include +#include +#include + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +#if 0 +#define FOLD_DEBUG printf("%d: Fold state = %d, current=%c, last=%c\n", __LINE__, sf->fold_state, current->type, last->type == CHAR_NULL ? '~': last->type) +#else +#define FOLD_DEBUG +#endif + +// order is important here +#include "sqlparse_private.h" +#include "sqlparse_data.h" + +// memmem is a linux function +// may not exist in Windows, and doesn't exist +// in Mac OS X < 10.8 and FreeBSD < 6.0 +// Define our own. Modified to use 'const char*' +// instead of (void *) +// + +/*- + * Copyright (c) 2005 Pascal Gloor + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +const char * +my_memmem(const char *cl, size_t l_len, const char *cs, size_t s_len) +{ + register const char *cur, *last; + + /* we need something to compare */ + if (l_len == 0 || s_len == 0) + return NULL; + + /* "s" must be smaller or equal to "l" */ + if (l_len < s_len) + return NULL; + + /* special case where s_len == 1 */ + if (s_len == 1) + return (const char*) memchr(cl, (int)*cs, l_len); + + /* the last position where its possible to find "s" in "l" */ + last = cl + l_len - s_len; + + for (cur = cl; cur <= last; cur++) + if (cur[0] == cs[0] && memcmp(cur, cs, s_len) == 0) + return cur; + + return NULL; +} + + +size_t strlenspn(const char *s, size_t len, const char *accept) +{ + size_t i; + for (i = 0; i < len; ++i) { + /* likely we can do better by inlining this function + * but this works for now + */ + if (strchr(accept, s[i]) == NULL) { + return i; + } + } + return len; +} + +/* + * ASCII case insenstive compare only! + */ +int cstrcasecmp(const char *a, const char *b) +{ + int ca, cb; + + do { + ca = *a++ & 0xff; + cb = *b++ & 0xff; + if (ca >= 'a' && ca <= 'z') + ca -= 0x20; + if (cb >= 'a' && cb <= 'z') + cb -= 0x20; + } while (ca == cb && ca != '\0'); + + return ca - cb; +} + +int streq(const char *a, const char *b) +{ + return cstrcasecmp(a, b) == 0; +} + +void st_clear(stoken_t * st) +{ + st->type = CHAR_NULL; + st->str_open = CHAR_NULL; + st->str_close = CHAR_NULL; + st->val[0] = CHAR_NULL; +} + +int st_is_empty(const stoken_t * st) +{ + return st->type == CHAR_NULL; +} + +void st_assign_char(stoken_t * st, const char stype, const char value) +{ + st->type = stype; + st->val[0] = value; + st->val[1] = CHAR_NULL; +} + +void st_assign(stoken_t * st, const char stype, const char *value, + size_t len) +{ + size_t last = len < (ST_MAX_SIZE - 1) ? len : (ST_MAX_SIZE - 1); + st->type = stype; + strncpy(st->val, value, last); + st->val[last] = CHAR_NULL; +} + +void st_assign_cstr(stoken_t * st, const char stype, const char *value) +{ + st->type = stype; + strncpy(st->val, value, ST_MAX_SIZE - 1); + st->val[ST_MAX_SIZE - 1] = CHAR_NULL; +} + +int st_equals_cstr(const stoken_t * st, const char stype, + const char *value) +{ + return st->type == stype && !cstrcasecmp(value, st->val); +} + +void st_copy(stoken_t * dest, const stoken_t * src) +{ + memcpy(dest, src, sizeof(stoken_t)); +} + +const char *bsearch_cstrcase(const char *key, const char *base[], size_t nmemb) +{ + int left = 0; + int right = (int) nmemb - 1; + + while (left <= right) { + int pos = (left + right) / 2; + int cmp = cstrcasecmp(base[pos], key); + if (cmp == 0) { + return base[pos]; + } else if (cmp < 0) { + left = pos + 1; + } else { + right = pos - 1; + } + } + return NULL; +} + +const char *bsearch_cstr(const char *key, const char *base[], size_t nmemb) +{ + int left = 0; + int right = (int) nmemb - 1; + + while (left <= right) { + int pos = (left + right) / 2; + int cmp = strcmp(base[pos], key); + if (cmp == 0) { + return base[pos]; + } else if (cmp < 0) { + left = pos + 1; + } else { + right = pos - 1; + } + } + return NULL; +} + +char bsearch_keyword_type(const char *key, const keyword_t * keywords, + size_t numb) +{ + int left = 0; + int right = (int) numb - 1; + + while (left <= right) { + int pos = (left + right) / 2; + int cmp = cstrcasecmp(keywords[pos].word, key); + if (cmp == 0) { + return keywords[pos].type; + } else if (cmp < 0) { + left = pos + 1; + } else { + right = pos - 1; + } + } + return CHAR_NULL; +} + +int is_operator2(const char *key) +{ + return bsearch_cstrcase(key, operators2, operators2_sz) != NULL; +} + +int st_is_multiword_start(const stoken_t * st) +{ + return bsearch_cstrcase(st->val, + multikeywords_start, + multikeywords_start_sz) != NULL; +} + +int st_is_unary_op(const stoken_t * st) +{ + return (st->type == 'o' && !(strcmp(st->val, "+") && + strcmp(st->val, "-") && + strcmp(st->val, "!") && + strcmp(st->val, "!!") && + cstrcasecmp(st->val, "NOT") && + strcmp(st->val, "~"))); +} + +int st_is_arith_op(const stoken_t * st) +{ + return (st->type == 'o' && !(strcmp(st->val, "-") && + strcmp(st->val, "+") && + strcmp(st->val, "~") && + strcmp(st->val, "!") && + strcmp(st->val, "/") && + strcmp(st->val, "%") && + strcmp(st->val, "*") && + strcmp(st->val, "|") && + strcmp(st->val, "&") && + cstrcasecmp(st->val, "MOD") && + cstrcasecmp(st->val, "DIV"))); +} + +size_t parse_white(sfilter * sf) +{ + return sf->pos + 1; +} + +size_t parse_operator1(sfilter * sf) +{ + stoken_t *current = &sf->syntax_current; + const char *cs = sf->s; + size_t pos = sf->pos; + + st_assign_char(current, 'o', cs[pos]); + return pos + 1; +} + +size_t parse_other(sfilter * sf) +{ + stoken_t *current = &sf->syntax_current; + const char *cs = sf->s; + size_t pos = sf->pos; + + st_assign_char(current, '?', cs[pos]); + return pos + 1; +} + +size_t parse_char(sfilter * sf) +{ + stoken_t *current = &sf->syntax_current; + const char *cs = sf->s; + size_t pos = sf->pos; + + st_assign_char(current, cs[pos], cs[pos]); + return pos + 1; +} + +size_t parse_eol_comment(sfilter * sf) +{ + stoken_t *current = &sf->syntax_current; + const char *cs = sf->s; + const size_t slen = sf->slen; + size_t pos = sf->pos; + + const char *endpos = + (const char *) memchr((const void *) (cs + pos), '\n', slen - pos); + if (endpos == NULL) { + st_assign_cstr(current, 'c', cs + pos); + return slen; + } else { + st_assign(current, 'c', cs + pos, endpos - cs - pos); + return (endpos - cs) + 1; + } +} + +size_t parse_dash(sfilter * sf) +{ + stoken_t *current = &sf->syntax_current; + const char *cs = sf->s; + const size_t slen = sf->slen; + size_t pos = sf->pos; + + + size_t pos1 = pos + 1; + if (pos1 < slen && cs[pos1] == '-') { + return parse_eol_comment(sf); + } else { + st_assign_char(current, 'o', '-'); + return pos1; + } +} + +size_t is_mysql_comment(const char *cs, const size_t len, size_t pos) +{ + size_t i; + + if (pos + 2 >= len) { + return 0; + } + if (cs[pos + 2] != '!') { + return 0; + } + // this is a mysql comment + // got "/*!" + if (pos + 3 >= len) { + return 3; + } + + if (!isdigit(cs[pos + 3])) { + return 3; + } + // handle odd case of /*!0SELECT + if (!isdigit(cs[pos + 4])) { + return 4; + } + + if (pos + 7 >= len) { + return 4; + } + + for (i = pos + 5; i <= pos + 7; ++i) { + if (!isdigit(cs[i])) { + return 3; + } + } + return 8; +} + +size_t parse_slash(sfilter * sf) +{ + stoken_t *current = &sf->syntax_current; + const char *cs = sf->s; + const size_t slen = sf->slen; + size_t pos = sf->pos; + const char* cur = cs + pos; + + size_t pos1 = pos + 1; + if (pos1 == slen || cs[pos1] != '*') { + return parse_operator1(sf); + } + + size_t inc = is_mysql_comment(cs, slen, pos); + if (inc == 0) { + + // skip over initial '/*' + const char *ptr = + (const char *) my_memmem(cur + 2, slen - (pos + 2), "*/", 2); + if (ptr == NULL) { + // unterminated comment + st_assign_cstr(current, 'c', cs + pos); + return slen; + } else { + // postgresql allows nested comments which makes + // this is incompatible with parsing so + // if we find a '/*' inside the coment, then + // make a new token. + char ctype = 'c'; + const size_t clen = (ptr + 2) - (cur); + if (my_memmem(cur + 2, ptr - (cur + 2), "/*", 2) != + NULL) { + ctype = 'X'; + } + st_assign(current, ctype, cs + pos, clen); + + return pos + clen; + } + } else { + // MySQL Comment + sf->in_comment = TRUE; + st_clear(current); + return pos + inc; + } +} + +size_t parse_backslash(sfilter * sf) +{ + stoken_t *current = &sf->syntax_current; + const char *cs = sf->s; + const size_t slen = sf->slen; + size_t pos = sf->pos; + + if (pos + 1 < slen && cs[pos + 1] == 'N') { + st_assign_cstr(current, '1', "NULL"); + return pos + 2; + } else { + return parse_other(sf); + } +} + +size_t parse_operator2(sfilter * sf) +{ + stoken_t *current = &sf->syntax_current; + const char *cs = sf->s; + const size_t slen = sf->slen; + size_t pos = sf->pos; + + if (pos + 1 >= slen) { + return parse_operator1(sf); + } + char op2[3] = { cs[pos], cs[pos + 1], CHAR_NULL }; + + // Special Hack for MYSQL style comments + // instead of turning: + // /*! FOO */ into FOO by rewriting the string, we + // turn it into FOO */ and ignore the ending comment + if (sf->in_comment && op2[0] == '*' && op2[1] == '/') { + sf->in_comment = FALSE; + st_clear(current); + return pos + 2; + } else if (pos + 2 < slen && op2[0] == '<' && op2[1] == '=' + && cs[pos + 2] == '>') { + // special 3-char operator + + st_assign_cstr(current, 'o', "<=>"); + return pos + 3; + } else if (is_operator2(op2)) { + if (streq(op2, "&&") || streq(op2, "||")) { + st_assign_cstr(current, '&', op2); + } else { + // normal 2 char operator + st_assign_cstr(current, 'o', op2); + } + return pos + 2; + } else { + // must be a single char operator + return parse_operator1(sf); + } +} + +size_t parse_string_core(const char *cs, const size_t len, size_t pos, + stoken_t * st, char delim, size_t offset) +{ + // offset is to skip the perhaps first quote char + const char *qpos = + (const char *) memchr((const void *) (cs + pos + offset), delim, + len - pos - offset); + + // then keep string open/close info + if (offset == 1) { + // this is real quote + st->str_open = delim; + } else { + // this was a simulated quote + st->str_open = CHAR_NULL; + } + + while (TRUE) { + if (qpos == NULL) { + // string ended with no trailing quote + // assign what we have + st_assign_cstr(st, 's', cs + pos + offset); + st->str_close = CHAR_NULL; + return len; + } else if (*(qpos - 1) != '\\') { + // ending quote is not escaped.. copy and end + st_assign(st, 's', cs + pos + offset, + qpos - (cs + pos + offset)); + st->str_close = delim; + return qpos - cs + 1; + } else { + qpos = + (const char *) memchr((const void *) (qpos + 1), delim, + (cs + len) - (qpos + 1)); + } + } +} + +/** + * Used when first char is a ' or " + */ +size_t parse_string(sfilter * sf) +{ + stoken_t *current = &sf->syntax_current; + const char *cs = sf->s; + const size_t slen = sf->slen; + size_t pos = sf->pos; + + // assert cs[pos] == single or double quote + return parse_string_core(cs, slen, pos, current, cs[pos], 1); +} + +size_t parse_word(sfilter * sf) +{ + stoken_t *current = &sf->syntax_current; + const char *cs = sf->s; + size_t pos = sf->pos; + + size_t slen = + strlenspn(cs + pos, sf->slen - pos, + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.$"); + + st_assign(current, 'n', cs + pos, slen); + if (slen < ST_MAX_SIZE) { + char ch = bsearch_keyword_type(current->val, sql_keywords, + sql_keywords_sz); + if (ch == CHAR_NULL) { + ch = 'n'; + } + current->type = ch; + } + return pos + slen; +} + +size_t parse_var(sfilter * sf) +{ + stoken_t *current = &sf->syntax_current; + const char *cs = sf->s; + const size_t slen = sf->slen; + size_t pos = sf->pos; + + size_t pos1 = pos + 1; + + // move past optional other '@' + if (pos1 < slen && cs[pos1] == '@') { + pos1 += 1; + } + + size_t xlen = + strlenspn(cs + pos1, slen - pos1, + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.$"); + if (xlen == 0) { + st_assign(current, 'v', cs + pos, (pos1 - pos)); + return pos1; + } else { + st_assign(current, 'v', cs + pos, xlen + (pos1 - pos)); + return pos1 + xlen; + } +} + +size_t parse_number(sfilter * sf) +{ + stoken_t *current = &sf->syntax_current; + const char *cs = sf->s; + const size_t slen = sf->slen; + size_t pos = sf->pos; + + if (pos + 1 < slen && cs[pos] == '0' && (cs[pos + 1] == 'X' || cs[pos + 1] == 'x')) { + // TBD compare if isxdigit + size_t xlen = + strlenspn(cs + pos + 2, slen - pos - 2, "0123456789ABCDEFabcdef"); + if (xlen == 0) { + st_assign_cstr(current, 'n', "0X"); + return pos + 2; + } else { + st_assign(current, '1', cs + pos, 2 + xlen); + return pos + 2 + xlen; + } + } + size_t start = pos; + + while (isdigit(cs[pos])) { + pos += 1; + } + if (cs[pos] == '.') { + pos += 1; + while (pos < slen && isdigit(cs[pos])) { + pos += 1; + } + if (pos - start == 1) { + st_assign_char(current, 'n', '.'); + return pos; + } + } + + if (cs[pos] == 'E' || cs[pos] == 'e') { + pos += 1; + if (pos < slen && (cs[pos] == '+' || cs[pos] == '-')) { + pos += 1; + } + while (isdigit(cs[pos])) { + pos += 1; + } + } else if (isalpha(cs[pos])) { + // oh no, we have something like '6FOO' + // use microsoft style parsing and take just + // the number part and leave the rest to be + // parsed later + st_assign(current, '1', cs + start, pos - start); + return pos; + } + + st_assign(current, '1', cs + start, pos - start); + return pos; +} + +int parse_token(sfilter * sf) +{ + stoken_t *current = &sf->syntax_current; + const char *s = sf->s; + const size_t slen = sf->slen; + size_t *pos = &sf->pos; + + st_clear(current); + + if (*pos == 0 && sf->delim != CHAR_NULL) { + *pos = parse_string_core(s, slen, 0, current, sf->delim, 0); + return TRUE; + } + + while (*pos < slen) { + const int ch = (int) (s[*pos]); + if (ch < 0 || ch > 127) { + *pos += 1; + continue; + } + pt2Function fnptr = char_parse_map[ch]; + *pos = (*fnptr) (sf); + if (current->type != CHAR_NULL) { + return TRUE; + } + } + return FALSE; +} + +void sfilter_reset(sfilter * sf, const char *s, size_t len) +{ + memset(sf, 0, sizeof(sfilter)); + sf->s = s; + sf->slen = len; +} + +int syntax_merge_words(stoken_t * a, stoken_t * b) +{ + if (! + (a->type == 'k' || a->type == 'n' || a->type == 'o' + || a->type == 'U')) { + return FALSE; + } + + size_t sz1 = strlen(a->val); + size_t sz2 = strlen(b->val); + size_t sz3 = sz1 + sz2 + 1; + if (sz3 >= ST_MAX_SIZE) { + return FALSE; + } + // oddly annoying last.val + ' ' + current.val + char tmp[ST_MAX_SIZE]; + memcpy(tmp, a->val, sz1); + tmp[sz1] = ' '; + memcpy(tmp + sz1 + 1, b->val, sz2); + tmp[sz3] = CHAR_NULL; + + char ch = bsearch_keyword_type(tmp, multikeywords, multikeywords_sz); + if (ch != CHAR_NULL) { + // -1, don't copy the null byte + st_assign(a, ch, tmp, sz3); + return TRUE; + } else { + return FALSE; + } +} + +int sqli_tokenize(sfilter * sf, stoken_t * sout) +{ + stoken_t *last = &sf->syntax_last; + stoken_t *current = &sf->syntax_current; + + while (parse_token(sf)) { + char ttype = current->type; + if (ttype == 'c') { + st_copy(&sf->syntax_comment, current); + continue; + } + st_clear(&sf->syntax_comment); + + // + // If we don't have a saved token + // + if (last->type == CHAR_NULL) { + switch (ttype) { + + // items that have special needs + case 's': + st_copy(last, current); + continue; + case 'n': + case 'k': + case 'U': + case '&': + case 'o': + if (st_is_multiword_start(current)) { + st_copy(last, current); + continue; + } else if (current->type == 'o' || current->type == '&') { + //} else if (st_is_unary_op(current)) { + st_copy(last, current); + continue; + } else { + // copy to out + st_copy(sout, current); + return TRUE; + } + default: + // copy to out + st_copy(sout, current); + return TRUE; + } + } + // + // We have a saved token + // + + switch (ttype) { + case 's': + if (last->type == 's') { + // "FOO" "BAR" == "FOO" (skip second string) + continue; + } else { + st_copy(sout, last); + st_copy(last, current); + return TRUE; + } + break; + + case 'o': + // first case to handle "IS" + "NOT" + if (syntax_merge_words(last, current)) { + continue; + } else if (st_is_unary_op(current) + && (last->type == 'o' || last->type == '&' + || last->type == 'U')) { + // if an operator is followed by a unary operator, skip it. + // 1, + ==> "+" is not unary, it's arithmetic + // AND, + ==> "+" is unary + continue; + } else { + // no match + st_copy(sout, last); + st_copy(last, current); + return TRUE; + } + break; + + case 'n': + case 'k': + if (syntax_merge_words(last, current)) { + continue; + } else { + // total no match + st_copy(sout, last); + st_copy(last, current); + return TRUE; + } + break; + + default: + // fix up for ambigous "IN" + // handle case where IN is typically a function + // but used in compound "IN BOOLEAN MODE" jive + if (last->type == 'n' && !cstrcasecmp(last->val, "IN")) { + st_copy(last, current); + st_assign_cstr(sout, 'f', "IN"); + return TRUE; + } else { + // no match at all + st_copy(sout, last); + st_copy(last, current); + return TRUE; + } + break; + } + } + + // final cleanup + if (last->type) { + st_copy(sout, last); + st_clear(last); + return TRUE; + } else if (sf->syntax_comment.type) { + st_copy(sout, &sf->syntax_comment); + st_clear(&sf->syntax_comment); + return TRUE; + } else { + return FALSE; + } +} + +int filter_fold(sfilter * sf, stoken_t * sout) +{ + stoken_t *last = &sf->fold_last; + stoken_t *current = &sf->fold_current; + + if (sf->fold_state == 4 && !st_is_empty(last)) { + st_copy(sout, last); + sf->fold_state = 2; + st_clear(last); + return TRUE; + } + + while (sqli_tokenize(sf, current)) { + // 0 = start of statement + // skip ( and unary ops + if (sf->fold_state == 0) { + if (current->type == '(') { + continue; + } + if (st_is_unary_op(current)) { + continue; + } + sf->fold_state = 1; + } + + if (st_is_empty(last)) { + FOLD_DEBUG; + if (current->type == '1' || current->type == 'n' + || current->type == '(') { + sf->fold_state = 2; + st_copy(last, current); + } + st_copy(sout, current); + return TRUE; + } else if (last->type == '(' && st_is_unary_op(current)) { + // similar to beginning of statement + // an opening '(' resets state, and we should skip all + // unary operators + continue; + } else if (last->type == '(' && current->type == '(') { + // if we get another '(' after another + // emit 1, but keep state + st_copy(sout, current); + return TRUE; + } else if ((last->type == '1' || last->type == 'n') + && st_is_arith_op(current)) { + FOLD_DEBUG; + st_copy(last, current); + } else if (last->type == 'o' + && (current->type == '1' || current->type == 'n')) { + FOLD_DEBUG; + st_copy(last, current); + } else { + if (sf->fold_state == 2) { + if (last->type != '1' && last->type != '(' + && last->type != 'n') { + FOLD_DEBUG; + st_copy(sout, last); + st_copy(last, current); + sf->fold_state = 4; + } else { + FOLD_DEBUG; + st_copy(sout, current); + st_clear(last); + } + return TRUE; + } else { + if (last->type == 'o') { + st_copy(sout, last); + st_copy(last, current); + sf->fold_state = 4; + } else { + sf->fold_state = 2; + st_copy(sout, current); + st_clear(last); + } + return TRUE; + } + } + } + + if (!st_is_empty(last)) { + if (st_is_arith_op(last)) { + st_copy(sout, last); + st_clear(last); + return TRUE; + } else { + st_clear(last); + } + } + + return FALSE; +} + +int is_string_sqli(sfilter * sql_state, const char *s, size_t slen, + const char delim, ptr_fingerprints_fn fn) +{ + sfilter_reset(sql_state, s, slen); + sql_state->delim = delim; + + int all_done = 0; + int tlen = 0; + while (tlen < MAX_TOKENS) { + all_done = filter_fold(sql_state, &(sql_state->tokenvec[tlen])); + if (!all_done) { + break; + } + + sql_state->pat[tlen] = sql_state->tokenvec[tlen].type; + tlen += 1; + } + sql_state->pat[tlen] = CHAR_NULL; + + // if token 5 (last) looks like a functino word (such as ABS or ASCII) + // then check token 6 to see if it's a "(". + // if NOT then, it's not a function. + + if (tlen == MAX_TOKENS && !all_done + && sql_state->pat[MAX_TOKENS - 1] == 'f') { + + stoken_t tmp; + all_done = filter_fold(sql_state, &tmp); + if (!all_done && tmp.type != '(') { + sql_state->reason = __LINE__; + return FALSE; + } + } + // check for 'X' in pattern + // this means parsing could not be done + // accurately due to pgsql's double comments + // or other syntax that isn't consistent + // should be very rare false positive + if (strchr(sql_state->pat, 'X')) { + return TRUE; + } + + int patmatch = fn(sql_state->pat); + + if (!patmatch) { + sql_state->reason = __LINE__; + return FALSE; + } + switch (tlen) { + case 2:{ + // if 'comment' is '#' ignore.. too many FP + if (sql_state->tokenvec[1].val[0] == '#') { + sql_state->reason = __LINE__; + return FALSE; + } + // detect obvious sqli scans.. many people put '--' in plain text + // so only detect if input ends with '--', e.g. 1-- but not 1-- foo + if ((strlen(sql_state->tokenvec[1].val) > 2) + && sql_state->tokenvec[1].val[0] == '-') { + sql_state->reason = __LINE__; + return FALSE; + } + break; + } + case 3:{ + // ...foo' + 'bar... + // no opening quote, no closing quote + // and each string has data + if (streq(sql_state->pat, "sos") + || streq(sql_state->pat, "s&s")) { + if ((sql_state->tokenvec[0].str_open == CHAR_NULL) + && (sql_state->tokenvec[2].str_close == CHAR_NULL)) { + + // if ....foo" + "bar.... + return TRUE; + } else { + // not sqli + sql_state->reason = __LINE__; + return FALSE; + } + break; + } + } /* case 3 */ + } /* end switch */ + return TRUE; +} + +int is_sqli(sfilter * sql_state, const char *s, size_t slen, + ptr_fingerprints_fn fn) +{ + + if (slen == 0) { + return FALSE; + } + + if (is_string_sqli(sql_state, s, slen, CHAR_NULL, fn)) { + return TRUE; + } + + if (memchr(s, CHAR_SINGLE, slen) + && is_string_sqli(sql_state, s, slen, CHAR_SINGLE, fn)) { + return TRUE; + } + + if (memchr(s, CHAR_DOUBLE, slen) + && is_string_sqli(sql_state, s, slen, CHAR_DOUBLE, fn)) { + return TRUE; + } + + return FALSE; +} + +/* + not used yet + +// [('o', 228), ('k', 220), ('1', 217), (')', 157), ('(', 156), ('s', 154), ('n', 77), ('f', 73), (';', 59), (',', 35), ('v', 17), ('c', 15), +int char2int(char c) +{ + const char *map = "ok1()snf;,"; + const char *pos = strchr(map, c); + if (pos == NULL) { + return 15; + } else { + return (int) (pos - map) + 1; + } +} + +unsigned long long pat2int(const char *pat) +{ + unsigned long long val = 0; + while (*pat) { + val = (val << 4) + char2int(*pat); + pat += 1; + } + return val; +} +*/ diff --git a/apache2/libinjection/sqlparse.h b/apache2/libinjection/sqlparse.h index 40e19f19..f6a0d188 100644 --- a/apache2/libinjection/sqlparse.h +++ b/apache2/libinjection/sqlparse.h @@ -1,859 +1,83 @@ - - - - - - - - - ModSecurity/apache2/libinjection/sqlparse.h at da961d4c1535d2131c1733258b3f809feeabadf5 · client9/ModSecurity · GitHub - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - -
- -
- - - - - - - -
-
- -
-
-
- - - - - -

- public - - - / - ModSecurity - - forked from SpiderLabs/ModSecurity - -

-
- - - - -
- - - - - - -
- - -
- - - tree: - da961d4c15 - - -
- -
-
- Switch branches/tags - -
- -
-
- -
-
- -
-
- -
- -
- -
- - master -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
Nothing to show
-
- - -
-
- -
- - 2.7.3 -
-
- - 2.7.2 -
-
- - 2.7.1 -
-
- -
Nothing to show
- -
- -
-
-
- -
- - - -
- - - - - - - -
-
- -
- - - - - - - -
-
- - - - - - - - - -
- - - - - - - -
- - -
- -
-
- -
-
-
-
- - file - 84 lines (69 sloc) - 1.586 kb -
-
-
- Edit - Raw - Blame - History -
-
- -
-
- - - - - -
- 1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 - - -
/**
* Copyright 2012, Nick Galbreath
* nickg@client9.com
* BSD License -- see COPYING.txt for details
*
*
* HOW TO USE:
*
* // Normalize query or postvar value
* // ATTENTION: this modifies user_string... make copy if that is not ok
* size_t new_len = qs_normalize(user_string, user_string_len);
*
* sfilter s;
* bool sqli = is_sqli(&s, user_string, new_len);
*
* // That's it! sfilter s has some data on how it matched or not
* // details to come!
*
*/

#ifndef _SQLPARSE_H
#define _SQLPARSE_H

#ifdef __cplusplus
extern "C" {
#endif

#define ST_MAX_SIZE 32
#define MAX_TOKENS 5

typedef struct {
    char type;
    char str_open;
    char str_close;
    char val[ST_MAX_SIZE];
} stoken_t;

typedef struct {
    /* input */
    const char *s;
    size_t slen;

    /* current tokenize state */
    size_t pos;
    int in_comment;

    /* syntax fixups state */
    stoken_t syntax_current;
    stoken_t syntax_last;
    stoken_t syntax_comment;

    /* constant folding state */
    stoken_t fold_current;
    stoken_t fold_last;
    int fold_state;

    /* final sqli data */
    stoken_t tokenvec[MAX_TOKENS];

    // +1 for possible ending null
    char pat[MAX_TOKENS + 1];
    char delim;
    int reason;
} sfilter;

/**
* Pointer to function, takes cstr input, return true/false
*/
typedef int (*ptr_fingerprints_fn)(const char*);

/**
*
*
* \return TRUE if SQLi, FALSE is benign
*/
int is_sqli(sfilter * sql_state, const char *s, size_t slen,
             ptr_fingerprints_fn fn);

#ifdef __cplusplus
}
#endif

#endif /* _SQLPARSE_H */
-
-
- -
-
- - - - -
-
-
- - - - -
-
-
-
- - -
- - - - - -
-
-
- -
-
-
-
-
-
- -
- - - -
- - Something went wrong with that request. Please try again. - -
- - - - - - - - +/** + * Copyright 2012, Nick Galbreath + * nickg@client9.com + * BSD License -- see COPYING.txt for details + * + * + * HOW TO USE: + * + * // Normalize query or postvar value + * // ATTENTION: this modifies user_string... make copy if that is not ok + * size_t new_len = qs_normalize(user_string, user_string_len); + * + * sfilter s; + * bool sqli = is_sqli(&s, user_string, new_len); + * + * // That's it! sfilter s has some data on how it matched or not + * // details to come! + * + */ + +#ifndef _SQLPARSE_H +#define _SQLPARSE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define ST_MAX_SIZE 32 +#define MAX_TOKENS 5 + +typedef struct { + char type; + char str_open; + char str_close; + char val[ST_MAX_SIZE]; +} stoken_t; + +typedef struct { + /* input */ + const char *s; + size_t slen; + + /* current tokenize state */ + size_t pos; + int in_comment; + + /* syntax fixups state */ + stoken_t syntax_current; + stoken_t syntax_last; + stoken_t syntax_comment; + + /* constant folding state */ + stoken_t fold_current; + stoken_t fold_last; + int fold_state; + + /* final sqli data */ + stoken_t tokenvec[MAX_TOKENS]; + + // +1 for possible ending null + char pat[MAX_TOKENS + 1]; + char delim; + int reason; +} sfilter; + +/** + * Pointer to function, takes cstr input, return true/false + */ +typedef int (*ptr_fingerprints_fn)(const char*); + +/** + * + * + * \return TRUE if SQLi, FALSE is benign + */ +int is_sqli(sfilter * sql_state, const char *s, size_t slen, + ptr_fingerprints_fn fn); + +#ifdef __cplusplus +} +#endif + +#endif /* _SQLPARSE_H */ diff --git a/apache2/libinjection/sqlparse_data.h b/apache2/libinjection/sqlparse_data.h new file mode 100644 index 00000000..a76af56d --- /dev/null +++ b/apache2/libinjection/sqlparse_data.h @@ -0,0 +1,682 @@ +#ifndef _SQLPARSE_DATA_H +#define _SQLPARSE_DATA_H +#include "sqlparse.h" + +static const char* operators2[] = { + "!!", + "!<", + "!=", + "!>", + "!~", + "%=", + "&&", + "&=", + "*=", + "+=", + "-=", + "/=", + ":=", + "<<", + "<=", + "<>", + "<@", + ">=", + ">>", + "@>", + "^=", + "|/", + "|=", + "||", + "~*", +}; +static const size_t operators2_sz = 25; + +static const keyword_t sql_keywords[] = { + {"ABS", 'f'}, + {"ACCESSIBLE", 'k'}, + {"ACOS", 'f'}, + {"ADD", 'k'}, + {"ADDDATE", 'f'}, + {"ADDTIME", 'f'}, + {"AES_DECRYPT", 'f'}, + {"AES_ENCRYPT", 'f'}, + {"AGAINST", 'k'}, + {"ALL_USERS", 'k'}, + {"ALTER", 'k'}, + {"ANALYZE", 'k'}, + {"AND", '&'}, + {"AS", 'k'}, + {"ASC", 'k'}, + {"ASCII", 'f'}, + {"ASENSITIVE", 'k'}, + {"ASIN", 'f'}, + {"ATAN", 'f'}, + {"ATAN2", 'f'}, + {"AVG", 'f'}, + {"BEFORE", 'k'}, + {"BEGIN", 'k'}, + {"BENCHMARK", 'f'}, + {"BETWEEN", 'k'}, + {"BIGINT", 'k'}, + {"BIN", 'f'}, + {"BINARY", 'k'}, + {"BINARY_DOUBLE_INFINITY", '1'}, + {"BINARY_DOUBLE_NAN", '1'}, + {"BINARY_FLOAT_INFINITY", '1'}, + {"BINARY_FLOAT_NAN", '1'}, + {"BINBINARY", 'f'}, + {"BIT_AND", 'f'}, + {"BIT_COUNT", 'f'}, + {"BIT_LENGTH", 'f'}, + {"BIT_OR", 'f'}, + {"BIT_XOR", 'f'}, + {"BLOB", 'k'}, + {"BOOLEAN", 'k'}, + {"BOTH", 'k'}, + {"BY", 'n'}, + {"CALL", 'k'}, + {"CASCADE", 'k'}, + {"CASE", 'o'}, + {"CAST", 'f'}, + {"CEIL", 'f'}, + {"CEILING", 'f'}, + {"CHANGE", 'k'}, + {"CHAR", 'f'}, + {"CHARACTER", 'k'}, + {"CHARACTER_LENGTH", 'f'}, + {"CHARSET", 'f'}, + {"CHAR_LENGTH", 'f'}, + {"CHECK", 'k'}, + {"CHR", 'f'}, + {"COALESCE", 'k'}, + {"COERCIBILITY", 'f'}, + {"COLLATE", 'k'}, + {"COLLATION", 'f'}, + {"COLUMN", 'k'}, + {"COMPRESS", 'f'}, + {"CONCAT", 'f'}, + {"CONCAT_WS", 'f'}, + {"CONDITION", 'k'}, + {"CONNECTION_ID", 'f'}, + {"CONSTRAINT", 'k'}, + {"CONTINUE", 'k'}, + {"CONV", 'f'}, + {"CONVERT", 'f'}, + {"CONVERT_TZ", 'f'}, + {"COS", 'f'}, + {"COT", 'f'}, + {"COUNT", 'f'}, + {"CRC32", 'f'}, + {"CREATE", 'k'}, + {"CTXSYS.DRITHSX.SN", 'f'}, + {"CURDATE", 'f'}, + {"CURRENT_DATE", 'k'}, + {"CURRENT_DATECURRENT_TIME", 'f'}, + {"CURRENT_TIME", 'k'}, + {"CURRENT_TIMESTAMP", 'k'}, + {"CURRENT_USER", 'k'}, + {"CURSOR", 'k'}, + {"CURTIME", 'f'}, + {"DATABASE", 'k'}, + {"DATABASES", 'k'}, + {"DATE", 'f'}, + {"DATEDIFF", 'f'}, + {"DATE_ADD", 'f'}, + {"DATE_FORMAT", 'f'}, + {"DATE_SUB", 'f'}, + {"DAY", 'f'}, + {"DAYNAME", 'f'}, + {"DAYOFMONTH", 'f'}, + {"DAYOFWEEK", 'f'}, + {"DAYOFYEAR", 'f'}, + {"DAY_HOUR", 'k'}, + {"DAY_MICROSECOND", 'k'}, + {"DAY_MINUTE", 'k'}, + {"DAY_SECOND", 'k'}, + {"DBMS_PIPE.RECEIVE_MESSAGE", 'f'}, + {"DEC", 'k'}, + {"DECIMAL", 'k'}, + {"DECLARE", 'k'}, + {"DECODE", 'f'}, + {"DEFAULT", 'k'}, + {"DEGREES", 'f'}, + {"DELAY", 'k'}, + {"DELAYED", 'k'}, + {"DELETE", 'k'}, + {"DESC", 'k'}, + {"DESCRIBE", 'k'}, + {"DES_DECRYPT", 'f'}, + {"DES_ENCRYPT", 'f'}, + {"DETERMINISTIC", 'k'}, + {"DISTINCROW", 'k'}, + {"DISTINCT", 'k'}, + {"DIV", 'o'}, + {"DROP", 'k'}, + {"DUAL", 'k'}, + {"EACH", 'k'}, + {"ELSE", 'k'}, + {"ELSEIF", 'k'}, + {"ELT", 'f'}, + {"ENCLOSED", 'k'}, + {"ENCODE", 'f'}, + {"ENCRYPT", 'f'}, + {"ESCAPED", 'k'}, + {"EXEC", 'k'}, + {"EXECUTE", 'k'}, + {"EXISTS", 'k'}, + {"EXIT", 'k'}, + {"EXP", 'f'}, + {"EXPLAIN", 'k'}, + {"EXPORT_SET", 'f'}, + {"EXTRACT", 'f'}, + {"EXTRACTVALUE", 'f'}, + {"EXTRACT_VALUE", 'f'}, + {"FALSE", '1'}, + {"FETCH", 'k'}, + {"FIELD", 'f'}, + {"FIND_IN_SET", 'f'}, + {"FLOOR", 'f'}, + {"FOR", 'n'}, + {"FORCE", 'k'}, + {"FOREIGN", 'k'}, + {"FORMAT", 'f'}, + {"FOUND_ROWS", 'f'}, + {"FROM", 'k'}, + {"FROM_DAYS", 'f'}, + {"FROM_UNIXTIME", 'f'}, + {"FULLTEXT", 'k'}, + {"GENERATE_SERIES", 'f'}, + {"GET_FORMAT", 'f'}, + {"GET_LOCK", 'f'}, + {"GOTO", 'k'}, + {"GRANT", 'k'}, + {"GREATEST", 'f'}, + {"GROUP", 'n'}, + {"GROUP_CONCAT", 'f'}, + {"HAVING", 'k'}, + {"HEX", 'f'}, + {"HIGH_PRIORITY", 'k'}, + {"HOST_NAME", 'f'}, + {"HOUR", 'f'}, + {"HOUR_MICROSECOND", 'k'}, + {"HOUR_MINUTE", 'k'}, + {"HOUR_SECOND", 'k'}, + {"IF", 'k'}, + {"IFF", 'f'}, + {"IFNULL", 'f'}, + {"IGNORE", 'k'}, + {"IIF", 'f'}, + {"IN", 'n'}, + {"INDEX", 'k'}, + {"INET_ATON", 'f'}, + {"INET_NTOA", 'f'}, + {"INFILE", 'k'}, + {"INNER", 'k'}, + {"INOUT", 'k'}, + {"INSENSITIVE", 'k'}, + {"INSERT", 'k'}, + {"INSTR", 'f'}, + {"INT", 'k'}, + {"INT1", 'k'}, + {"INT2", 'k'}, + {"INT3", 'k'}, + {"INT4", 'k'}, + {"INT8", 'k'}, + {"INTEGER", 'k'}, + {"INTERVAL", 'k'}, + {"INTO", 'k'}, + {"IS", 'o'}, + {"ISNULL", 'f'}, + {"IS_FREE_LOCK", 'f'}, + {"IS_MEMBERIS_SRVROLEMEMBER", 'f'}, + {"IS_USED_LOCK", 'f'}, + {"ITERATE", 'k'}, + {"JOIN", 'k'}, + {"KEYS", 'k'}, + {"KILL", 'k'}, + {"LAST_INSERT_ID", 'f'}, + {"LCASE", 'f'}, + {"LEADING", 'k'}, + {"LEAST", 'f'}, + {"LEAVE", 'k'}, + {"LEFT", 'n'}, + {"LENGTH", 'f'}, + {"LIKE", 'o'}, + {"LIMIT", 'k'}, + {"LINEAR", 'k'}, + {"LINES", 'k'}, + {"LN", 'f'}, + {"LOAD", 'k'}, + {"LOAD_FILE", 'f'}, + {"LOCALTIME", 'k'}, + {"LOCALTIMESTAMP", 'k'}, + {"LOCATE", 'f'}, + {"LOCK", 'n'}, + {"LOG", 'f'}, + {"LOG10", 'f'}, + {"LOG2", 'f'}, + {"LONGBLOB", 'k'}, + {"LONGTEXT", 'k'}, + {"LOOP", 'k'}, + {"LOWER", 'f'}, + {"LOW_PRIORITY", 'k'}, + {"LPAD", 'f'}, + {"LTRIM", 'f'}, + {"MAKEDATE", 'f'}, + {"MAKE_SET", 'f'}, + {"MASTER_BIND", 'k'}, + {"MASTER_POS_WAIT", 'f'}, + {"MASTER_SSL_VERIFY_SERVER_CERT", 'k'}, + {"MATCH", 'k'}, + {"MAX", 'f'}, + {"MAXVALUE", 'k'}, + {"MD5", 'f'}, + {"MEDIUMBLOB", 'k'}, + {"MEDIUMINT", 'k'}, + {"MEDIUMTEXT", 'k'}, + {"MERGE", 'k'}, + {"MICROSECOND", 'f'}, + {"MID", 'f'}, + {"MIDDLEINT", 'k'}, + {"MIN", 'f'}, + {"MINUTE", 'f'}, + {"MINUTE_MICROSECOND", 'k'}, + {"MINUTE_SECOND", 'k'}, + {"MOD", 'o'}, + {"MODE", 'n'}, + {"MODIFIES", 'k'}, + {"MONTH", 'f'}, + {"MONTHNAME", 'f'}, + {"NAME_CONST", 'f'}, + {"NOT", 'o'}, + {"NOW", 'f'}, + {"NO_WRITE_TO_BINLOG", 'k'}, + {"NULL", '1'}, + {"NULLIF", 'f'}, + {"NUMERIC", 'k'}, + {"OCT", 'f'}, + {"OCTET_LENGTH", 'f'}, + {"OFFSET", 'k'}, + {"OLD_PASSWORD", 'f'}, + {"ONE_SHOT", 'k'}, + {"OPEN", 'k'}, + {"OPENDATASOURCE", 'f'}, + {"OPENQUERY", 'f'}, + {"OPENROWSET", 'f'}, + {"OPENXML", 'f'}, + {"OPTIMIZE", 'k'}, + {"OPTION", 'k'}, + {"OPTIONALLY", 'k'}, + {"OR", '&'}, + {"ORD", 'f'}, + {"ORDER", 'n'}, + {"OUT", 'k'}, + {"OUTFILE", 'k'}, + {"OWN3D", 'k'}, + {"PARTITION", 'k'}, + {"PASSWORD", 'k'}, + {"PERIOD_ADD", 'f'}, + {"PERIOID_DIFF", 'f'}, + {"PG_ADVISORY_LOCK", 'f'}, + {"PG_SLEEP", 'f'}, + {"PI", 'f'}, + {"POSITION", 'f'}, + {"POW", 'f'}, + {"POWER", 'f'}, + {"PRECISION", 'k'}, + {"PRIMARY", 'k'}, + {"PROCEDURE", 'k'}, + {"PURGE", 'k'}, + {"QUARTER", 'f'}, + {"QUOTE", 'f'}, + {"RADIANS", 'f'}, + {"RAND", 'f'}, + {"RANDOMBLOB", 'f'}, + {"RANGE", 'k'}, + {"READ", 'k'}, + {"READS", 'k'}, + {"READ_WRITE", 'k'}, + {"REAL", 'n'}, + {"REFERENCES", 'k'}, + {"REGEXP", 'o'}, + {"RELEASE", 'k'}, + {"RELEASE_LOCK", 'f'}, + {"RENAME", 'k'}, + {"REPEAT", 'k'}, + {"REPLACE", 'k'}, + {"REQUIRE", 'k'}, + {"RESIGNAL", 'k'}, + {"RESTRICT", 'k'}, + {"RETURN", 'k'}, + {"REVERSE", 'f'}, + {"REVOKE", 'k'}, + {"RIGHT", 'n'}, + {"RLIKE", 'o'}, + {"ROUND", 'f'}, + {"ROW", 'f'}, + {"ROW_COUNT", 'f'}, + {"RPAD", 'f'}, + {"RTRIM", 'f'}, + {"SCHEMA", 'k'}, + {"SCHEMAS", 'k'}, + {"SECOND_MICROSECOND", 'k'}, + {"SEC_TO_TIME", 'f'}, + {"SELECT", 'k'}, + {"SENSITIVE", 'k'}, + {"SEPARATOR", 'k'}, + {"SESSION_USER", 'f'}, + {"SET", 'k'}, + {"SHA", 'f'}, + {"SHA1", 'f'}, + {"SHA2", 'f'}, + {"SHOW", 'n'}, + {"SHUTDOWN", 'k'}, + {"SIGN", 'f'}, + {"SIGNAL", 'k'}, + {"SIMILAR", 'k'}, + {"SIN", 'f'}, + {"SLEEP", 'f'}, + {"SMALLINT", 'k'}, + {"SOUNDEX", 'f'}, + {"SOUNDS", 'o'}, + {"SPACE", 'f'}, + {"SPATIAL", 'k'}, + {"SPECIFIC", 'k'}, + {"SQL", 'k'}, + {"SQLEXCEPTION", 'k'}, + {"SQLSTATE", 'k'}, + {"SQLWARNING", 'k'}, + {"SQL_BIG_RESULT", 'k'}, + {"SQL_CALC_FOUND_ROWS", 'k'}, + {"SQL_SMALL_RESULT", 'k'}, + {"SQRT", 'f'}, + {"SSL", 'k'}, + {"STARTING", 'k'}, + {"STDDEV", 'f'}, + {"STDDEV_POP", 'f'}, + {"STDDEV_SAMP", 'f'}, + {"STRAIGHT_JOIN", 'k'}, + {"STRCMP", 'f'}, + {"STR_TO_DATE", 'f'}, + {"SUBDATE", 'f'}, + {"SUBSTR", 'f'}, + {"SUBSTRING", 'f'}, + {"SUBSTRING_INDEX", 'f'}, + {"SUBTIME", 'f'}, + {"SUM", 'f'}, + {"SYS.STRAGG", 'f'}, + {"SYSCOLUMNS", 'k'}, + {"SYSDATE", 'f'}, + {"SYSOBJECTS", 'k'}, + {"SYSTEM_USER", 'f'}, + {"SYSUSERS", 'k'}, + {"TABLE", 'k'}, + {"TAN", 'f'}, + {"TERMINATED", 'k'}, + {"THEN", 'k'}, + {"TIME", 'k'}, + {"TIMEDIFF", 'f'}, + {"TIMESTAMP", 'f'}, + {"TIMESTAMPADD", 'f'}, + {"TIME_FORMAT", 'f'}, + {"TIME_TO_SEC", 'f'}, + {"TINYBLOB", 'k'}, + {"TINYINT", 'k'}, + {"TINYTEXT", 'k'}, + {"TOP", 'k'}, + {"TO_CHAR", 'f'}, + {"TO_DAYS", 'f'}, + {"TO_SECONDS", 'f'}, + {"TRAILING", 'n'}, + {"TRIGGER", 'k'}, + {"TRIM", 'f'}, + {"TRUE", '1'}, + {"TRUNCATE", 'f'}, + {"UCASE", 'f'}, + {"UNCOMPRESS", 'f'}, + {"UNCOMPRESS_LENGTH", 'f'}, + {"UNDO", 'k'}, + {"UNHEX", 'f'}, + {"UNION", 'U'}, + {"UNIQUE", 'n'}, + {"UNIX_TIMESTAMP", 'f'}, + {"UNI_ON", 'U'}, + {"UNLOCK", 'k'}, + {"UNSIGNED", 'k'}, + {"UPDATE", 'k'}, + {"UPDATEXML", 'f'}, + {"UPPER", 'f'}, + {"USAGE", 'k'}, + {"USE", 'k'}, + {"USING", 'f'}, + {"UTC_DATE", 'k'}, + {"UTC_TIME", 'k'}, + {"UTC_TIMESTAMP", 'k'}, + {"UTL_INADDR.GET_HOST_ADDRESS", 'f'}, + {"UUID", 'f'}, + {"UUID_SHORT", 'f'}, + {"VALUES", 'k'}, + {"VARBINARY", 'k'}, + {"VARCHAR", 'k'}, + {"VARCHARACTER", 'k'}, + {"VARIANCE", 'f'}, + {"VARYING", 'k'}, + {"VAR_POP", 'f'}, + {"VAR_SAMP", 'f'}, + {"VERSION", 'f'}, + {"WAITFOR", 'k'}, + {"WEEK", 'f'}, + {"WEEKDAY", 'f'}, + {"WEEKOFYEAR", 'f'}, + {"WHEN", 'k'}, + {"WHERE", 'k'}, + {"WHILE", 'k'}, + {"WITH", 'k'}, + {"XMLELEMENT", 'f'}, + {"XMLFOREST", 'f'}, + {"XMLFORMAT", 'f'}, + {"XMLTYPE", 'f'}, + {"XOR", 'o'}, + {"XP_EXECRESULTSET", 'k'}, + {"YEAR", 'f'}, + {"YEARWEEK", 'f'}, + {"YEAR_MONTH", 'k'}, + {"ZEROFILL", 'k'}, +}; +static const size_t sql_keywords_sz = 450; +static const char* multikeywords_start[] = { + "ALTER", + "CROSS", + "FULL", + "GROUP", + "IN", + "IN BOOLEAN", + "INTERSECT", + "IS", + "LEFT", + "LOCK", + "NATURAL", + "NOT", + "NOT SIMILAR", + "ORDER", + "OWN3D", + "READ", + "RIGHT", + "SELECT", + "SIMILAR", + "SOUNDS", + "UNION", +}; +static const size_t multikeywords_start_sz = 21; +static const keyword_t multikeywords[] = { + {"ALTER DOMAIN", 'k'}, + {"ALTER TABLE", 'k'}, + {"CROSS JOIN", 'k'}, + {"FULL OUTER", 'k'}, + {"GROUP BY", 'B'}, + {"IN BOOLEAN", 'n'}, + {"IN BOOLEAN MODE", 'k'}, + {"INTERSECT ALL", 'o'}, + {"IS NOT", 'o'}, + {"LEFT JOIN", 'k'}, + {"LEFT OUTER", 'k'}, + {"LOCK TABLE", 'k'}, + {"LOCK TABLES", 'k'}, + {"NATURAL FULL", 'k'}, + {"NATURAL INNER", 'k'}, + {"NATURAL JOIN", 'k'}, + {"NATURAL LEFT", 'k'}, + {"NATURAL OUTER", 'k'}, + {"NATURAL RIGHT", 'k'}, + {"NOT BETWEEN", 'o'}, + {"NOT IN", 'o'}, + {"NOT LIKE", 'o'}, + {"NOT REGEXP", 'o'}, + {"NOT RLIKE", 'o'}, + {"NOT SIMILAR", 'o'}, + {"NOT SIMILAR TO", 'o'}, + {"ORDER BY", 'B'}, + {"OWN3D BY", 'B'}, + {"READ WRITE", 'k'}, + {"RIGHT JOIN", 'k'}, + {"RIGHT OUTER", 'k'}, + {"SELECT ALL", 'k'}, + {"SIMILAR TO", 'o'}, + {"SOUNDS LIKE", 'o'}, + {"UNION ALL", 'U'}, +}; +static const size_t multikeywords_sz = 35; + +typedef size_t (*pt2Function)(sfilter *sf); +static const pt2Function char_parse_map[] = { + &parse_white, /* 0 */ + &parse_white, /* 1 */ + &parse_white, /* 2 */ + &parse_white, /* 3 */ + &parse_white, /* 4 */ + &parse_white, /* 5 */ + &parse_white, /* 6 */ + &parse_white, /* 7 */ + &parse_white, /* 8 */ + &parse_white, /* 9 */ + &parse_white, /* 10 */ + &parse_white, /* 11 */ + &parse_white, /* 12 */ + &parse_white, /* 13 */ + &parse_white, /* 14 */ + &parse_white, /* 15 */ + &parse_white, /* 16 */ + &parse_white, /* 17 */ + &parse_white, /* 18 */ + &parse_white, /* 19 */ + &parse_white, /* 20 */ + &parse_white, /* 21 */ + &parse_white, /* 22 */ + &parse_white, /* 23 */ + &parse_white, /* 24 */ + &parse_white, /* 25 */ + &parse_white, /* 26 */ + &parse_white, /* 27 */ + &parse_white, /* 28 */ + &parse_white, /* 29 */ + &parse_white, /* 30 */ + &parse_white, /* 31 */ + &parse_white, /* 32 */ + &parse_operator2, /* 33 */ + &parse_string, /* 34 */ + &parse_eol_comment, /* 35 */ + &parse_white, /* 36 */ + &parse_operator1, /* 37 */ + &parse_operator2, /* 38 */ + &parse_string, /* 39 */ + &parse_char, /* 40 */ + &parse_char, /* 41 */ + &parse_operator2, /* 42 */ + &parse_operator1, /* 43 */ + &parse_char, /* 44 */ + &parse_dash, /* 45 */ + &parse_number, /* 46 */ + &parse_slash, /* 47 */ + &parse_number, /* 48 */ + &parse_number, /* 49 */ + &parse_number, /* 50 */ + &parse_number, /* 51 */ + &parse_number, /* 52 */ + &parse_number, /* 53 */ + &parse_number, /* 54 */ + &parse_number, /* 55 */ + &parse_number, /* 56 */ + &parse_number, /* 57 */ + &parse_char, /* 58 */ + &parse_char, /* 59 */ + &parse_operator2, /* 60 */ + &parse_operator2, /* 61 */ + &parse_operator2, /* 62 */ + &parse_other, /* 63 */ + &parse_var, /* 64 */ + &parse_word, /* 65 */ + &parse_word, /* 66 */ + &parse_word, /* 67 */ + &parse_word, /* 68 */ + &parse_word, /* 69 */ + &parse_word, /* 70 */ + &parse_word, /* 71 */ + &parse_word, /* 72 */ + &parse_word, /* 73 */ + &parse_word, /* 74 */ + &parse_word, /* 75 */ + &parse_word, /* 76 */ + &parse_word, /* 77 */ + &parse_word, /* 78 */ + &parse_word, /* 79 */ + &parse_word, /* 80 */ + &parse_word, /* 81 */ + &parse_word, /* 82 */ + &parse_word, /* 83 */ + &parse_word, /* 84 */ + &parse_word, /* 85 */ + &parse_word, /* 86 */ + &parse_word, /* 87 */ + &parse_word, /* 88 */ + &parse_word, /* 89 */ + &parse_word, /* 90 */ + &parse_other, /* 91 */ + &parse_backslash, /* 92 */ + &parse_other, /* 93 */ + &parse_operator1, /* 94 */ + &parse_word, /* 95 */ + &parse_word, /* 96 */ + &parse_word, /* 97 */ + &parse_word, /* 98 */ + &parse_word, /* 99 */ + &parse_word, /* 100 */ + &parse_word, /* 101 */ + &parse_word, /* 102 */ + &parse_word, /* 103 */ + &parse_word, /* 104 */ + &parse_word, /* 105 */ + &parse_word, /* 106 */ + &parse_word, /* 107 */ + &parse_word, /* 108 */ + &parse_word, /* 109 */ + &parse_word, /* 110 */ + &parse_word, /* 111 */ + &parse_word, /* 112 */ + &parse_word, /* 113 */ + &parse_word, /* 114 */ + &parse_word, /* 115 */ + &parse_word, /* 116 */ + &parse_word, /* 117 */ + &parse_word, /* 118 */ + &parse_word, /* 119 */ + &parse_word, /* 120 */ + &parse_word, /* 121 */ + &parse_word, /* 122 */ + &parse_other, /* 123 */ + &parse_operator2, /* 124 */ + &parse_other, /* 125 */ + &parse_operator1, /* 126 */ + &parse_white, /* 127 */ +}; + +#endif diff --git a/apache2/libinjection/sqlparse_private.h b/apache2/libinjection/sqlparse_private.h index df10b020..0d16c033 100644 --- a/apache2/libinjection/sqlparse_private.h +++ b/apache2/libinjection/sqlparse_private.h @@ -1,869 +1,109 @@ - - - - - - - - - ModSecurity/apache2/libinjection/sqlparse_private.h at da961d4c1535d2131c1733258b3f809feeabadf5 · client9/ModSecurity · GitHub - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - -
- -
- - - - - - - -
-
- -
-
-
- - - - - -

- public - - - / - ModSecurity - - forked from SpiderLabs/ModSecurity - -

-
- - - - -
- - - - - - -
- - -
- - - tree: - da961d4c15 - - -
- -
-
- Switch branches/tags - -
- -
-
- -
-
- -
-
- -
- -
- -
- - master -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
Nothing to show
-
- - -
-
- -
- - 2.7.3 -
-
- - 2.7.2 -
-
- - 2.7.1 -
-
- -
Nothing to show
- -
- -
-
-
- -
- - - -
- - - - - - - -
-
- -
- - - - - - - -
-
- - - - - - - - -
- Fetching contributors… - -
-

Octocat-spinner-32-eaf2f5

-

Cannot retrieve contributors at this time

-
-
- -
- -
-
- -
-
-
-
- - file - 110 lines (87 sloc) - 3.316 kb -
-
-
- Edit - Raw - Blame - History -
-
- -
-
- - - - - -
- 1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 - - -
/**
* Copyright 2012, Nick Galbreath
* nickg@client9.com
* BSD License - see COPYING.txt for details
*
* (setq-default indent-tabs-mode nil)
* (setq c-default-style "k&r"
* c-basic-offset 4)
* indent -kr -nut
*/
#ifndef _SQLPARSE_PRIVATE_H
#define _SQLPARSE_PRIVATE_H

#include "sqlparse.h"

#define CHAR_NULL '\0'
#define CHAR_SINGLE '\''
#define CHAR_DOUBLE '"'

/***
* The stdlib function 'strspn' assumes input to null-delimited.
* This allows us to specifying and input length and allows
* embedded nulls
*/
size_t strlenspn(const char *s, size_t len, const char *accept);

int streq(const char *a, const char *b);

void st_clear(stoken_t * st);
void st_assign_char(stoken_t * st, const char stype, const char value);
void st_set_type(stoken_t * st, const char stype);
void st_assign(stoken_t * st, const char stype, const char *value,
               size_t len);
void st_assign_cstr(stoken_t * st, const char stype, const char *value);
void st_copy(stoken_t * dest, const stoken_t * src);

int st_equals_cstr(const stoken_t * src, const char stype,
                    const char *value);

int st_is_empty(const stoken_t * st);
int st_is_arith_op(const stoken_t * st);
int st_is_unary_op(const stoken_t * st);
int st_is_english_op(const stoken_t * st);
int st_is_logical_op(const stoken_t * st);
int st_is_multiword_start(const stoken_t * st);

const char *bsearch_cstr(const char *key, const char *base[],
                         size_t nmemb);

typedef struct {
    const char *word;
    char type;
} keyword_t;

char bsearch_keyword_type(const char *key, const keyword_t keywords[],
                          size_t len);

int is_operator2(const char *key);

int is_sqli_pattern(const char *key);

size_t parse_none(sfilter * sf);
size_t parse_other(sfilter * sf);
size_t parse_white(sfilter * sf);
size_t parse_operator1(sfilter *sf);
size_t parse_char(sfilter *sf);
size_t parse_eol_comment(sfilter *sf);
size_t parse_dash(sfilter *sf);
size_t is_mysql_comment(const char *cs, const size_t len, size_t pos);
size_t parse_slash(sfilter *sf);
size_t parse_backslash(sfilter * sf);
size_t parse_operator2(sfilter *sf);
size_t parse_string_core(const char *cs, const size_t len, size_t pos,
                         stoken_t * st, char delim, size_t offset);
size_t parse_string(sfilter *sf);
size_t parse_word(sfilter * sf);
size_t parse_var(sfilter * sf);

size_t parse_number(sfilter * sf);

int parse_token(sfilter * sf);

/**
* Looks at syntax_last and syntax_current to see
* if they can be merged into a multi-keyword
*/
int syntax_merge_words(stoken_t * a, stoken_t * b);

void sfilter_reset(sfilter * sf, const char *s, size_t slen);

/**
* Takes a raw stream of SQL tokens and does the following:
* * Merge mutliple strings into one "foo", "bar" --> "foo bar"
* * Remove comments except last one 1, +, -- foo, 1 ->> 1,+,1
* * Merge multi-word keywords and operators into one
* e.g. "UNION", "ALL" --> "UNION ALL"
*/
int sqli_tokenize(sfilter * sf, stoken_t * sout);

int filter_fold(sfilter * sf, stoken_t * sout);

int is_string_sqli(sfilter * sql_state, const char *s, size_t slen,
                    const char delim,
                    ptr_fingerprints_fn fn);

int char2int(char c);
unsigned long long pat2int(const char *pat);

#endif /* _SQLPARSE_PRIVATE_H */
-
-
- -
-
- - - - -
-
-
- - - - -
-
-
-
- - -
- - - - - -
-
-
- -
-
-
-
-
-
- -
- - - -
- - Something went wrong with that request. Please try again. - -
- - - - - - - - +/** + * Copyright 2012, Nick Galbreath + * nickg@client9.com + * BSD License - see COPYING.txt for details + * + * (setq-default indent-tabs-mode nil) + * (setq c-default-style "k&r" + * c-basic-offset 4) + * indent -kr -nut + */ +#ifndef _SQLPARSE_PRIVATE_H +#define _SQLPARSE_PRIVATE_H + +#include "sqlparse.h" + +#define CHAR_NULL '\0' +#define CHAR_SINGLE '\'' +#define CHAR_DOUBLE '"' + +/*** + * The stdlib function 'strspn' assumes input to null-delimited. + * This allows us to specifying and input length and allows + * embedded nulls + */ +size_t strlenspn(const char *s, size_t len, const char *accept); + +int streq(const char *a, const char *b); + +void st_clear(stoken_t * st); +void st_assign_char(stoken_t * st, const char stype, const char value); +void st_set_type(stoken_t * st, const char stype); +void st_assign(stoken_t * st, const char stype, const char *value, + size_t len); +void st_assign_cstr(stoken_t * st, const char stype, const char *value); +void st_copy(stoken_t * dest, const stoken_t * src); + +int st_equals_cstr(const stoken_t * src, const char stype, + const char *value); + +int st_is_empty(const stoken_t * st); +int st_is_arith_op(const stoken_t * st); +int st_is_unary_op(const stoken_t * st); +int st_is_english_op(const stoken_t * st); +int st_is_logical_op(const stoken_t * st); +int st_is_multiword_start(const stoken_t * st); + +const char *bsearch_cstr(const char *key, const char *base[], + size_t nmemb); + +typedef struct { + const char *word; + char type; +} keyword_t; + +char bsearch_keyword_type(const char *key, const keyword_t keywords[], + size_t len); + +int is_operator2(const char *key); + +int is_sqli_pattern(const char *key); + +size_t parse_none(sfilter * sf); +size_t parse_other(sfilter * sf); +size_t parse_white(sfilter * sf); +size_t parse_operator1(sfilter *sf); +size_t parse_char(sfilter *sf); +size_t parse_eol_comment(sfilter *sf); +size_t parse_dash(sfilter *sf); +size_t is_mysql_comment(const char *cs, const size_t len, size_t pos); +size_t parse_slash(sfilter *sf); +size_t parse_backslash(sfilter * sf); +size_t parse_operator2(sfilter *sf); +size_t parse_string_core(const char *cs, const size_t len, size_t pos, + stoken_t * st, char delim, size_t offset); +size_t parse_string(sfilter *sf); +size_t parse_word(sfilter * sf); +size_t parse_var(sfilter * sf); + +size_t parse_number(sfilter * sf); + +int parse_token(sfilter * sf); + +/** + * Looks at syntax_last and syntax_current to see + * if they can be merged into a multi-keyword + */ +int syntax_merge_words(stoken_t * a, stoken_t * b); + +void sfilter_reset(sfilter * sf, const char *s, size_t slen); + +/** + * Takes a raw stream of SQL tokens and does the following: + * * Merge mutliple strings into one "foo", "bar" --> "foo bar" + * * Remove comments except last one 1, +, -- foo, 1 ->> 1,+,1 + * * Merge multi-word keywords and operators into one + * e.g. "UNION", "ALL" --> "UNION ALL" + */ +int sqli_tokenize(sfilter * sf, stoken_t * sout); + +int filter_fold(sfilter * sf, stoken_t * sout); + +int is_string_sqli(sfilter * sql_state, const char *s, size_t slen, + const char delim, + ptr_fingerprints_fn fn); + +int char2int(char c); +unsigned long long pat2int(const char *pat); + +#endif /* _SQLPARSE_PRIVATE_H */