Repository: flutter
Issue: [multicast_dns] TXT records can be unparsable
Labels: package,p: multicast_dns,team-ecosystem,P3,triaged-ecosystem

### What package does this bug report belong to?

multicast_dns

### What target platforms are you seeing this bug on?

Linux

### Have you already upgraded your packages?

Yes

### Dependency versions

<details open><summary>pubspec.lock</summary>

```lock
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
  args:
    dependency: transitive
    description:
      name: args
      sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596
      url: "https://pub.dev"
    source: hosted
    version: "2.4.2"
  async:
    dependency: transitive
    description:
      name: async
      sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
      url: "https://pub.dev"
    source: hosted
    version: "2.11.0"
  aurora:
    dependency: "direct main"
    description:
      path: "../../libaurora/lang/dart/aurora"
      relative: true
    source: path
    version: "0.0.1"
  bluez:
    dependency: "direct main"
    description:
      name: bluez
      sha256: bfd004c81e3de0f06dce8580bc39a4600e4a6efe465a866b31d4d954c9f356aa
      url: "https://pub.dev"
    source: hosted
    version: "0.8.1"
  boolean_selector:
    dependency: transitive
    description:
      name: boolean_selector
      sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
      url: "https://pub.dev"
    source: hosted
    version: "2.1.1"
  cbor:
    dependency: transitive
    description:
      name: cbor
      sha256: a44a7e6e40d0b196b04af30282661ffc5d6b8b2bcb1d5200f422194c6e0f58fb
      url: "https://pub.dev"
    source: hosted
    version: "5.1.2"
  characters:
    dependency: transitive
    description:
      name: characters
      sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
      url: "https://pub.dev"
    source: hosted
    version: "1.3.0"
  clock:
    dependency: transitive
    description:
      name: clock
      sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
      url: "https://pub.dev"
    source: hosted
    version: "1.1.1"
  collection:
    dependency: "direct main"
    description:
      name: collection
      sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
      url: "https://pub.dev"
    source: hosted
    version: "1.18.0"
  convert:
    dependency: transitive
    description:
      name: convert
      sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
      url: "https://pub.dev"
    source: hosted
    version: "3.1.1"
  cupertino_icons:
    dependency: "direct main"
    description:
      name: cupertino_icons
      sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d
      url: "https://pub.dev"
    source: hosted
    version: "1.0.6"
  dbus:
    dependency: transitive
    description:
      name: dbus
      sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac"
      url: "https://pub.dev"
    source: hosted
    version: "0.7.10"
  fake_async:
    dependency: transitive
    description:
      name: fake_async
      sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
      url: "https://pub.dev"
    source: hosted
    version: "1.3.1"
  ffi:
    dependency: transitive
    description:
      name: ffi
      sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
      url: "https://pub.dev"
    source: hosted
    version: "2.1.0"
  file_picker:
    dependency: "direct main"
    description:
      name: file_picker
      sha256: "4e42aacde3b993c5947467ab640882c56947d9d27342a5b6f2895b23956954a6"
      url: "https://pub.dev"
    source: hosted
    version: "6.1.1"
  flutter:
    dependency: "direct main"
    description: flutter
    source: sdk
    version: "0.0.0"
  flutter_lints:
    dependency: "direct dev"
    description:
      name: flutter_lints
      sha256: e2a421b7e59244faef694ba7b30562e489c2b489866e505074eb005cd7060db7
      url: "https://pub.dev"
    source: hosted
    version: "3.0.1"
  flutter_plugin_android_lifecycle:
    dependency: transitive
    description:
      name: flutter_plugin_android_lifecycle
      sha256: b068ffc46f82a55844acfa4fdbb61fad72fa2aef0905548419d97f0f95c456da
      url: "https://pub.dev"
    source: hosted
    version: "2.0.17"
  flutter_riverpod:
    dependency: "direct main"
    description:
      name: flutter_riverpod
      sha256: da9591d1f8d5881628ccd5c25c40e74fc3eef50ba45e40c3905a06e1712412d5
      url: "https://pub.dev"
    source: hosted
    version: "2.4.9"
  flutter_test:
    dependency: "direct dev"
    description: flutter
    source: sdk
    version: "0.0.0"
  flutter_web_plugins:
    dependency: transitive
    description: flutter
    source: sdk
    version: "0.0.0"
  hex:
    dependency: transitive
    description:
      name: hex
      sha256: "4e7cd54e4b59ba026432a6be2dd9d96e4c5205725194997193bf871703b82c4a"
      url: "https://pub.dev"
    source: hosted
    version: "0.2.0"
  http:
    dependency: "direct main"
    description:
      name: http
      sha256: d4872660c46d929f6b8a9ef4e7a7eff7e49bbf0c4ec3f385ee32df5119175139
      url: "https://pub.dev"
    source: hosted
    version: "1.1.2"
  http_parser:
    dependency: transitive
    description:
      name: http_parser
      sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
      url: "https://pub.dev"
    source: hosted
    version: "4.0.2"
  ieee754:
    dependency: transitive
    description:
      name: ieee754
      sha256: "7d87451c164a56c156180d34a4e93779372edd191d2c219206100b976203128c"
      url: "https://pub.dev"
    source: hosted
    version: "1.0.3"
  intl:
    dependency: "direct main"
    description:
      name: intl
      sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
      url: "https://pub.dev"
    source: hosted
    version: "0.19.0"
  lints:
    dependency: transitive
    description:
      name: lints
      sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290
      url: "https://pub.dev"
    source: hosted
    version: "3.0.0"
  matcher:
    dependency: transitive
    description:
      name: matcher
      sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
      url: "https://pub.dev"
    source: hosted
    version: "0.12.16"
  material_color_utilities:
    dependency: transitive
    description:
      name: material_color_utilities
      sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
      url: "https://pub.dev"
    source: hosted
    version: "0.5.0"
  mcumgr:
    dependency: "direct main"
    description:
      name: mcumgr
      sha256: fb5adc090e29fefc63ef9380105885a701543c451bb6b2bdbfae1b8d075149e9
      url: "https://pub.dev"
    source: hosted
    version: "0.0.3"
  meta:
    dependency: transitive
    description:
      name: meta
      sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
      url: "https://pub.dev"
    source: hosted
    version: "1.10.0"
  multicast_dns:
    dependency: "direct main"
    description:
      name: multicast_dns
      sha256: "316cc47a958d4bd3c67bd238fe8b44fdfb6133bad89cb191c0c3bd3edb14e296"
      url: "https://pub.dev"
    source: hosted
    version: "0.3.2+6"
  path:
    dependency: transitive
    description:
      name: path
      sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
      url: "https://pub.dev"
    source: hosted
    version: "1.8.3"
  petitparser:
    dependency: transitive
    description:
      name: petitparser
      sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
      url: "https://pub.dev"
    source: hosted
    version: "6.0.2"
  plugin_platform_interface:
    dependency: transitive
    description:
      name: plugin_platform_interface
      sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
      url: "https://pub.dev"
    source: hosted
    version: "2.1.8"
  riverpod:
    dependency: transitive
    description:
      name: riverpod
      sha256: "942999ee48b899f8a46a860f1e13cee36f2f77609eb54c5b7a669bb20d550b11"
      url: "https://pub.dev"
    source: hosted
    version: "2.4.9"
  sky_engine:
    dependency: transitive
    description: flutter
    source: sdk
    version: "0.0.99"
  source_span:
    dependency: transitive
    description:
      name: source_span
      sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
      url: "https://pub.dev"
    source: hosted
    version: "1.10.0"
  stack_trace:
    dependency: transitive
    description:
      name: stack_trace
      sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
      url: "https://pub.dev"
    source: hosted
    version: "1.11.1"
  state_notifier:
    dependency: transitive
    description:
      name: state_notifier
      sha256: b8677376aa54f2d7c58280d5a007f9e8774f1968d1fb1c096adcb4792fba29bb
      url: "https://pub.dev"
    source: hosted
    version: "1.0.0"
  stream_channel:
    dependency: transitive
    description:
      name: stream_channel
      sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
      url: "https://pub.dev"
    source: hosted
    version: "2.1.2"
  string_scanner:
    dependency: transitive
    description:
      name: string_scanner
      sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
      url: "https://pub.dev"
    source: hosted
    version: "1.2.0"
  term_glyph:
    dependency: transitive
    description:
      name: term_glyph
      sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
      url: "https://pub.dev"
    source: hosted
    version: "1.2.1"
  test_api:
    dependency: transitive
    description:
      name: test_api
      sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
      url: "https://pub.dev"
    source: hosted
    version: "0.6.1"
  typed_data:
    dependency: transitive
    description:
      name: typed_data
      sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
      url: "https://pub.dev"
    source: hosted
    version: "1.3.2"
  vector_math:
    dependency: "direct main"
    description:
      name: vector_math
      sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
      url: "https://pub.dev"
    source: hosted
    version: "2.1.4"
  web:
    dependency: transitive
    description:
      name: web
      sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
      url: "https://pub.dev"
    source: hosted
    version: "0.3.0"
  win32:
    dependency: transitive
    description:
      name: win32
      sha256: "464f5674532865248444b4c3daca12bd9bf2d7c47f759ce2617986e7229494a8"
      url: "https://pub.dev"
    source: hosted
    version: "5.2.0"
  xml:
    dependency: transitive
    description:
      name: xml
      sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
      url: "https://pub.dev"
    source: hosted
    version: "6.5.0"
sdks:
  dart: ">=3.2.0 <4.0.0"
  flutter: ">=3.7.0"

```

</details>


### Steps to reproduce

Use multicast_dns to parse a TXT record that contains a binary-encoded value containing a newline character '\n'.

### Expected results

The user should be able to recover each entry of a TXT record reliably. Instead of concatenating them into a single string, a List<String> could be used.

### Actual results

Due to the text property being [stitched together with newlines](https://github.com/flutter/packages/blob/main/packages/multicast_dns/lib/src/packet.dart#L346), it is impossible to write a fully reliable algorithm to parse any TXT records that have binary-encoded values.

[This document](http://www.zeroconf.org/Rendezvous/txtrecords.html) describes the value field format under the section Rules for values in DNS-SD Name/Value pairs.

> The value is opaque binary data. Often the value for a particular attribute will be US-ASCII (or UTF-8) text, but it is legal for a value to be any binary data. For example, if the value of a key is an IPv4 address, that address should simply be stored as four bytes of binary data, not as a variable-length 7-15 byte ASCII string giving the address represented in textual dotted decimal notation.

### Code sample

Here is a TXT record with a [field "xp"](https://github.com/openthread/ot-br-posix/blob/897028fe9ef1b7604d8911f1c31b048d70c15c8a/src/border_agent/border_agent.cpp#L399) which contains a binary-encoded value containing a '\n' (\010) character.
```
$ avahi-browse -r _meshcop._udp
= enp11s0 IPv6 OpenThread BorderRouter #19E3                 _meshcop._udp        local
   hostname = [<...>]
   address = [<...>]
   port = [49152]
   txt = ["omr=@\253m.\253\211\129\000\001" "dn=DefaultDomain" "bb=\240\191" "sq=$" "pt=_e\2415" "at=\000\000\000\000\000\001\000\000" "sb=\000\000\001\177" "xa=>\195 \027bF\025\227" "tv=1.3.0" "xp=\010\246\196Cg'\2291" "nn=ahemphill.0" "mn=BorderRouter" "vn=OpenThread" "id=\187\023\155L]{b9\191\029\190\2406\197\020\250" "rv=1"]
```

Here is the resulting array from multicast_dns:
```
TxtResourceRecord txt;
// client.lookup, etc to obtain text record
print(${utf8.encode(txt.text)}");
print(${txt.text});
```

```
[114, 118, 61, 49, 10, 105, 100, 61, 239, 191, 189, 23, 239, 191, 189, 76, 93, 123, 98, 57, 239, 191, 189, 29, 239, 191, 189, 239, 191, 189, 54, 239, 191, 189, 20, 239, 191, 189, 10, 118, 110, 61, 79, 112, 101, 110, 84, 104, 114, 101, 97, 100, 10, 109, 110, 61, 66, 111, 114, 100, 101, 114, 82, 111, 117, 116, 101, 114, 10, 110, 110, 61, 97, 104, 101, 109, 112, 104, 105, 108, 108, 46, 48, 10, 120, 112, 61, 10, 239, 191, 189, 239, 191, 189, 67, 103, 39, 239, 191, 189, 49, 10, 116, 118, 61, 49, 46, 51, 46, 48, 10, 120, 97, 61, 62, 239, 191, 189, 32, 27, 98, 70, 25, 239, 191, 189, 10, 115, 98, 61, 0, 0, 1, 239, 191, 189, 10, 97, 116, 61, 0, 0, 0, 0, 0, 1, 0, 0, 10, 112, 116, 61, 95, 101, 239, 191, 189, 53, 10, 115, 113, 61, 36, 10, 98, 98, 61, 239, 191, 189, 10, 100, 110, 61, 68, 101, 102, 97, 117, 108, 116, 68, 111, 109, 97, 105, 110, 10, 111, 109, 114, 61, 64, 239, 191, 189, 109, 46, 239, 191, 189, 211, 129, 0, 1, 10]
rv=1
id=��L]{b9���6��
vn=OpenThread
mn=BorderRouter
nn=ahemphill.0
xp=
��Cg'�1
tv=1.3.0
xa=>� F�
sb=�
at=
pt=_e�5
sq=$
bb=�
dn=DefaultDomain
omr=@�m.�Ӂ
```

The "xp" record gets broken up onto two lines here since it contains a newline itself.

### Screenshots or Videos

_No response_

### Logs

_No response_

### Flutter Doctor output

<details open><summary>Doctor output</summary>

```console
$ flutter doctor -v
[✓] Flutter (Channel stable, 3.16.5, on Ubuntu 22.04.2 LTS 6.2.0-39-generic,
    locale en_US.UTF-8)
    • Flutter version 3.16.5 on channel stable at
      /home/adam/snap/flutter/common/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 78666c8dc5 (3 weeks ago), 2023-12-19 16:14:14 -0800
    • Engine revision 3f3e560236
    • Dart version 3.2.3
    • DevTools version 2.28.4

[✗] Android toolchain - develop for Android devices
    ✗ Unable to locate Android SDK.
      Install Android Studio from:
      https://developer.android.com/studio/index.html
      On first launch it will assist you in installing the Android SDK
      components.
      (or visit https://flutter.dev/docs/get-started/install/linux#android-setup
      for detailed instructions).
      If the Android SDK has been installed to a custom location, please use
      `flutter config --android-sdk` to update to that location.


[✗] Chrome - develop for the web (Cannot find Chrome executable at
    google-chrome)
    ! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.

[✓] Linux toolchain - develop for Linux desktop
    • clang version 10.0.0-4ubuntu1
    • cmake version 3.16.3
    • ninja version 1.10.0
    • pkg-config version 0.29.1

[!] Android Studio (not installed)
    • Android Studio not found; download from
      https://developer.android.com/studio/index.html
      (or visit https://flutter.dev/docs/get-started/install/linux#android-setup
      for detailed instructions).

[✓] VS Code (version 1.85.1)
    • VS Code at /usr/share/code
    • Flutter extension version 3.80.0

[✓] Connected device (1 available)
    • Linux (desktop) • linux • linux-x64 • Ubuntu 22.04.2 LTS 6.2.0-39-generic

[✓] Network resources
    • All expected network resources are available.

! Doctor found issues in 3 categories.

```

</details>