-
Notifications
You must be signed in to change notification settings - Fork 0
/
cinSolve.py
87 lines (68 loc) · 2.87 KB
/
cinSolve.py
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
# tokenizer, validateAgainstWhitelist and secureEval functions in this module written by https://github.com/Koenig-Heinrich-der-4te
import math
# this floods the namespace, I know, but this is intentional to allow expressions in /solve to not explicitly specify math.whatever()
from math import *
from cinIO import config, strings
from cinLogging import printHighlighted
from cinPalette import *
from cinShared import *
badParenthesisRegex = r"\(([ \t\n])*(-)*([ \t\n\d])*\)" # catches parenthesis that are empty, or contain only a number, including negative numbers
adminGuild = config["adminGuild"]
solveBlacklist = config["solveBlacklist"]
solveWhitelist = config["solveWhitelist"]
secureSolve = config["secureSolve"]
if secureSolve:
printHighlighted(f"{highlightedColor}using whitelist for /solve")
else:
printHighlighted(f"{highlightedColor}using (insecure) blacklist for /solve (ADMIN GUILD ONLY)")
def formatEvalResult(value):
return f"{value:,}"
tokenizer = re.compile("[\.,\(\)\*\/\+\-% ]|\d+|\w+")
def validateAgainstWhitelist(expression):
i = 0
while i < len(expression):
match = tokenizer.match(expression, i)
if match is None:
return False
token = match.group()
if token[0].isalpha() and token not in solveWhitelist:
return False
i = match.end()
return True
def secureEval(expression):
if validateAgainstWhitelist(expression):
try:
return formatEvalResult(eval(expression, globals(), vars(math)))
except Exception:
return strings['errors']['failedToResolveEval']
else:
return "Bad Math expression"
def validateAgainstBlacklist(expression):
# check if eval contains bad words OR parenthesis with only whitespace
containsBadParenthesis = re.findall(badParenthesisRegex, expression)
containsBadWords = containsAny(expression, solveBlacklist)
containsBadWords = containsBadWords or containsBadParenthesis
return not containsBadWords
def insecureEval(expression):
if validateAgainstBlacklist(expression):
try:
evalResult = formatEvalResult(eval(expression))
except Exception:
evalResult = strings['errors']['failedToResolveEval']
else:
evalResult = "fuck you. (noticed bad keywords in eval)"
return evalResult
async def solve(message, messageContent):
# default offsets are for /solve
myCharOffset = [7, 0]
if "cinnamon, eval(" in messageContent.lower():
myCharOffset = [15, 1]
textToEval = messageContent[myCharOffset[0]:len(messageContent) - myCharOffset[1]]
if secureSolve:
response = secureEval(textToEval)
else:
if adminGuild == message.guild.id:
response = insecureEval(textToEval)
else:
response = strings['errors']['guildIsNotAdminGuildMsg']
await message.channel.send(response)