1
0
mirror of https://github.com/django/django.git synced 2025-06-21 11:29:12 +00:00

Fixed #36152 -- Deprecated use of "%" in column aliases.

Unintentional support existed only on SQLite and Oracle.
This commit is contained in:
Jacob Walls 2025-02-17 19:27:21 -05:00 committed by Sarah Boyce
parent 56f468681a
commit 8ede411a81
4 changed files with 49 additions and 0 deletions

View File

@ -10,7 +10,9 @@ all about the internals of models in order to get the information it needs.
import copy
import difflib
import functools
import inspect
import sys
import warnings
from collections import Counter, namedtuple
from collections.abc import Iterator, Mapping
from itertools import chain, count, product
@ -42,12 +44,17 @@ from django.db.models.query_utils import (
from django.db.models.sql.constants import INNER, LOUTER, ORDER_DIR, SINGLE
from django.db.models.sql.datastructures import BaseTable, Empty, Join, MultiJoin
from django.db.models.sql.where import AND, OR, ExtraWhere, NothingNode, WhereNode
from django.utils.deprecation import RemovedInDjango70Warning
from django.utils.functional import cached_property
from django.utils.regex_helper import _lazy_re_compile
from django.utils.tree import Node
__all__ = ["Query", "RawQuery"]
# RemovedInDjango70Warning: When the deprecation ends, replace with:
# Quotation marks ('"`[]), whitespace characters, semicolons, percent signs
# or inline SQL comments are forbidden in column aliases.
# FORBIDDEN_ALIAS_PATTERN = _lazy_re_compile(r"['`\"\]\[;\s]|%|--|/\*|\*/")
# Quotation marks ('"`[]), whitespace characters, semicolons, or inline
# SQL comments are forbidden in column aliases.
FORBIDDEN_ALIAS_PATTERN = _lazy_re_compile(r"['`\"\]\[;\s]|--|/\*|\*/")
@ -1206,9 +1213,23 @@ class Query(BaseExpression):
return alias or seen[None]
def check_alias(self, alias):
# RemovedInDjango70Warning: When the deprecation ends, remove.
if "%" in alias:
if "aggregate" in {frame.function for frame in inspect.stack()}:
stacklevel = 5
else:
# annotate() and alias().
stacklevel = 6
warnings.warn(
"Using percent signs in a column alias is deprecated.",
stacklevel=stacklevel,
category=RemovedInDjango70Warning,
)
if FORBIDDEN_ALIAS_PATTERN.search(alias):
raise ValueError(
"Column aliases cannot contain whitespace characters, quotation marks, "
# RemovedInDjango70Warning: When the deprecation ends, replace with:
# "semicolons, percent signs, or SQL comments."
"semicolons, or SQL comments."
)

View File

@ -28,6 +28,9 @@ details on these changes.
* The ``URLIZE_ASSUME_HTTPS`` transitional setting will be removed.
* Using a percent sign in a column alias or annotation will raise
``ValueError``.
* Support for setting the ``ADMINS`` or ``MANAGERS`` settings to a list of
(name, address) tuples will be removed.

View File

@ -375,6 +375,8 @@ Miscellaneous
``per_page`` argument of :class:`django.core.paginator.Paginator` and
:class:`django.core.paginator.AsyncPaginator` is deprecated.
* Using a percent sign in a column alias or annotation is deprecated.
Features removed in 6.0
=======================

View File

@ -39,6 +39,7 @@ from django.db.models.functions import (
from django.db.models.sql.query import get_field_names_from_opts
from django.test import TestCase, skipUnlessDBFeature
from django.test.utils import register_lookup
from django.utils.deprecation import RemovedInDjango70Warning
from .models import (
Author,
@ -1157,6 +1158,11 @@ class NonAggregateAnnotationTestCase(TestCase):
def test_alias_sql_injection(self):
crafted_alias = """injected_name" from "annotations_book"; --"""
# RemovedInDjango70Warning: When the deprecation ends, replace with:
# msg = (
# "Column aliases cannot contain whitespace characters, quotation marks, "
# "semicolons, percent signs, or SQL comments."
# )
msg = (
"Column aliases cannot contain whitespace characters, quotation marks, "
"semicolons, or SQL comments."
@ -1176,10 +1182,17 @@ class NonAggregateAnnotationTestCase(TestCase):
"ali/*as",
"alias*/",
"alias;",
# RemovedInDjango70Warning: When the deprecation ends, add this case.
# "alias%",
# [] are used by MSSQL.
"alias[",
"alias]",
]
# RemovedInDjango70Warning: When the deprecation ends, replace with:
# msg = (
# "Column aliases cannot contain whitespace characters, quotation marks, "
# "semicolons, percent signs, or SQL comments."
# )
msg = (
"Column aliases cannot contain whitespace characters, quotation marks, "
"semicolons, or SQL comments."
@ -1189,6 +1202,11 @@ class NonAggregateAnnotationTestCase(TestCase):
with self.assertRaisesMessage(ValueError, msg):
Book.objects.annotate(**{crafted_alias: Value(1)})
def test_alias_containing_percent_sign_deprecation(self):
msg = "Using percent signs in a column alias is deprecated."
with self.assertRaisesMessage(RemovedInDjango70Warning, msg):
Book.objects.annotate(**{"alias%": Value(1)})
@skipUnless(connection.vendor == "postgresql", "PostgreSQL tests")
@skipUnlessDBFeature("supports_json_field")
def test_set_returning_functions(self):
@ -1476,6 +1494,11 @@ class AliasTests(TestCase):
def test_alias_sql_injection(self):
crafted_alias = """injected_name" from "annotations_book"; --"""
# RemovedInDjango70Warning: When the deprecation ends, replace with:
# msg = (
# "Column aliases cannot contain whitespace characters, quotation marks, "
# "semicolons, percent signs, or SQL comments."
# )
msg = (
"Column aliases cannot contain whitespace characters, quotation marks, "
"semicolons, or SQL comments."