Opened 4 weeks ago

Closed 4 weeks ago

Last modified 3 weeks ago

#36098 closed Bug (fixed)

TypeError: object of type 'IPv6Address' has no len() when running tests with GeoDjango

Reported by: Natalia Bidart Owned by: Mariusz Felisiak
Component: GIS Version: 5.1
Severity: Release blocker Keywords:
Cc: Sarah Boyce Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Natalia Bidart)

Following the security release for 5.1.5, 5.0.11 and 4.2.18, there seems to be an issue with the GeoDjango tests:

Traceback (most recent call last):
  File "/home/jenkins/workspace/pull-requests-focal/database/mysql_gis/label/focal-pr/python/python3.10/django/core/validators.py", line 305, in validate_ipv4_address
    ipaddress.IPv4Address(value)
  File "/usr/lib/python3.10/ipaddress.py", line 1305, in __init__
    self._ip = self._ip_int_from_string(addr_str)
  File "/usr/lib/python3.10/ipaddress.py", line 1192, in _ip_int_from_string
    raise AddressValueError("Expected 4 octets in %r" % ip_str)
ipaddress.AddressValueError: Expected 4 octets in '::ffff:27d:a0d8'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/jenkins/workspace/pull-requests-focal/database/mysql_gis/label/focal-pr/python/python3.10/django/core/validators.py", line 325, in validate_ipv46_address
    validate_ipv4_address(value)
  File "/home/jenkins/workspace/pull-requests-focal/database/mysql_gis/label/focal-pr/python/python3.10/django/core/validators.py", line 307, in validate_ipv4_address
    raise ValidationError(
django.core.exceptions.ValidationError: ['Enter a valid IPv4 address.']

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/jenkins/workspace/pull-requests-focal/database/mysql_gis/label/focal-pr/python/python3.10/tests/gis_tests/test_geoip2.py", line 131, in test_country
    self.assertEqual(g.country(query), self.expected_country)
  File "/home/jenkins/workspace/pull-requests-focal/database/mysql_gis/label/focal-pr/python/python3.10/django/contrib/gis/geoip2.py", line 207, in country
    response = self._query(query, require_city=False)
  File "/home/jenkins/workspace/pull-requests-focal/database/mysql_gis/label/focal-pr/python/python3.10/django/contrib/gis/geoip2.py", line 157, in _query
    validate_ipv46_address(query)
  File "/home/jenkins/workspace/pull-requests-focal/database/mysql_gis/label/focal-pr/python/python3.10/django/core/validators.py", line 328, in validate_ipv46_address
    validate_ipv6_address(value)
  File "/home/jenkins/workspace/pull-requests-focal/database/mysql_gis/label/focal-pr/python/python3.10/django/core/validators.py", line 315, in validate_ipv6_address
    if not is_valid_ipv6_address(value):
  File "/home/jenkins/workspace/pull-requests-focal/database/mysql_gis/label/focal-pr/python/python3.10/django/utils/ipv6.py", line 59, in is_valid_ipv6_address
    _ipv6_address_from_str(ip_str)
  File "/home/jenkins/workspace/pull-requests-focal/database/mysql_gis/label/focal-pr/python/python3.10/django/utils/ipv6.py", line 10, in _ipv6_address_from_str
    if len(ip_str) > max_length:
TypeError: object of type 'IPv6Address' has no len()

Change History (14)

comment:1 by Mariusz Felisiak, 4 weeks ago

Triage Stage: UnreviewedAccepted

Sorry, I've notice the ticket when I had a patch ready. Feel-free to close it, PR.

We have two issues here:

  • first GeoIP2._query() unnecessarily calls validate_ipv46_address for always valid query,
  • second validate_ipv46_address() and validate_ipv6_address() crash on ipaddress.IPv6Address instances.

I know that calling validate_ipv46_address()/validate_ipv6_address() is pointless, but it worked for years so I'd fix it.

comment:2 by Natalia Bidart, 4 weeks ago

Thank you Mariusz, let's push forward your PR, mine needs tests still and release note. I will re-assign this to you. I guess I should issue releases ASAP? Is there a precedent for how to handle cases like this?

We also need to update the docstrings of the two validator helpers because they clearly state that a string is expected (and this is what caused the issue in the first place). I agree with you that we can't change that behavior (i.e. the validators should work with ipv4 and ipv6 instances), so we need to update the docstrings. I will add further comments in the PR.

comment:3 by Natalia Bidart, 4 weeks ago

Description: modified (diff)
Has patch: set
Owner: changed from Natalia Bidart to Mariusz Felisiak

comment:4 by Natalia Bidart, 4 weeks ago

Triage Stage: AcceptedReady for checkin

comment:5 by Mariusz Felisiak, 4 weeks ago

I guess I should issue releases ASAP? Is there a precedent for how to handle cases like this?

It depends how serious a regression is. It's not very urgent, but releasing a hot-fix wouldn't hurt. The last time I remember was in 2021, when we issued 9 releases in two week :)

in reply to:  5 comment:6 by Natalia Bidart, 4 weeks ago

Cc: Sarah Boyce added

Replying to Mariusz Felisiak:

I guess I should issue releases ASAP? Is there a precedent for how to handle cases like this?

It depends how serious a regression is. It's not very urgent, but releasing a hot-fix wouldn't hurt. The last time I remember was in 2021, when we issued 9 releases in two week :)

Thank you for the pointers, I will consider doing releases tomorrow morning, before Sarah cuts the new stable branch (will add Sarah as cc).

comment:7 by Sarah Boyce, 4 weeks ago

Thank you for the pointers, I will consider doing releases tomorrow morning, before Sarah cuts the new stable branch (will add Sarah as cc).

I don't think the cutting of the 5.2 branch adds an urgency as to when we release. I think it's preferable to merge into main (and do the back-ports) before the cut, but whether there is a release or not doesn't make a difference to me (I don't think).

Last edited 4 weeks ago by Sarah Boyce (previous) (diff)

comment:8 by nessita <124304+nessita@…>, 4 weeks ago

Resolution: fixed
Status: assignedclosed

In b3c5830:

Fixed #36098 -- Fixed validate_ipv6_address()/validate_ipv46_address() crash for non-string values.

Regression in ca2be7724e1244a4cb723de40a070f873c6e94bf.

comment:9 by Natalia <124304+nessita@…>, 4 weeks ago

In c81669cb:

[5.1.x] Fixed #36098 -- Fixed validate_ipv6_address()/validate_ipv46_address() crash for non-string values.

Regression in ca2be7724e1244a4cb723de40a070f873c6e94bf.

Backport of b3c5830769d8a5dbf2f974da7116fe503c9454d9 from main.

comment:10 by Natalia <124304+nessita@…>, 4 weeks ago

In 21dfd30:

[5.0.x] Fixed #36098 -- Fixed validate_ipv6_address()/validate_ipv46_address() crash for non-string values.

Regression in ca2be7724e1244a4cb723de40a070f873c6e94bf.

Backport of b3c5830769d8a5dbf2f974da7116fe503c9454d9 from main.

comment:11 by Natalia <124304+nessita@…>, 4 weeks ago

In 043dfad:

[4.2.x] Fixed #36098 -- Fixed validate_ipv6_address()/validate_ipv46_address() crash for non-string values.

Regression in ca2be7724e1244a4cb723de40a070f873c6e94bf.

Backport of b3c5830769d8a5dbf2f974da7116fe503c9454d9 from main.

comment:12 by GitHub <noreply@…>, 4 weeks ago

In 57b0229:

[4.2.x] Refs #36098 -- Fixed validate_ipv4_address() crash for non-string values.

Regression in ca2be7724e1244a4cb723de40a070f873c6e94bf.

comment:13 by sysedit, 3 weeks ago

Hello,
the fix for the CVE introduces the following change:

from django.db.models import GenericIPAddressField 
GenericIPAddressField().run_validators('fe80::f59c:37a5:cab1:8bd9%ethernet_32770')

This would be ok with Django 5.0.10 but would raise

ValidationError: ['Enter a valid IPv4 or IPv6 address.']

in Django 5.0.11 as the string is 40 char long and not 39. As this ticket only fixes non-str handling, the exception will still be raised, correct ?

Should the max-length be raised to something larger, like 65 ? https://superuser.com/questions/381022/how-many-characters-can-an-ip-address-be seems to indicate that this would be the common value to handle IPv6 with scope zone properly ?

Last edited 3 weeks ago by sysedit (previous) (diff)

in reply to:  13 comment:14 by Natalia Bidart, 3 weeks ago

Hello sysedit!

Replying to sysedit:

in Django 5.0.11 as the string is 40 char long and not 39. As this ticket only fixes non-str handling, the exception will still be raised, correct ?

Yes, this is correct.

Should the max-length be raised to something larger, like 65 ? https://superuser.com/questions/381022/how-many-characters-can-an-ip-address-be seems to indicate that this would be the common value to handle IPv6 with scope zone properly ?

You can customize the max_length yourself in your forms, see a wider discussion in this forum post, which I believe would solve the ValidationError issue for your project.

Note: See TracTickets for help on using tickets.
Back to Top