| 1242 | } |
| 1243 | |
| 1244 | static bool ParseTxtRData(const uint8_t* data, uint16_t data_len, StoredTxt* txt, uint32_t max_txt, uint32_t* txt_count) |
| 1245 | { |
| 1246 | *txt_count = 0; |
| 1247 | |
| 1248 | uint32_t offset = 0; |
| 1249 | while (offset < data_len) |
| 1250 | { |
| 1251 | uint8_t len = data[offset++]; |
| 1252 | if (offset + len > data_len) |
| 1253 | return false; |
| 1254 | |
| 1255 | if (len > 0 && *txt_count < max_txt) |
| 1256 | { |
| 1257 | char kv[320]; |
| 1258 | uint32_t copy_len = len; |
| 1259 | if (copy_len >= sizeof(kv)) |
| 1260 | copy_len = sizeof(kv) - 1; |
| 1261 | |
| 1262 | memcpy(kv, data + offset, copy_len); |
| 1263 | kv[copy_len] = 0; |
| 1264 | |
| 1265 | const char* eq = strchr(kv, '='); |
| 1266 | if (eq) |
| 1267 | { |
| 1268 | uint32_t key_len = (uint32_t) (eq - kv); |
| 1269 | uint32_t value_len = (uint32_t) strlen(eq + 1); |
| 1270 | |
| 1271 | if (key_len >= sizeof(txt[*txt_count].m_Key)) |
| 1272 | key_len = sizeof(txt[*txt_count].m_Key) - 1; |
| 1273 | if (value_len >= sizeof(txt[*txt_count].m_Value)) |
| 1274 | value_len = sizeof(txt[*txt_count].m_Value) - 1; |
| 1275 | |
| 1276 | memcpy(txt[*txt_count].m_Key, kv, key_len); |
| 1277 | txt[*txt_count].m_Key[key_len] = 0; |
| 1278 | memcpy(txt[*txt_count].m_Value, eq + 1, value_len); |
| 1279 | txt[*txt_count].m_Value[value_len] = 0; |
| 1280 | } |
| 1281 | else |
| 1282 | { |
| 1283 | uint32_t key_len = copy_len; |
| 1284 | if (key_len >= sizeof(txt[*txt_count].m_Key)) |
| 1285 | key_len = sizeof(txt[*txt_count].m_Key) - 1; |
| 1286 | |
| 1287 | memcpy(txt[*txt_count].m_Key, kv, key_len); |
| 1288 | txt[*txt_count].m_Key[key_len] = 0; |
| 1289 | txt[*txt_count].m_Value[0] = 0; |
| 1290 | } |
| 1291 | |
| 1292 | ++(*txt_count); |
| 1293 | } |
| 1294 | |
| 1295 | offset += len; |
| 1296 | } |
| 1297 | |
| 1298 | return true; |
| 1299 | } |
| 1300 | |
| 1301 | static bool QueryMatchesService(const RegisteredService& service, const char* qname, uint16_t qtype) |
no outgoing calls
no test coverage detected