mirror of
https://github.com/zulip/zulip.git
synced 2025-11-04 14:03:30 +00:00
validator: Reject ISO 8601 dates missing leading zeros.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
committed by
Tim Abbott
parent
90354c4e5f
commit
2ab0b3d4fc
@@ -43,4 +43,4 @@ API_FEATURE_LEVEL = 35
|
|||||||
# historical commits sharing the same major version, in which case a
|
# historical commits sharing the same major version, in which case a
|
||||||
# minor version bump suffices.
|
# minor version bump suffices.
|
||||||
|
|
||||||
PROVISION_VERSION = '117.2'
|
PROVISION_VERSION = '117.3'
|
||||||
|
|||||||
@@ -92,7 +92,8 @@ def check_date(var_name: str, val: object) -> str:
|
|||||||
if not isinstance(val, str):
|
if not isinstance(val, str):
|
||||||
raise ValidationError(_('{var_name} is not a string').format(var_name=var_name))
|
raise ValidationError(_('{var_name} is not a string').format(var_name=var_name))
|
||||||
try:
|
try:
|
||||||
datetime.strptime(val, '%Y-%m-%d')
|
if datetime.strptime(val, '%Y-%m-%d').strftime('%Y-%m-%d') != val:
|
||||||
|
raise ValidationError(_('{var_name} is not a date').format(var_name=var_name))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise ValidationError(_('{var_name} is not a date').format(var_name=var_name))
|
raise ValidationError(_('{var_name} is not a date').format(var_name=var_name))
|
||||||
return val
|
return val
|
||||||
|
|||||||
27
zerver/migrations/0306_custom_profile_field_date_format.py
Normal file
27
zerver/migrations/0306_custom_profile_field_date_format.py
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
"""
|
||||||
|
We previously accepted invalid ISO 8601 dates like 1909-3-5 for
|
||||||
|
date values of custom profile fields. Correct them by adding the
|
||||||
|
missing leading zeros: 1909-03-05.
|
||||||
|
"""
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("zerver", "0305_realm_deactivated_redirect"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RunSQL(
|
||||||
|
sql="""\
|
||||||
|
UPDATE zerver_customprofilefieldvalue
|
||||||
|
SET value = to_char(to_date(value, 'YYYY-MM-DD'), 'YYYY-MM-DD')
|
||||||
|
FROM zerver_customprofilefield AS f
|
||||||
|
WHERE f.id = field_id
|
||||||
|
AND f.field_type = 4
|
||||||
|
AND value <> to_char(to_date(value, 'YYYY-MM-DD'), 'YYYY-MM-DD');
|
||||||
|
""",
|
||||||
|
reverse_sql="",
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -4133,7 +4133,7 @@ paths:
|
|||||||
"value": "I am:\n* The prince of Denmark\n* Nephew to the usurping Claudius",
|
"value": "I am:\n* The prince of Denmark\n* Nephew to the usurping Claudius",
|
||||||
"rendered_value": "<p>I am:</p>\n<ul>\n<li>The prince of Denmark</li>\n<li>Nephew to the usurping Claudius</li>\n</ul>",
|
"rendered_value": "<p>I am:</p>\n<ul>\n<li>The prince of Denmark</li>\n<li>Nephew to the usurping Claudius</li>\n</ul>",
|
||||||
},
|
},
|
||||||
"5": {"value": "1900-1-1"},
|
"5": {"value": "1900-01-01"},
|
||||||
"7": {"value": "[11]"},
|
"7": {"value": "[11]"},
|
||||||
"6": {"value": "https://blog.zulig.org"},
|
"6": {"value": "https://blog.zulig.org"},
|
||||||
"1":
|
"1":
|
||||||
@@ -4488,7 +4488,7 @@ paths:
|
|||||||
"user_id": 5,
|
"user_id": 5,
|
||||||
"profile_data":
|
"profile_data":
|
||||||
{
|
{
|
||||||
"5": {"value": "2000-1-1"},
|
"5": {"value": "2000-01-01"},
|
||||||
"4": {"value": "emacs"},
|
"4": {"value": "emacs"},
|
||||||
"7": {"value": "[10]"},
|
"7": {"value": "[10]"},
|
||||||
"1":
|
"1":
|
||||||
@@ -5538,7 +5538,7 @@ paths:
|
|||||||
"value": "I am:\n* The prince of Denmark\n* Nephew to the usurping Claudius",
|
"value": "I am:\n* The prince of Denmark\n* Nephew to the usurping Claudius",
|
||||||
"rendered_value": "<p>I am:</p>\n<ul>\n<li>The prince of Denmark</li>\n<li>Nephew to the usurping Claudius</li>\n</ul>",
|
"rendered_value": "<p>I am:</p>\n<ul>\n<li>The prince of Denmark</li>\n<li>Nephew to the usurping Claudius</li>\n</ul>",
|
||||||
},
|
},
|
||||||
"5": {"value": "1900-1-1"},
|
"5": {"value": "1900-01-01"},
|
||||||
"7": {"value": "[11]"},
|
"7": {"value": "[11]"},
|
||||||
"6": {"value": "https://blog.zulig.org"},
|
"6": {"value": "https://blog.zulig.org"},
|
||||||
"1":
|
"1":
|
||||||
|
|||||||
@@ -504,6 +504,8 @@ class UpdateCustomProfileFieldTest(CustomProfileFieldTestCase):
|
|||||||
field_name = "Birthday"
|
field_name = "Birthday"
|
||||||
self.assert_error_update_invalid_value(field_name, "a-b-c",
|
self.assert_error_update_invalid_value(field_name, "a-b-c",
|
||||||
f"{field_name} is not a date")
|
f"{field_name} is not a date")
|
||||||
|
self.assert_error_update_invalid_value(field_name, "1909-3-5",
|
||||||
|
f"{field_name} is not a date")
|
||||||
self.assert_error_update_invalid_value(field_name, 123,
|
self.assert_error_update_invalid_value(field_name, 123,
|
||||||
f"{field_name} is not a string")
|
f"{field_name} is not a string")
|
||||||
|
|
||||||
@@ -526,7 +528,7 @@ class UpdateCustomProfileFieldTest(CustomProfileFieldTestCase):
|
|||||||
('Biography', '~~short~~ **long** text data'),
|
('Biography', '~~short~~ **long** text data'),
|
||||||
('Favorite food', 'long short text data'),
|
('Favorite food', 'long short text data'),
|
||||||
('Favorite editor', 'vim'),
|
('Favorite editor', 'vim'),
|
||||||
('Birthday', '1909-3-5'),
|
('Birthday', '1909-03-05'),
|
||||||
('Favorite website', 'https://zulip.com'),
|
('Favorite website', 'https://zulip.com'),
|
||||||
('Mentor', [self.example_user("cordelia").id]),
|
('Mentor', [self.example_user("cordelia").id]),
|
||||||
('GitHub', 'zulip-mobile'),
|
('GitHub', 'zulip-mobile'),
|
||||||
|
|||||||
@@ -598,7 +598,7 @@ class PermissionTest(ZulipTestCase):
|
|||||||
'Biography': 'long text data',
|
'Biography': 'long text data',
|
||||||
'Favorite food': 'short text data',
|
'Favorite food': 'short text data',
|
||||||
'Favorite editor': 'vim',
|
'Favorite editor': 'vim',
|
||||||
'Birthday': '1909-3-5',
|
'Birthday': '1909-03-05',
|
||||||
'Favorite website': 'https://zulip.com',
|
'Favorite website': 'https://zulip.com',
|
||||||
'Mentor': [cordelia.id],
|
'Mentor': [cordelia.id],
|
||||||
'GitHub': 'timabbott',
|
'GitHub': 'timabbott',
|
||||||
|
|||||||
@@ -505,7 +505,7 @@ class Command(BaseCommand):
|
|||||||
{"id": biography.id, "value": "Betrayer of Othello."},
|
{"id": biography.id, "value": "Betrayer of Othello."},
|
||||||
{"id": favorite_food.id, "value": "Apples"},
|
{"id": favorite_food.id, "value": "Apples"},
|
||||||
{"id": favorite_editor.id, "value": "emacs"},
|
{"id": favorite_editor.id, "value": "emacs"},
|
||||||
{"id": birthday.id, "value": "2000-1-1"},
|
{"id": birthday.id, "value": "2000-01-01"},
|
||||||
{"id": favorite_website.id, "value": "https://zulip.readthedocs.io/en/latest/"},
|
{"id": favorite_website.id, "value": "https://zulip.readthedocs.io/en/latest/"},
|
||||||
{"id": mentor.id, "value": [hamlet.id]},
|
{"id": mentor.id, "value": [hamlet.id]},
|
||||||
{"id": github_profile.id, "value": 'zulip'},
|
{"id": github_profile.id, "value": 'zulip'},
|
||||||
@@ -518,7 +518,7 @@ class Command(BaseCommand):
|
|||||||
},
|
},
|
||||||
{"id": favorite_food.id, "value": "Dark chocolate"},
|
{"id": favorite_food.id, "value": "Dark chocolate"},
|
||||||
{"id": favorite_editor.id, "value": "vim"},
|
{"id": favorite_editor.id, "value": "vim"},
|
||||||
{"id": birthday.id, "value": "1900-1-1"},
|
{"id": birthday.id, "value": "1900-01-01"},
|
||||||
{"id": favorite_website.id, "value": "https://blog.zulig.org"},
|
{"id": favorite_website.id, "value": "https://blog.zulig.org"},
|
||||||
{"id": mentor.id, "value": [iago.id]},
|
{"id": mentor.id, "value": [iago.id]},
|
||||||
{"id": github_profile.id, "value": 'zulipbot'},
|
{"id": github_profile.id, "value": 'zulipbot'},
|
||||||
|
|||||||
Reference in New Issue
Block a user