|
40 | 40 | from django.db.models.sql.datastructures import BaseTable, Empty, Join, MultiJoin
|
41 | 41 | from django.db.models.sql.where import AND, OR, ExtraWhere, NothingNode, WhereNode
|
42 | 42 | from django.utils.functional import cached_property
|
| 43 | +from django.utils.regex_helper import _lazy_re_compile |
43 | 44 | from django.utils.tree import Node
|
44 | 45 |
|
45 | 46 | __all__ = ["Query", "RawQuery"]
|
46 | 47 |
|
| 48 | +# Quotation marks ('"`[]), whitespace characters, semicolons, or inline |
| 49 | +# SQL comments are forbidden in column aliases. |
| 50 | +FORBIDDEN_ALIAS_PATTERN = _lazy_re_compile(r"['`\"\]\[;\s]|--|/\*|\*/") |
| 51 | + |
47 | 52 |
|
48 | 53 | def get_field_names_from_opts(opts):
|
49 | 54 | return set(
|
@@ -1077,8 +1082,16 @@ def join_parent_model(self, opts, model, alias, seen):
|
1077 | 1082 | alias = seen[int_model] = join_info.joins[-1]
|
1078 | 1083 | return alias or seen[None]
|
1079 | 1084 |
|
| 1085 | + def check_alias(self, alias): |
| 1086 | + if FORBIDDEN_ALIAS_PATTERN.search(alias): |
| 1087 | + raise ValueError( |
| 1088 | + "Column aliases cannot contain whitespace characters, quotation marks, " |
| 1089 | + "semicolons, or SQL comments." |
| 1090 | + ) |
| 1091 | + |
1080 | 1092 | def add_annotation(self, annotation, alias, is_summary=False, select=True):
|
1081 | 1093 | """Add a single annotation expression to the Query."""
|
| 1094 | + self.check_alias(alias) |
1082 | 1095 | annotation = annotation.resolve_expression(
|
1083 | 1096 | self, allow_joins=True, reuse=None, summarize=is_summary
|
1084 | 1097 | )
|
@@ -2234,6 +2247,7 @@ def add_extra(self, select, select_params, where, params, tables, order_by):
|
2234 | 2247 | else:
|
2235 | 2248 | param_iter = iter([])
|
2236 | 2249 | for name, entry in select.items():
|
| 2250 | + self.check_alias(name) |
2237 | 2251 | entry = str(entry)
|
2238 | 2252 | entry_params = []
|
2239 | 2253 | pos = entry.find("%s")
|
|
0 commit comments