Skip to content

Do not convert empty strings in TXT records to bool - #226

Merged
jstasiak merged 6 commits into
python-zeroconf:masterfrom
mtdcr:empty_strings
Mar 7, 2020
Merged

Do not convert empty strings in TXT records to bool#226
jstasiak merged 6 commits into
python-zeroconf:masterfrom
mtdcr:empty_strings

Conversation

@mtdcr

@mtdcr mtdcr commented Feb 10, 2020

Copy link
Copy Markdown

It's been wrong since the first commit. Empty strings are just empty strings.

@mtdcr

mtdcr commented Feb 19, 2020

Copy link
Copy Markdown
Author

I've added another commit to adjust the property tests. Note that some of these tests assumed surprising results before (and somehow still do now). Why should 1.0 become False?

@coveralls

coveralls commented Feb 19, 2020

Copy link
Copy Markdown

Coverage Status

Coverage increased (+0.2%) to 93.783% when pulling 4cde41f on mtdcr:empty_strings into bef8f59 on jstasiak:master.

@jstasiak

Copy link
Copy Markdown
Collaborator

This is good question, it has been like this since the first commit, so I guess there's no way to know now. I see there's some documentation on this in RFC 6763 but I'm yet to read it – do you maybe know off the top of your head if the way to handle integers, text, floating point numbers etc. is standardized?

@mtdcr

mtdcr commented Feb 20, 2020

Copy link
Copy Markdown
Author

No, it's not standardized. Values are just binary octets. I don't think the library should try to convert any values of received TXT records from binary. For conversion to binary, I think str(value).encode('utf-8') would be good enough to handle all types. How about something like this untested patch?

diff --git a/zeroconf/__init__.py b/zeroconf/__init__.py
index ddb64b5..9039e10 100644
--- a/zeroconf/__init__.py
+++ b/zeroconf/__init__.py
@@ -1656,19 +1656,10 @@ class ServiceInfo(RecordUpdateListener):
                     key = key.encode('utf-8')
 
                 if value is None:
-                    suffix = b''
-                elif isinstance(value, str):
-                    suffix = value.encode('utf-8')
-                elif isinstance(value, bytes):
-                    suffix = value
-                elif isinstance(value, int):
-                    if value:
-                        suffix = b'true'
-                    else:
-                        suffix = b'false'
+                    record = key
                 else:
-                    suffix = b''
-                list_.append(b'='.join((key, suffix)))
+                    record = key + b'=' + str(value).encode('utf-8')
+                list_.append(record)
             for item in list_:
                 result = b''.join((result, int2byte(len(item)), item))
             self.text = result
@@ -1695,12 +1686,7 @@ class ServiceInfo(RecordUpdateListener):
             except ValueError:
                 # No equals sign at all
                 key = s
-                value = False
-            else:
-                if value == b'true':
-                    value = True
-                elif value == b'false':
-                    value = False
+                value = None
 
             # Only update non-existent properties
             if key and result.get(key) is None:

@jstasiak

Copy link
Copy Markdown
Collaborator

With the exception of the str(value).encode('utf-8') part (value can be already bytes) this looks good to me. I'm slightly hesitant of breaking backwards compatibility like this (someone may depend on the current behavior) but tough luck, we'll add backwards incompatibility entry in the changelog.

@mtdcr

mtdcr commented Feb 28, 2020

Copy link
Copy Markdown
Author

I've added new commits with slightly modified code + adjusted test cases. Please review and feel free to squash them as you like or to pick only the first commits now and new ones later.

@jstasiak jstasiak left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@jstasiak
jstasiak merged commit 8e3adf8 into python-zeroconf:master Mar 7, 2020
@mtdcr
mtdcr deleted the empty_strings branch April 10, 2021 18:42
bboe added a commit to bboe/python-zeroconf that referenced this pull request Aug 12, 2026
RFC 6763 6.4: a key with no '=' is a boolean attribute; `key=` is present
with an empty value. Collapsing both to None makes them indistinguishable,
so a received `key=` re-encodes as a bare `key`.

Regression in python-zeroconf#1225 (first released in 0.80.0), which replaced explicit
branching on the separator with `value or None`. Restores the behaviour
python-zeroconf#226 introduced.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants