mirror of
https://github.com/django/django.git
synced 2026-02-09 02:49:25 +08:00
[4.2.x] Refs CVE-2026-1312 -- Raised ValueError when FilteredRelation aliases contain periods.
This prevents failures at the database layer, given that aliases in the
ON clause are not quoted.
Systematically quoting aliases even in FilteredRelation is tracked in
https://code.djangoproject.com/ticket/36795.
Backport of 005d60d97c from main.
This commit is contained in:
@@ -1622,6 +1622,11 @@ class Query(BaseExpression):
|
||||
return target_clause
|
||||
|
||||
def add_filtered_relation(self, filtered_relation, alias):
|
||||
if "." in alias:
|
||||
raise ValueError(
|
||||
"FilteredRelation doesn't support aliases with periods "
|
||||
"(got %r)." % alias
|
||||
)
|
||||
self.check_alias(alias)
|
||||
filtered_relation.alias = alias
|
||||
lookups = dict(get_children_from_q(filtered_relation.condition))
|
||||
|
||||
@@ -211,6 +211,19 @@ class FilteredRelationTests(TestCase):
|
||||
str(queryset.query),
|
||||
)
|
||||
|
||||
def test_period_forbidden(self):
|
||||
msg = (
|
||||
"FilteredRelation doesn't support aliases with periods (got 'book.alice')."
|
||||
)
|
||||
with self.assertRaisesMessage(ValueError, msg):
|
||||
Author.objects.annotate(
|
||||
**{
|
||||
"book.alice": FilteredRelation(
|
||||
"book", condition=Q(book__title__iexact="poem by alice")
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
def test_multiple(self):
|
||||
qs = (
|
||||
Author.objects.annotate(
|
||||
|
||||
@@ -15,7 +15,6 @@ from django.db.models import (
|
||||
Value,
|
||||
)
|
||||
from django.db.models.functions import Length, Upper
|
||||
from django.db.utils import DatabaseError
|
||||
from django.test import TestCase
|
||||
|
||||
from .models import (
|
||||
@@ -408,13 +407,19 @@ class OrderingTests(TestCase):
|
||||
self.assertNotEqual(qs[0].headline, "Backdated")
|
||||
|
||||
relation = FilteredRelation("author")
|
||||
qs2 = Article.objects.annotate(**{crafted: relation}).order_by(crafted)
|
||||
with self.assertRaises(DatabaseError):
|
||||
msg = (
|
||||
"FilteredRelation doesn't support aliases with periods "
|
||||
"(got 'ordering_article.pub_date')."
|
||||
)
|
||||
with self.assertRaisesMessage(ValueError, msg):
|
||||
qs2 = Article.objects.annotate(**{crafted: relation}).order_by(crafted)
|
||||
# Before, unlike F(), which causes ordering expressions to be
|
||||
# replaced by ordinals like n in ORDER BY n, these were ordered by
|
||||
# pub_date instead of author.
|
||||
# The Article model orders by -pk, so sorting on author will place
|
||||
# first any article by author2 instead of the backdated one.
|
||||
# This assertion is reachable if FilteredRelation.__init__() starts
|
||||
# supporting periods in aliases in the future.
|
||||
self.assertNotEqual(qs2[0].headline, "Backdated")
|
||||
|
||||
def test_order_by_pk(self):
|
||||
|
||||
Reference in New Issue
Block a user