changeset 51719a6696d5 in trytond:default
details: https://hg.tryton.org/trytond?cmd=changeset&node=51719a6696d5
description:
Prevent assign SQL value to record instances
issue10413
review379441002
diffstat:
trytond/model/fields/field.py | 5 ++++
trytond/model/fields/many2one.py | 5 ++-
trytond/model/fields/multiselection.py | 9 +------
trytond/model/fields/reference.py | 5 +--
trytond/tests/test_field_binary.py | 10 +++++++++
trytond/tests/test_field_boolean.py | 10 +++++++++
trytond/tests/test_field_char.py | 36 +++++++++++++++++++++++++--------
trytond/tests/test_field_date.py | 10 +++++++++
trytond/tests/test_field_datetime.py | 10 +++++++++
trytond/tests/test_field_float.py | 10 +++++++++
trytond/tests/test_field_integer.py | 10 +++++++++
trytond/tests/test_field_numeric.py | 10 +++++++++
trytond/tests/test_field_time.py | 10 +++++++++
13 files changed, 119 insertions(+), 21 deletions(-)
diffs (319 lines):
diff -r caef4ed4b9ce -r 51719a6696d5 trytond/model/fields/field.py
--- a/trytond/model/fields/field.py Wed Oct 27 22:22:44 2021 +0200
+++ b/trytond/model/fields/field.py Thu Oct 28 09:00:33 2021 +0200
@@ -343,8 +343,13 @@
def __set__(self, inst, value):
assert self.name is not None
+ if isinstance(value, (Query, Expression)):
+ raise ValueError("Can not assign SQL")
if inst._values is None:
inst._values = inst._record()
+ if (self._py_type and value is not None
+ and not isinstance(value, self._py_type)):
+ value = self._py_type(value)
inst._values[self.name] = value
def sql_format(self, value):
diff -r caef4ed4b9ce -r 51719a6696d5 trytond/model/fields/many2one.py
--- a/trytond/model/fields/many2one.py Wed Oct 27 22:22:44 2021 +0200
+++ b/trytond/model/fields/many2one.py Thu Oct 28 09:00:33 2021 +0200
@@ -1,6 +1,6 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
-from sql import Literal, Column, With
+from sql import Literal, Column, With, Query, Expression
from sql.aggregate import Max
from sql.conditionals import Coalesce
from sql.operators import Or
@@ -19,7 +19,6 @@
'''
_type = 'many2one'
_sql_type = 'INTEGER'
- _py_type = int
def __init__(self, model_name, string='', left=None, right=None, path=None,
ondelete='SET NULL', datetime_field=None, target_search='join',
@@ -115,6 +114,8 @@
def sql_format(self, value):
assert value is not False
+ if value and not isinstance(value, (Query, Expression)):
+ value = int(value)
return super().sql_format(value)
def convert_domain_path(self, domain, tables):
diff -r caef4ed4b9ce -r 51719a6696d5 trytond/model/fields/multiselection.py
--- a/trytond/model/fields/multiselection.py Wed Oct 27 22:22:44 2021 +0200
+++ b/trytond/model/fields/multiselection.py Thu Oct 28 09:00:33 2021 +0200
@@ -18,7 +18,7 @@
"Define a multi-selection field."
_type = 'multiselection'
_sql_type = 'VARCHAR'
- _py_type = list
+ _py_type = tuple
def __init__(self, selection, string='', sort=True, translate=True,
help='', help_selection=None, required=False, readonly=False,
@@ -66,15 +66,10 @@
def sql_format(self, value):
value = super().sql_format(value)
- if isinstance(value, list):
+ if isinstance(value, (list, tuple)):
value = dumps(sorted(set(value)))
return value
- def __set__(self, inst, value):
- if value:
- value = tuple(value)
- super().__set__(inst, value)
-
def _domain_column(self, operator, column):
database = Transaction().database
return database.json_get(super()._domain_column(operator, column))
diff -r caef4ed4b9ce -r 51719a6696d5 trytond/model/fields/reference.py
--- a/trytond/model/fields/reference.py Wed Oct 27 22:22:44 2021 +0200
+++ b/trytond/model/fields/reference.py Thu Oct 28 09:00:33 2021 +0200
@@ -20,7 +20,6 @@
'''
_type = 'reference'
_sql_type = 'VARCHAR'
- _py_type = str
def __init__(self, string='', selection=None, sort=True,
selection_change_with=None, translate=True, search_order=None,
@@ -159,11 +158,11 @@
super(Reference, self).__set__(inst, value)
def sql_format(self, value):
- if not isinstance(value, (str, Query, Expression)):
+ if value and not isinstance(value, (str, Query, Expression)):
try:
value = '%s,%s' % tuple(value)
except TypeError:
- pass
+ value = str(value)
return super(Reference, self).sql_format(value)
@with_inactive_records
diff -r caef4ed4b9ce -r 51719a6696d5 trytond/tests/test_field_binary.py
--- a/trytond/tests/test_field_binary.py Wed Oct 27 22:22:44 2021 +0200
+++ b/trytond/tests/test_field_binary.py Thu Oct 28 09:00:33 2021 +0200
@@ -124,6 +124,16 @@
self.assertEqual(binary.binary, cast(b'foo'))
@with_transaction()
+ def test_set_sql_value(self):
+ "Test cannot set SQL value"
+ Binary = Pool().get('test.binary')
+
+ binary = Binary()
+
+ with self.assertRaises(ValueError):
+ binary.binary = Literal('foo')
+
+ @with_transaction()
def test_read_size(self):
"Test read binary size"
Binary = Pool().get('test.binary')
diff -r caef4ed4b9ce -r 51719a6696d5 trytond/tests/test_field_boolean.py
--- a/trytond/tests/test_field_boolean.py Wed Oct 27 22:22:44 2021 +0200
+++ b/trytond/tests/test_field_boolean.py Thu Oct 28 09:00:33 2021 +0200
@@ -60,6 +60,16 @@
self.assertEqual(boolean.boolean, True)
@with_transaction()
+ def test_set_sql_value(self):
+ "Test cannot set SQL value"
+ Boolean = Pool().get('test.boolean')
+
+ boolean = Boolean()
+
+ with self.assertRaises(ValueError):
+ boolean.boolean = Literal(True)
+
+ @with_transaction()
def test_search_equals_true(self):
"Test search boolean equals True"
Boolean = Pool().get('test.boolean')
diff -r caef4ed4b9ce -r 51719a6696d5 trytond/tests/test_field_char.py
--- a/trytond/tests/test_field_char.py Wed Oct 27 22:22:44 2021 +0200
+++ b/trytond/tests/test_field_char.py Thu Oct 28 09:00:33 2021 +0200
@@ -42,15 +42,6 @@
self.assertEqual(char.char, "é")
@with_transaction()
- def test_create_with_sql_value(self):
- "Test create with SQL value"
- Char = self.Char()
-
- char, = Char.create([{'char': Literal('Foo')}])
-
- self.assertEqual(char.char, "Foo")
-
- @with_transaction()
def test_search_equals(self):
"Test search char equals"
Char = self.Char()
@@ -344,6 +335,25 @@
return Pool().get('test.char')
@with_transaction()
+ def test_create_with_sql_value(self):
+ "Test create with SQL value"
+ Char = self.Char()
+
+ char, = Char.create([{'char': Literal('Foo')}])
+
+ self.assertEqual(char.char, "Foo")
+
+ @with_transaction()
+ def test_set_sql_value(self):
+ "Test cannot set SQL value"
+ Char = self.Char()
+
+ char = Char()
+
+ with self.assertRaises(ValueError):
+ char.char = Literal('Foo')
+
+ @with_transaction()
def test_create_without_default(self):
"Test create char without default"
Char = Pool().get('test.char')
@@ -477,6 +487,14 @@
return Pool().get('test.char_translate')
@with_transaction()
+ def test_create_with_sql_value(self):
+ "Test cannot create with SQL value"
+ Char = self.Char()
+
+ with self.assertRaises(ValueError):
+ Char.create([{'char': Literal('Foo')}])
+
+ @with_transaction()
def test_translation_default_language_cache(self):
"""Test set translation for default language does not fill
transactional
cache with former value"""
diff -r caef4ed4b9ce -r 51719a6696d5 trytond/tests/test_field_date.py
--- a/trytond/tests/test_field_date.py Wed Oct 27 22:22:44 2021 +0200
+++ b/trytond/tests/test_field_date.py Thu Oct 28 09:00:33 2021 +0200
@@ -88,6 +88,16 @@
self.assertTrue(date.date)
@with_transaction()
+ def test_set_sql_value(self):
+ "Test cannot set SQL value"
+ Date = Pool().get('test.date')
+
+ date = Date()
+
+ with self.assertRaises(ValueError):
+ date.date = CurrentDate()
+
+ @with_transaction()
def test_create_non_date(self):
"Test create date with non date"
Date = Pool().get('test.date')
diff -r caef4ed4b9ce -r 51719a6696d5 trytond/tests/test_field_datetime.py
--- a/trytond/tests/test_field_datetime.py Wed Oct 27 22:22:44 2021 +0200
+++ b/trytond/tests/test_field_datetime.py Thu Oct 28 09:00:33 2021 +0200
@@ -88,6 +88,16 @@
self.assertTrue(datetime.datetime)
@with_transaction()
+ def test_set_sql_value(self):
+ "Test cannot set SQL value"
+ DateTime = Pool().get('test.datetime')
+
+ datetime = DateTime()
+
+ with self.assertRaises(ValueError):
+ datetime.datetime = CurrentTimestamp()
+
+ @with_transaction()
def test_create_non_datetime(self):
"Test create datetime with non datetime"
DateTime = Pool().get('test.datetime')
diff -r caef4ed4b9ce -r 51719a6696d5 trytond/tests/test_field_float.py
--- a/trytond/tests/test_field_float.py Wed Oct 27 22:22:44 2021 +0200
+++ b/trytond/tests/test_field_float.py Thu Oct 28 09:00:33 2021 +0200
@@ -70,6 +70,16 @@
self.assertEqual(float_.float, 2.5)
@with_transaction()
+ def test_set_sql_value(self):
+ "Test cannot set SQL value"
+ Float = Pool().get('test.float')
+
+ float_ = Float()
+
+ with self.assertRaises(ValueError):
+ float_.float = Literal(42)
+
+ @with_transaction()
def test_create_non_float(self):
"Test create float with non float"
Float = Pool().get('test.float')
diff -r caef4ed4b9ce -r 51719a6696d5 trytond/tests/test_field_integer.py
--- a/trytond/tests/test_field_integer.py Wed Oct 27 22:22:44 2021 +0200
+++ b/trytond/tests/test_field_integer.py Thu Oct 28 09:00:33 2021 +0200
@@ -59,6 +59,16 @@
self.assertEqual(integer.integer, 5)
@with_transaction()
+ def test_set_sql_value(self):
+ "Test cannot set SQL value"
+ Integer = Pool().get('test.integer_default')
+
+ integer = Integer()
+
+ with self.assertRaises(ValueError):
+ integer.integer = Literal(42)
+
+ @with_transaction()
def test_create_non_integer(self):
"Test create integer with non integer"
Integer = Pool().get('test.integer')
diff -r caef4ed4b9ce -r 51719a6696d5 trytond/tests/test_field_numeric.py
--- a/trytond/tests/test_field_numeric.py Wed Oct 27 22:22:44 2021 +0200
+++ b/trytond/tests/test_field_numeric.py Thu Oct 28 09:00:33 2021 +0200
@@ -71,6 +71,16 @@
self.assertEqual(numeric.numeric, Decimal('2.5'))
@with_transaction()
+ def test_set_sql_value(self):
+ "Test cannot set SQL value"
+ Numeric = Pool().get('test.numeric')
+
+ numeric = Numeric()
+
+ with self.assertRaises(ValueError):
+ numeric.numeric = Literal(42)
+
+ @with_transaction()
def test_create_non_numeric(self):
"Test create numeric with non numeric"
Numeric = Pool().get('test.numeric')
diff -r caef4ed4b9ce -r 51719a6696d5 trytond/tests/test_field_time.py
--- a/trytond/tests/test_field_time.py Wed Oct 27 22:22:44 2021 +0200
+++ b/trytond/tests/test_field_time.py Thu Oct 28 09:00:33 2021 +0200
@@ -86,6 +86,16 @@
self.assertTrue(time.time)
@with_transaction()
+ def test_set_sql_value(self):
+ "Test cannot set SQL value"
+ Time = Pool().get('test.time')
+
+ time = Time()
+
+ with self.assertRaises(ValueError):
+ time.time = Time.time.sql_cast(CurrentTimestamp())
+
+ @with_transaction()
def test_create_non_time(self):
"Test create time with non time"
Time = Pool().get('test.time')