From bd562dd5c7178ef4f0d4fb862a74d9f1fef4aed4 Mon Sep 17 00:00:00 2001 From: Martin Hauser Date: Tue, 14 Jul 2026 18:25:56 +0200 Subject: [PATCH] Fixes #22662: Fix database overflow when saving Cables with large lengths (#22668) --- .../0238_alter_cable__abs_length.py | 16 +++++++++++ netbox/dcim/models/cables.py | 2 +- netbox/dcim/tests/test_models.py | 28 +++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 netbox/dcim/migrations/0238_alter_cable__abs_length.py diff --git a/netbox/dcim/migrations/0238_alter_cable__abs_length.py b/netbox/dcim/migrations/0238_alter_cable__abs_length.py new file mode 100644 index 000000000..f963e400c --- /dev/null +++ b/netbox/dcim/migrations/0238_alter_cable__abs_length.py @@ -0,0 +1,16 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0237_module_remove_local_context_data'), + ] + + operations = [ + migrations.AlterField( + model_name='cable', + name='_abs_length', + field=models.DecimalField(blank=True, decimal_places=4, max_digits=14, null=True), + ), + ] diff --git a/netbox/dcim/models/cables.py b/netbox/dcim/models/cables.py index a7d1e366b..d30801ed3 100644 --- a/netbox/dcim/models/cables.py +++ b/netbox/dcim/models/cables.py @@ -133,7 +133,7 @@ class Cable(PrimaryModel): ) # Stores the normalized length (in meters) for database ordering _abs_length = models.DecimalField( - max_digits=10, + max_digits=14, decimal_places=4, blank=True, null=True diff --git a/netbox/dcim/tests/test_models.py b/netbox/dcim/tests/test_models.py index 6f8139835..c09adc337 100644 --- a/netbox/dcim/tests/test_models.py +++ b/netbox/dcim/tests/test_models.py @@ -1,3 +1,5 @@ +from decimal import Decimal + from django.core.exceptions import ValidationError from django.db.models.signals import post_save from django.test import TestCase, tag @@ -2227,6 +2229,32 @@ class CableTestCase(TestCase): interface = Interface(device=device, name='tmp', cable=cable) self.assertIsNone(interface.path) + def test_cable_length_normalization_large_kilometer_value(self): + """ + A large kilometer length must pass validation and fit in the normalized length field. + """ + cable = Cable.objects.first() + cable.length = Decimal('1234') + cable.length_unit = CableLengthUnitChoices.UNIT_KILOMETER + cable.full_clean() + cable.save() + cable.refresh_from_db() + + self.assertEqual(cable._abs_length, Decimal('1234000.0000')) + + def test_cable_length_normalization_maximum_mile_value(self): + """ + The maximum length value expressed in miles must fit in the normalized length field. + """ + cable = Cable.objects.first() + cable.length = Decimal('999999.99') + cable.length_unit = CableLengthUnitChoices.UNIT_MILE + cable.full_clean() + cable.save() + cable.refresh_from_db() + + self.assertEqual(cable._abs_length, Decimal('1609343983.9066')) + class CableTerminationTestCase(TestCase):