fix: harden twenty four game submissions

This commit is contained in:
2026-08-09 03:30:31 +08:00
parent b1ac6cef86
commit ce7bed5f19
4 changed files with 90 additions and 3 deletions
+22 -2
View File
@@ -1,5 +1,6 @@
import ast
import secrets
import unicodedata
from collections import Counter
from fractions import Fraction
@@ -36,6 +37,18 @@ TWENTY_FOUR_PUZZLES = {
MathGameAttempt.Difficulty.HARD: [(1, 5, 5, 5), (3, 3, 7, 7), (5, 5, 7, 11)],
}
TWENTY_FOUR_SYMBOLS = str.maketrans(
{
"×": "*",
"·": "*",
"": "*",
"÷": "/",
"": "-",
"": "-",
"": "-",
}
)
def _grid_from_text(value):
return [[int(value[row * 9 + column]) for column in range(9)] for row in range(9)]
@@ -80,7 +93,10 @@ def start_game(user, kind, difficulty):
def _validate_twenty_four_expression(source, numbers):
source = str(source or "").strip()
source = unicodedata.normalize("NFKC", str(source or "")).translate(
TWENTY_FOUR_SYMBOLS
)
source = source.strip()
if not source or len(source) > 120:
raise ValidationError({"expression": "请输入不超过 120 个字符的表达式"})
try:
@@ -90,7 +106,11 @@ def _validate_twenty_four_expression(source, numbers):
used = []
def evaluate(node):
if isinstance(node, ast.Constant) and isinstance(node.value, int):
if (
isinstance(node, ast.Constant)
and isinstance(node.value, int)
and not isinstance(node.value, bool)
):
used.append(node.value)
return Fraction(node.value)
if isinstance(node, ast.BinOp) and isinstance(