diff --git a/src/documents/serialisers.py b/src/documents/serialisers.py index 5c90c6f1c..5c71de9a9 100644 --- a/src/documents/serialisers.py +++ b/src/documents/serialisers.py @@ -18,6 +18,8 @@ from django.core.exceptions import ValidationError from django.core.validators import DecimalValidator from django.core.validators import EmailValidator from django.core.validators import MaxLengthValidator +from django.core.validators import MaxValueValidator +from django.core.validators import MinValueValidator from django.core.validators import RegexValidator from django.core.validators import integer_validator from django.db.models import Count @@ -875,6 +877,13 @@ class CustomFieldInstanceSerializer(serializers.ModelSerializer): uri_validator(data["value"]) elif field.data_type == CustomField.FieldDataType.INT: integer_validator(data["value"]) + try: + value_int = int(data["value"]) + except (TypeError, ValueError): + raise serializers.ValidationError("Enter a valid integer.") + # Keep values within the PostgreSQL integer range + MinValueValidator(-2147483648)(value_int) + MaxValueValidator(2147483647)(value_int) elif ( field.data_type == CustomField.FieldDataType.MONETARY and data["value"] != "" diff --git a/src/documents/tests/test_api_documents.py b/src/documents/tests/test_api_documents.py index 87190c23b..f40ef157f 100644 --- a/src/documents/tests/test_api_documents.py +++ b/src/documents/tests/test_api_documents.py @@ -1664,6 +1664,44 @@ class TestDocumentApi(DirectoriesMixin, DocumentConsumeDelayMixin, APITestCase): self.consume_file_mock.assert_not_called() + def test_patch_document_integer_custom_field_out_of_range(self): + """ + GIVEN: + - An integer custom field + - A document + WHEN: + - Patching the document with an integer value exceeding PostgreSQL's range + THEN: + - HTTP 400 is returned (validation catches the overflow) + - No custom field instance is created + """ + cf_int = CustomField.objects.create( + name="intfield", + data_type=CustomField.FieldDataType.INT, + ) + doc = Document.objects.create( + title="Doc", + checksum="123", + mime_type="application/pdf", + ) + + response = self.client.patch( + f"/api/documents/{doc.pk}/", + { + "custom_fields": [ + { + "field": cf_int.pk, + "value": 2**31, # overflow for PostgreSQL integer fields + }, + ], + }, + format="json", + ) + + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + self.assertIn("custom_fields", response.data) + self.assertEqual(CustomFieldInstance.objects.count(), 0) + def test_upload_with_webui_source(self): """ GIVEN: A document with a source file