DynamoDB: put_item(): Improve type validation (#5654)
This commit is contained in:
parent
96b2eff1bc
commit
37845792d3
@ -332,3 +332,8 @@ class TransactWriteSingleOpException(MockValidationException):
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__(self.there_can_be_only_one)
|
super().__init__(self.there_can_be_only_one)
|
||||||
|
|
||||||
|
|
||||||
|
class SerializationException(DynamodbException):
|
||||||
|
def __init__(self, msg):
|
||||||
|
super().__init__(error_type="SerializationException", message=msg)
|
||||||
|
@ -33,6 +33,7 @@ from moto.dynamodb.exceptions import (
|
|||||||
MockValidationException,
|
MockValidationException,
|
||||||
InvalidConversion,
|
InvalidConversion,
|
||||||
TransactWriteSingleOpException,
|
TransactWriteSingleOpException,
|
||||||
|
SerializationException,
|
||||||
)
|
)
|
||||||
from moto.dynamodb.models.utilities import bytesize
|
from moto.dynamodb.models.utilities import bytesize
|
||||||
from moto.dynamodb.models.dynamo_type import DynamoType
|
from moto.dynamodb.models.dynamo_type import DynamoType
|
||||||
@ -658,6 +659,17 @@ class Table(CloudFormationModel):
|
|||||||
self._validate_item_types(value)
|
self._validate_item_types(value)
|
||||||
elif type(value) == int and key == "N":
|
elif type(value) == int and key == "N":
|
||||||
raise InvalidConversion
|
raise InvalidConversion
|
||||||
|
if key == "S":
|
||||||
|
# This scenario is usually caught by boto3, but the user can disable parameter validation
|
||||||
|
# Which is why we need to catch it 'server-side' as well
|
||||||
|
if type(value) == int:
|
||||||
|
raise SerializationException(
|
||||||
|
"NUMBER_VALUE cannot be converted to String"
|
||||||
|
)
|
||||||
|
if type(value) == dict:
|
||||||
|
raise SerializationException(
|
||||||
|
"Start of structure or map found where not expected"
|
||||||
|
)
|
||||||
|
|
||||||
def put_item(
|
def put_item(
|
||||||
self,
|
self,
|
||||||
@ -699,9 +711,8 @@ class Table(CloudFormationModel):
|
|||||||
actual_type=range_value.type,
|
actual_type=range_value.type,
|
||||||
)
|
)
|
||||||
|
|
||||||
self._validate_key_sizes(item_attrs)
|
|
||||||
|
|
||||||
self._validate_item_types(item_attrs)
|
self._validate_item_types(item_attrs)
|
||||||
|
self._validate_key_sizes(item_attrs)
|
||||||
|
|
||||||
if expected is None:
|
if expected is None:
|
||||||
expected = {}
|
expected = {}
|
||||||
|
@ -870,3 +870,29 @@ def test_update_primary_key():
|
|||||||
table.get_item(Key={"pk": "testchangepk"})["Item"].should.equal(
|
table.get_item(Key={"pk": "testchangepk"})["Item"].should.equal(
|
||||||
{"pk": "testchangepk"}
|
{"pk": "testchangepk"}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_dynamodb
|
||||||
|
def test_put_item__string_as_integer_value():
|
||||||
|
if settings.TEST_SERVER_MODE:
|
||||||
|
raise SkipTest("Unable to mock a session with Config in ServerMode")
|
||||||
|
session = botocore.session.Session()
|
||||||
|
config = botocore.client.Config(parameter_validation=False)
|
||||||
|
client = session.create_client("dynamodb", region_name="us-east-1", config=config)
|
||||||
|
client.create_table(
|
||||||
|
TableName="without_sk",
|
||||||
|
KeySchema=[{"AttributeName": "pk", "KeyType": "HASH"}],
|
||||||
|
AttributeDefinitions=[{"AttributeName": "pk", "AttributeType": "S"}],
|
||||||
|
ProvisionedThroughput={"ReadCapacityUnits": 10, "WriteCapacityUnits": 10},
|
||||||
|
)
|
||||||
|
with pytest.raises(ClientError) as exc:
|
||||||
|
client.put_item(TableName="without_sk", Item={"pk": {"S": 123}})
|
||||||
|
err = exc.value.response["Error"]
|
||||||
|
err["Code"].should.equal("SerializationException")
|
||||||
|
err["Message"].should.equal("NUMBER_VALUE cannot be converted to String")
|
||||||
|
|
||||||
|
with pytest.raises(ClientError) as exc:
|
||||||
|
client.put_item(TableName="without_sk", Item={"pk": {"S": {"S": "asdf"}}})
|
||||||
|
err = exc.value.response["Error"]
|
||||||
|
err["Code"].should.equal("SerializationException")
|
||||||
|
err["Message"].should.equal("Start of structure or map found where not expected")
|
||||||
|
Loading…
Reference in New Issue
Block a user