Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
D
django
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
django
Commits
75c0d4ea
Kaydet (Commit)
75c0d4ea
authored
Nis 20, 2014
tarafından
Erik Romijn
Kaydeden (comit)
Tim Graham
Nis 21, 2014
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Fixed queries that may return unexpected results on MySQL due to typecasting.
This is a security fix; disclosure to follow shortly.
üst
c083e381
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
95 additions
and
2 deletions
+95
-2
__init__.py
django/db/models/fields/__init__.py
+15
-1
custom-model-fields.txt
docs/howto/custom-model-fields.txt
+11
-0
databases.txt
docs/ref/databases.txt
+16
-0
querysets.txt
docs/ref/models/querysets.txt
+10
-0
sql.txt
docs/topics/db/sql.txt
+10
-0
tests.py
tests/model_fields/tests.py
+33
-1
No files found.
django/db/models/fields/__init__.py
Dosyayı görüntüle @
75c0d4ea
...
@@ -1509,6 +1509,12 @@ class FilePathField(Field):
...
@@ -1509,6 +1509,12 @@ class FilePathField(Field):
del
kwargs
[
"max_length"
]
del
kwargs
[
"max_length"
]
return
name
,
path
,
args
,
kwargs
return
name
,
path
,
args
,
kwargs
def
get_prep_value
(
self
,
value
):
value
=
super
(
FilePathField
,
self
)
.
get_prep_value
(
value
)
if
value
is
None
:
return
None
return
six
.
text_type
(
value
)
def
formfield
(
self
,
**
kwargs
):
def
formfield
(
self
,
**
kwargs
):
defaults
=
{
defaults
=
{
'path'
:
self
.
path
,
'path'
:
self
.
path
,
...
@@ -1642,6 +1648,12 @@ class IPAddressField(Field):
...
@@ -1642,6 +1648,12 @@ class IPAddressField(Field):
del
kwargs
[
'max_length'
]
del
kwargs
[
'max_length'
]
return
name
,
path
,
args
,
kwargs
return
name
,
path
,
args
,
kwargs
def
get_prep_value
(
self
,
value
):
value
=
super
(
IPAddressField
,
self
)
.
get_prep_value
(
value
)
if
value
is
None
:
return
None
return
six
.
text_type
(
value
)
def
get_internal_type
(
self
):
def
get_internal_type
(
self
):
return
"IPAddressField"
return
"IPAddressField"
...
@@ -1711,12 +1723,14 @@ class GenericIPAddressField(Field):
...
@@ -1711,12 +1723,14 @@ class GenericIPAddressField(Field):
def
get_prep_value
(
self
,
value
):
def
get_prep_value
(
self
,
value
):
value
=
super
(
GenericIPAddressField
,
self
)
.
get_prep_value
(
value
)
value
=
super
(
GenericIPAddressField
,
self
)
.
get_prep_value
(
value
)
if
value
is
None
:
return
None
if
value
and
':'
in
value
:
if
value
and
':'
in
value
:
try
:
try
:
return
clean_ipv6_address
(
value
,
self
.
unpack_ipv4
)
return
clean_ipv6_address
(
value
,
self
.
unpack_ipv4
)
except
exceptions
.
ValidationError
:
except
exceptions
.
ValidationError
:
pass
pass
return
value
return
six
.
text_type
(
value
)
def
formfield
(
self
,
**
kwargs
):
def
formfield
(
self
,
**
kwargs
):
defaults
=
{
defaults
=
{
...
...
docs/howto/custom-model-fields.txt
Dosyayı görüntüle @
75c0d4ea
...
@@ -593,6 +593,17 @@ For example::
...
@@ -593,6 +593,17 @@ For example::
return ''.join([''.join(l) for l in (value.north,
return ''.join([''.join(l) for l in (value.north,
value.east, value.south, value.west)])
value.east, value.south, value.west)])
.. warning::
If your custom field uses the ``CHAR``, ``VARCHAR`` or ``TEXT``
types for MySQL, you must make sure that :meth:`.get_prep_value`
always returns a string type. MySQL performs flexible and unexpected
matching when a query is performed on these types and the provided
value is an integer, which can cause queries to include unexpected
objects in their results. This problem cannot occur if you always
return a string type from :meth:`.get_prep_value`.
Converting query values to database values
Converting query values to database values
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...
...
docs/ref/databases.txt
Dosyayı görüntüle @
75c0d4ea
...
@@ -507,6 +507,22 @@ MySQL does not support the ``NOWAIT`` option to the ``SELECT ... FOR UPDATE``
...
@@ -507,6 +507,22 @@ MySQL does not support the ``NOWAIT`` option to the ``SELECT ... FOR UPDATE``
statement. If ``select_for_update()`` is used with ``nowait=True`` then a
statement. If ``select_for_update()`` is used with ``nowait=True`` then a
``DatabaseError`` will be raised.
``DatabaseError`` will be raised.
Automatic typecasting can cause unexpected results
--------------------------------------------------
When performing a query on a string type, but with an integer value, MySQL will
coerce the types of all values in the table to an integer before performing the
comparison. If your table contains the values ``'abc'``, ``'def'`` and you
query for ``WHERE mycolumn=0``, both rows will match. Similarly, ``WHERE mycolumn=1``
will match the value ``'abc1'``. Therefore, string type fields included in Django
will always cast the value to a string before using it in a query.
If you implement custom model fields that inherit from :class:`~django.db.models.Field`
directly, are overriding :meth:`~django.db.models.Field.get_prep_value`, or use
:meth:`extra() <django.db.models.query.QuerySet.extra>` or
:meth:`raw() <django.db.models.Manager.raw>`, you should ensure that you
perform the appropriate typecasting.
.. _sqlite-notes:
.. _sqlite-notes:
SQLite notes
SQLite notes
...
...
docs/ref/models/querysets.txt
Dosyayı görüntüle @
75c0d4ea
...
@@ -1189,6 +1189,16 @@ of the arguments is required, but you should use at least one of them.
...
@@ -1189,6 +1189,16 @@ of the arguments is required, but you should use at least one of them.
Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
.. warning::
If you are performing queries on MySQL, note that MySQL's silent type coercion
may cause unexpected results when mixing types. If you query on a string
type column, but with an integer value, MySQL will coerce the types of all values
in the table to an integer before performing the comparison. For example, if your
table contains the values ``'abc'``, ``'def'`` and you query for ``WHERE mycolumn=0``,
both rows will match. To prevent this, perform the correct typecasting
before using the value in a query.
defer
defer
~~~~~
~~~~~
...
...
docs/topics/db/sql.txt
Dosyayı görüntüle @
75c0d4ea
...
@@ -66,6 +66,16 @@ options that make it very powerful.
...
@@ -66,6 +66,16 @@ options that make it very powerful.
database, but does nothing to enforce that. If the query does not
database, but does nothing to enforce that. If the query does not
return rows, a (possibly cryptic) error will result.
return rows, a (possibly cryptic) error will result.
.. warning::
If you are performing queries on MySQL, note that MySQL's silent type coercion
may cause unexpected results when mixing types. If you query on a string
type column, but with an integer value, MySQL will coerce the types of all values
in the table to an integer before performing the comparison. For example, if your
table contains the values ``'abc'``, ``'def'`` and you query for ``WHERE mycolumn=0``,
both rows will match. To prevent this, perform the correct typecasting
before using the value in a query.
Mapping query fields to model fields
Mapping query fields to model fields
------------------------------------
------------------------------------
...
...
tests/model_fields/tests.py
Dosyayı görüntüle @
75c0d4ea
...
@@ -673,12 +673,20 @@ class PromiseTest(test.TestCase):
...
@@ -673,12 +673,20 @@ class PromiseTest(test.TestCase):
self
.
assertIsInstance
(
self
.
assertIsInstance
(
CharField
()
.
get_prep_value
(
lazy_func
()),
CharField
()
.
get_prep_value
(
lazy_func
()),
six
.
text_type
)
six
.
text_type
)
lazy_func
=
lazy
(
lambda
:
0
,
int
)
self
.
assertIsInstance
(
CharField
()
.
get_prep_value
(
lazy_func
()),
six
.
text_type
)
def
test_CommaSeparatedIntegerField
(
self
):
def
test_CommaSeparatedIntegerField
(
self
):
lazy_func
=
lazy
(
lambda
:
'1,2'
,
six
.
text_type
)
lazy_func
=
lazy
(
lambda
:
'1,2'
,
six
.
text_type
)
self
.
assertIsInstance
(
self
.
assertIsInstance
(
CommaSeparatedIntegerField
()
.
get_prep_value
(
lazy_func
()),
CommaSeparatedIntegerField
()
.
get_prep_value
(
lazy_func
()),
six
.
text_type
)
six
.
text_type
)
lazy_func
=
lazy
(
lambda
:
0
,
int
)
self
.
assertIsInstance
(
CommaSeparatedIntegerField
()
.
get_prep_value
(
lazy_func
()),
six
.
text_type
)
def
test_DateField
(
self
):
def
test_DateField
(
self
):
lazy_func
=
lazy
(
lambda
:
datetime
.
date
.
today
(),
datetime
.
date
)
lazy_func
=
lazy
(
lambda
:
datetime
.
date
.
today
(),
datetime
.
date
)
...
@@ -709,12 +717,20 @@ class PromiseTest(test.TestCase):
...
@@ -709,12 +717,20 @@ class PromiseTest(test.TestCase):
self
.
assertIsInstance
(
self
.
assertIsInstance
(
FileField
()
.
get_prep_value
(
lazy_func
()),
FileField
()
.
get_prep_value
(
lazy_func
()),
six
.
text_type
)
six
.
text_type
)
lazy_func
=
lazy
(
lambda
:
0
,
int
)
self
.
assertIsInstance
(
FileField
()
.
get_prep_value
(
lazy_func
()),
six
.
text_type
)
def
test_FilePathField
(
self
):
def
test_FilePathField
(
self
):
lazy_func
=
lazy
(
lambda
:
'tests.py'
,
six
.
text_type
)
lazy_func
=
lazy
(
lambda
:
'tests.py'
,
six
.
text_type
)
self
.
assertIsInstance
(
self
.
assertIsInstance
(
FilePathField
()
.
get_prep_value
(
lazy_func
()),
FilePathField
()
.
get_prep_value
(
lazy_func
()),
six
.
text_type
)
six
.
text_type
)
lazy_func
=
lazy
(
lambda
:
0
,
int
)
self
.
assertIsInstance
(
FilePathField
()
.
get_prep_value
(
lazy_func
()),
six
.
text_type
)
def
test_FloatField
(
self
):
def
test_FloatField
(
self
):
lazy_func
=
lazy
(
lambda
:
1.2
,
float
)
lazy_func
=
lazy
(
lambda
:
1.2
,
float
)
...
@@ -735,9 +751,13 @@ class PromiseTest(test.TestCase):
...
@@ -735,9 +751,13 @@ class PromiseTest(test.TestCase):
int
)
int
)
def
test_IPAddressField
(
self
):
def
test_IPAddressField
(
self
):
lazy_func
=
lazy
(
lambda
:
'127.0.0.1'
,
six
.
text_type
)
with
warnings
.
catch_warnings
(
record
=
True
):
with
warnings
.
catch_warnings
(
record
=
True
):
warnings
.
simplefilter
(
"always"
)
warnings
.
simplefilter
(
"always"
)
lazy_func
=
lazy
(
lambda
:
'127.0.0.1'
,
six
.
text_type
)
self
.
assertIsInstance
(
IPAddressField
()
.
get_prep_value
(
lazy_func
()),
six
.
text_type
)
lazy_func
=
lazy
(
lambda
:
0
,
int
)
self
.
assertIsInstance
(
self
.
assertIsInstance
(
IPAddressField
()
.
get_prep_value
(
lazy_func
()),
IPAddressField
()
.
get_prep_value
(
lazy_func
()),
six
.
text_type
)
six
.
text_type
)
...
@@ -747,6 +767,10 @@ class PromiseTest(test.TestCase):
...
@@ -747,6 +767,10 @@ class PromiseTest(test.TestCase):
self
.
assertIsInstance
(
self
.
assertIsInstance
(
GenericIPAddressField
()
.
get_prep_value
(
lazy_func
()),
GenericIPAddressField
()
.
get_prep_value
(
lazy_func
()),
six
.
text_type
)
six
.
text_type
)
lazy_func
=
lazy
(
lambda
:
0
,
int
)
self
.
assertIsInstance
(
GenericIPAddressField
()
.
get_prep_value
(
lazy_func
()),
six
.
text_type
)
def
test_NullBooleanField
(
self
):
def
test_NullBooleanField
(
self
):
lazy_func
=
lazy
(
lambda
:
True
,
bool
)
lazy_func
=
lazy
(
lambda
:
True
,
bool
)
...
@@ -771,6 +795,10 @@ class PromiseTest(test.TestCase):
...
@@ -771,6 +795,10 @@ class PromiseTest(test.TestCase):
self
.
assertIsInstance
(
self
.
assertIsInstance
(
SlugField
()
.
get_prep_value
(
lazy_func
()),
SlugField
()
.
get_prep_value
(
lazy_func
()),
six
.
text_type
)
six
.
text_type
)
lazy_func
=
lazy
(
lambda
:
0
,
int
)
self
.
assertIsInstance
(
SlugField
()
.
get_prep_value
(
lazy_func
()),
six
.
text_type
)
def
test_SmallIntegerField
(
self
):
def
test_SmallIntegerField
(
self
):
lazy_func
=
lazy
(
lambda
:
1
,
int
)
lazy_func
=
lazy
(
lambda
:
1
,
int
)
...
@@ -783,6 +811,10 @@ class PromiseTest(test.TestCase):
...
@@ -783,6 +811,10 @@ class PromiseTest(test.TestCase):
self
.
assertIsInstance
(
self
.
assertIsInstance
(
TextField
()
.
get_prep_value
(
lazy_func
()),
TextField
()
.
get_prep_value
(
lazy_func
()),
six
.
text_type
)
six
.
text_type
)
lazy_func
=
lazy
(
lambda
:
0
,
int
)
self
.
assertIsInstance
(
TextField
()
.
get_prep_value
(
lazy_func
()),
six
.
text_type
)
def
test_TimeField
(
self
):
def
test_TimeField
(
self
):
lazy_func
=
lazy
(
lambda
:
datetime
.
datetime
.
now
()
.
time
(),
datetime
.
time
)
lazy_func
=
lazy
(
lambda
:
datetime
.
datetime
.
now
()
.
time
(),
datetime
.
time
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment