saghul/aiodns

Error when retrieving binary data in TXT records

maelp opened this issue · 8 comments

maelp commented

The RFC1035 indicates that TXT records are "" which are to be interpreted as binary data of length at most 255, prefixed with a length character.

If I'm packing a TXT record containing a null byte, it is not correctly parsed by the library and the parsed output contains an empty buffer

Do you know if c-area is capa of parsing those? Do you have a sample record I could query?

maelp commented

I'm not sure whether c-ares is doing it as it should or not, but I guess it should be supposed to because the RFC indicates that's how it should be done

For instance I'm trying to use this byte string as a TXT record (I'm using dnslib to pack the data, which works as expected when I inspect the packet, and aiodns to receive and parse the packet, which shows an empty record):

b'\x00\x08\xa7\xe4\xca\x88\x06\x12\x02\x12'

and (perhaps because the first byte is null) it outputs as an empty string

The bug is most likely here: https://github.com/saghul/pycares/blob/4e6e36f839255ebef05e0682b98cbee1533805ce/src/pycares/__init__.py#L749-L764 -- the txt reply structures do have a length field I'm not using, I'm relying on strlen really.

A patch would be most welcome!

maelp commented

I guess it is this indeed https://github.com/saghul/pycares/blob/4e6e36f839255ebef05e0682b98cbee1533805ce/src/pycares/utils.py#L21

it should not necessarily force a decoding as ascii, it should be a "bytes" response (but this might break existing code as it means that the result of the resp.text is "bytes" rather than "str", and it is to each user to know how to interpret it, although this would be the correct way to do it)

We are already returning bytes sometimes, and str just when the response is strictly ascii. Can't we keep that behavior?

maelp commented

So I guess the real "error" is there, trying to cast to a _ffi.string when it should stay as a byte array (but not sure how to do this using the lib?) https://github.com/saghul/pycares/blob/4e6e36f839255ebef05e0682b98cbee1533805ce/src/pycares/__init__.py#L763

maelp commented

The correct way seems to be

self.text = bytes(_ffi.buffer(txt.txt, txt.length))
maelp commented

This PR fixes the bug saghul/pycares#160