| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -86,7 +86,14 @@ cdef class ServiceInfo(RecordUpdateListener): | |||
| 86 | 86 | @cython.locals(cache=DNSCache) | |
| 87 | 87 | cpdef bint _load_from_cache(self, object zc, double now) | |
| 88 | 88 | ||
| 89 | - @cython.locals(length="unsigned char", index="unsigned int", key_value=bytes, key_sep_value=tuple) | ||
| 89 | + @cython.locals( | ||
| 90 | + length="unsigned char", | ||
| 91 | + index="unsigned int", | ||
| 92 | + key_value=bytes, | ||
| 93 | + key=bytes, | ||
| 94 | + sep=bytes, | ||
| 95 | + value=bytes, | ||
| 96 | + ) | ||
| 90 | 97 | cdef void _unpack_text_into_properties(self) | |
| 91 | 98 | ||
| 92 | 99 | @cython.locals(k=bytes, v=bytes) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -464,10 +464,12 @@ def _unpack_text_into_properties(self) -> None: | |||
| 464 | 464 | length = text[index] | |
| 465 | 465 | index += 1 | |
| 466 | 466 | key_value = text[index : index + length] | |
| 467 | - key_sep_value = key_value.partition(b"=") | ||
| 468 | - key = key_sep_value[0] | ||
| 467 | + key, sep, value = key_value.partition(b"=") | ||
| 469 | 468 | if key not in properties: | |
| 470 | - properties[key] = key_sep_value[2] or None | ||
| 469 | + # RFC 6763 section 6.4 distinguishes a key with no '=' (a | ||
| 470 | + # boolean attribute: present, no value) from `key=` (present | ||
| 471 | + # with an empty value), so test the separator, not the value. | ||
| 472 | + properties[key] = value if sep else None | ||
| 471 | 473 | index += length | |
| 472 | 474 | ||
| 473 | 475 | self._properties = properties | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -630,6 +630,64 @@ def test_service_info_duplicate_properties_txt_records(self): | |||
| 630 | 630 | assert info.properties[b"ci"] == b"2" | |
| 631 | 631 | zc.close() | |
| 632 | 632 | ||
| 633 | + def test_service_info_empty_value_txt_record(self): | ||
| 634 | + """Verify `key=` decodes to an empty value, not to a valueless `key`.""" | ||
| 635 | + zc = r.Zeroconf(interfaces=["127.0.0.1"]) | ||
| 636 | + service_name = "name._type._tcp.local." | ||
| 637 | + service_type = "_type._tcp.local." | ||
| 638 | + service_server = "ash-1.local." | ||
| 639 | + text = b"\x03rm=\x02rs\x05ve=05" | ||
| 640 | + info = ServiceInfo( | ||
| 641 | + service_type, | ||
| 642 | + service_name, | ||
| 643 | + 22, | ||
| 644 | + 0, | ||
| 645 | + 0, | ||
| 646 | + {"path": "/~paulsm/"}, | ||
| 647 | + service_server, | ||
| 648 | + addresses=[socket.inet_aton("10.0.1.2")], | ||
| 649 | + ) | ||
| 650 | + info.async_update_records( | ||
| 651 | + zc, | ||
| 652 | + r.current_time_millis(), | ||
| 653 | + [ | ||
| 654 | + r.RecordUpdate( | ||
| 655 | + r.DNSText( | ||
| 656 | + service_name, | ||
| 657 | + const._TYPE_TXT, | ||
| 658 | + const._CLASS_IN | const._CLASS_UNIQUE, | ||
| 659 | + 120, | ||
| 660 | + text, | ||
| 661 | + ), | ||
| 662 | + None, | ||
| 663 | + ) | ||
| 664 | + ], | ||
| 665 | + ) | ||
| 666 | + assert info.properties[b"rm"] == b"" | ||
| 667 | + assert info.properties[b"rs"] is None | ||
| 668 | + assert info.properties[b"ve"] == b"05" | ||
| 669 | + | ||
| 670 | + # The string-facing API must preserve the distinction too. | ||
| 671 | + assert info.decoded_properties["rm"] == "" | ||
| 672 | + assert info.decoded_properties["rs"] is None | ||
| 673 | + assert info.decoded_properties["ve"] == "05" | ||
| 674 | + | ||
| 675 | + # Re-encoding either view of the properties must reproduce the received rdata. | ||
| 676 | + for properties in (info.properties, info.decoded_properties): | ||
| 677 | + assert ( | ||
| 678 | + ServiceInfo( | ||
| 679 | + service_type, | ||
| 680 | + service_name, | ||
| 681 | + 22, | ||
| 682 | + 0, | ||
| 683 | + 0, | ||
| 684 | + properties, | ||
| 685 | + service_server, | ||
| 686 | + ).text | ||
| 687 | + == text | ||
| 688 | + ) | ||
| 689 | + zc.close() | ||
| 690 | + | ||
| 633 | 691 | ||
| 634 | 692 | def test_multiple_addresses(): | |
| 635 | 693 | type_ = "_http._tcp.local." | |
| Back | FazBrowse Home | New Git URL |
0 commit comments