From 9cf718b8f6c2eba65715c50a99e3814c29e4c0ce Mon Sep 17 00:00:00 2001 From: Akhil Narang Date: Fri, 18 Apr 2025 15:09:42 +0530 Subject: [PATCH 1/2] fix(db_query): use `re.DOTALL` Signed-off-by: Akhil Narang --- frappe/model/db_query.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/model/db_query.py b/frappe/model/db_query.py index 2aa951ee9f..a020865e89 100644 --- a/frappe/model/db_query.py +++ b/frappe/model/db_query.py @@ -38,7 +38,7 @@ LOCATE_CAST_PATTERN = re.compile(r"locate\(([^,]+),\s*([`\"]?name[`\"]?)\s*\)", FUNC_IFNULL_PATTERN = re.compile(r"(strpos|ifnull|coalesce)\(\s*[`\"]?name[`\"]?\s*,", flags=re.IGNORECASE) CAST_VARCHAR_PATTERN = re.compile(r"([`\"]?tab[\w`\" -]+\.[`\"]?name[`\"]?)(?!\w)", flags=re.IGNORECASE) ORDER_BY_PATTERN = re.compile(r"\ order\ by\ |\ asc|\ ASC|\ desc|\ DESC", flags=re.IGNORECASE) -SUB_QUERY_PATTERN = re.compile("^.*[,();@].*") +SUB_QUERY_PATTERN = re.compile("^.*[,();@].*", flags=re.DOTALL) IS_QUERY_PATTERN = re.compile(r"^(select|delete|update|drop|create)\s") IS_QUERY_PREDICATE_PATTERN = re.compile(r"\s*[0-9a-zA-z]*\s*( from | group by | order by | where | join )") FIELD_QUOTE_PATTERN = re.compile(r"[0-9a-zA-Z]+\s*'") From 7255c5fdf21f9ddf05b0e395d6f2c4bb5886e380 Mon Sep 17 00:00:00 2001 From: Akhil Narang Date: Fri, 18 Apr 2025 15:14:03 +0530 Subject: [PATCH 2/2] fix(db_query): improve subquery check Signed-off-by: Akhil Narang --- frappe/model/db_query.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/frappe/model/db_query.py b/frappe/model/db_query.py index a020865e89..9baec3e098 100644 --- a/frappe/model/db_query.py +++ b/frappe/model/db_query.py @@ -421,9 +421,11 @@ class DatabaseQuery: lower_field = field.lower().strip() if SUB_QUERY_PATTERN.match(field): - if lower_field[0] == "(": - subquery_token = lower_field[1:].lstrip().split(" ", 1)[0] - if subquery_token in blacklisted_keywords: + # Check for subquery anywhere in the field, not just at the beginning + if "(" in lower_field: + location = lower_field.index("(") + subquery_token = lower_field[location + 1 :].lstrip().split(" ", 1)[0] + if any(keyword in subquery_token for keyword in blacklisted_keywords): _raise_exception() function = lower_field.split("(", 1)[0].rstrip()