Fix weird encoding of string parameters not using `str_validator`
See original GitHub issueSo, we have a substantial number of endpoints that use json_validator=check_string or variants for verifying string inputs. This is a very strange thing to do, since rather than requiring as intended that we get passed a string, we’re checking that we’re being passed effectively json.dumps(input_string). There’s two changes we want to make here:
- We should use
json_validator=check_stringshould be replaced with no parameter – the default behavior returns a string, andcheck_stringdoesn’t validate anything else. - For cases where we want to use
check_string_inor similar for additional validation, the right way to do that is via passingstr_validator.
Note that doing so changes the actual API – so we will need to update tests and the web frontend (and document the API change, at least if it’s an endpoint that we imagine documenting – corporate/ probably never will be, so we can skip that here).
This is a very approximate audit. I noticed this when merging API documentation for display settings; most other API endpoints with this bug are not yet documented.
$ git grep 'json_validator=check_string'
corporate/views.py: billing_modality: str = REQ(json_validator=check_string),
corporate/views.py: schedule: str = REQ(json_validator=check_string),
corporate/views.py: license_management: Optional[str] = REQ(json_validator=check_string, default=None),
corporate/views.py: stripe_token: Optional[str] = REQ(json_validator=check_string, default=None),
corporate/views.py: signed_seat_count: str = REQ(json_validator=check_string),
corporate/views.py: salt: str = REQ(json_validator=check_string),
corporate/views.py: organization_type: str = REQ("organization-type", json_validator=check_string),
corporate/views.py: website: str = REQ("website", json_validator=check_string),
corporate/views.py: description: str = REQ("description", json_validator=check_string),
corporate/views.py: stripe_token: str = REQ("stripe_token", json_validator=check_string),
docs/tutorials/new-feature-tutorial.md: name: Optional[str] = REQ(json_validator=check_string, default=None),
docs/tutorials/writing-views.md: name: Optional[str]=REQ(json_validator=check_string, default=None),
zerver/views/hotspots.py: request: HttpRequest, user: UserProfile, hotspot: str = REQ(json_validator=check_string)
zerver/views/realm.py: name: Optional[str] = REQ(json_validator=check_string, default=None),
zerver/views/realm.py: description: Optional[str] = REQ(json_validator=check_string, default=None),
zerver/views/realm.py: default_language: Optional[str] = REQ(json_validator=check_string, default=None),
zerver/views/realm.py: "message_retention_days", json_validator=check_string_or_int, default=None
zerver/views/realm.py: default_code_block_language: Optional[str] = REQ(json_validator=check_string, default=None),
zerver/views/realm_domains.py: domain: str = REQ(json_validator=check_string),
zerver/views/streams.py: new_group_name: Optional[str] = REQ(json_validator=check_string, default=None),
zerver/views/streams.py: new_description: Optional[str] = REQ(json_validator=check_string, default=None),
zerver/views/streams.py: new_name: Optional[str] = REQ(json_validator=check_string, default=None),
zerver/views/streams.py: json_validator=check_string_or_int, default=None
zerver/views/streams.py: json_validator=check_string_or_int, default=RETENTION_DEFAULT
zerver/views/tutorial.py: request: HttpRequest, user_profile: UserProfile, status: str = REQ(json_validator=check_string)
zerver/views/user_settings.py: default_language: Optional[str] = REQ(json_validator=check_string, default=None),
zerver/views/user_settings.py: json_validator=check_string_in(default_view_options), default=None
zerver/views/user_settings.py: emojiset: Optional[str] = REQ(json_validator=check_string_in(emojiset_choices), default=None),
zerver/views/user_settings.py: json_validator=check_string_in(pytz.all_timezones_set), default=None
zerver/views/user_settings.py: notification_sound: Optional[str] = REQ(json_validator=check_string, default=None),
zerver/views/users.py: full_name: Optional[str] = REQ(default=None, json_validator=check_string),
zerver/views/video_calls.py: meeting_id: str = REQ(json_validator=check_string),
zerver/views/video_calls.py: password: str = REQ(json_validator=check_string),
zerver/views/video_calls.py: checksum: str = REQ(json_validator=check_string),
Tagging as difficult because this will require a lot of attention to detail, careful testing, etc.
(Just updated to reflect that I expect we’ll merged #18036, so it’s now json_validator, not validator).
Issue Analytics
- State:
- Created 2 years ago
- Reactions:1
- Comments:7 (5 by maintainers)

Top Related StackOverflow Question
We can close this as resolved, since everything but the one item separately tracked in https://github.com/zulip/zulip/issues/18409 is complete. Thanks for doing this @ligmitz!
Yeah, will create an issue for
users.pyand open a pull request soon foruser_settings.py.