1# Copyright 2021 Google LLC 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14"""Defines an Invalid JWT Error.""" 15 16import json 17from typing import Any 18 19from tink.jwt import _jwt_error 20 21 22def json_dumps(json_data: Any) -> str: 23 return json.dumps(json_data, separators=(',', ':')) 24 25 26def _validate_str(value: str) -> None: 27 """Uses encode('utf8') to check if value is a valid string.""" 28 _ = value.encode('utf8') 29 30 31def _validate_value(value: Any) -> None: 32 """Validates strings in a JSON object value.""" 33 # We don't need to check strings inside dicts, because json.loads will call 34 # _dict_with_validation for these. 35 if isinstance(value, str): 36 _validate_str(value) 37 if isinstance(value, list): 38 for item in value: 39 if isinstance(item, str): 40 _validate_str(item) 41 42 43def _dict_with_validation(pairs): 44 """Validates pairs and returns a dict.""" 45 keys = set() 46 for key, value in pairs: 47 _validate_str(key) 48 if key in keys: 49 raise _jwt_error.JwtInvalidError( 50 'Failed to parse JSON string, duplicated key') 51 keys.add(key) 52 _validate_value(value) 53 return dict(pairs) 54 55 56def json_loads(json_text: str) -> Any: 57 """Does the same as json.loads, but with some additional validation.""" 58 try: 59 return json.loads(json_text, object_pairs_hook=_dict_with_validation) 60 except json.decoder.JSONDecodeError: 61 raise _jwt_error.JwtInvalidError('Failed to parse JSON string') 62 except RecursionError: 63 raise _jwt_error.JwtInvalidError( 64 'Failed to parse JSON string, too many recursions') 65 except UnicodeEncodeError: 66 raise _jwt_error.JwtInvalidError('invalid character') 67