Matter SDK Coverage Report
Current view: top level - lib/dnssd/minimal_mdns/core - QName.cpp (source / functions) Coverage Total Hit
Test: SHA:3f9cd168e84cd831b7699126f5296f5c5498690f Lines: 90.3 % 72 65
Test Date: 2026-04-27 19:52:19 Functions: 100.0 % 6 6

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2020 Project CHIP Authors
       4              :  *
       5              :  *    Licensed under the Apache License, Version 2.0 (the "License");
       6              :  *    you may not use this file except in compliance with the License.
       7              :  *    You may obtain a copy of the License at
       8              :  *
       9              :  *        http://www.apache.org/licenses/LICENSE-2.0
      10              :  *
      11              :  *    Unless required by applicable law or agreed to in writing, software
      12              :  *    distributed under the License is distributed on an "AS IS" BASIS,
      13              :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14              :  *    See the License for the specific language governing permissions and
      15              :  *    limitations under the License.
      16              :  */
      17              : #include <assert.h>
      18              : #include <strings.h>
      19              : 
      20              : #include "QName.h"
      21              : 
      22              : namespace mdns {
      23              : namespace Minimal {
      24              : 
      25        61586 : bool SerializedQNameIterator::Next()
      26              : {
      27        61586 :     return mIsValid && Next(true);
      28              : }
      29              : 
      30        62262 : bool SerializedQNameIterator::Next(bool followIndirectPointers)
      31              : {
      32        62262 :     if (!mIsValid)
      33              :     {
      34            0 :         return false;
      35              :     }
      36              : 
      37              :     while (true)
      38              :     {
      39        72680 :         assert(mValidData.Contains(mCurrentPosition));
      40              : 
      41        72680 :         const uint8_t length = *mCurrentPosition;
      42        72680 :         if (*mCurrentPosition == 0)
      43              :         {
      44              :             // Done with all items
      45        12423 :             return false;
      46              :         }
      47              : 
      48        60257 :         if ((length & kPtrMask) == kPtrMask)
      49              :         {
      50        10631 :             if (!followIndirectPointers)
      51              :             {
      52              :                 // Stop at first indirect pointer
      53          207 :                 return false;
      54              :             }
      55              : 
      56              :             // PTR contains 2 bytes
      57        10424 :             if (!mValidData.Contains(mCurrentPosition + 1))
      58              :             {
      59            2 :                 mIsValid = false;
      60            2 :                 return false;
      61              :             }
      62              : 
      63        10422 :             size_t offset = static_cast<size_t>(((*mCurrentPosition & 0x3F) << 8) | *(mCurrentPosition + 1));
      64              :             // Look behind has to keep going backwards to avoid potential infinite recursion.
      65              :             // mLookBehindMax starts out <= mValidData.Size() and only decreases;
      66              :             // mLookBehindMax <= mCurrentPosition - mValidData.Start() remains true throughout.
      67        10422 :             if (offset >= mLookBehindMax)
      68              :             {
      69            4 :                 mIsValid = false;
      70            4 :                 return false;
      71              :             }
      72              : 
      73        10418 :             mLookBehindMax   = offset;
      74        10418 :             mCurrentPosition = mValidData.Start() + offset;
      75              :         }
      76              :         else
      77              :         {
      78              :             // This branch handles non-pointer data. This will be string of size [length].
      79        49626 :             if (length > kMaxValueSize)
      80              :             {
      81              :                 // value is too large (larger than RFC limit)
      82            0 :                 mIsValid = false;
      83            0 :                 return false;
      84              :             }
      85              : 
      86        49626 :             if (!mValidData.Contains(mCurrentPosition + 1 + length))
      87              :             {
      88              :                 // string outside valid data
      89            7 :                 mIsValid = false;
      90            7 :                 return false;
      91              :             }
      92              : 
      93        49619 :             memcpy(mValue, mCurrentPosition + 1, length);
      94        49619 :             mValue[length]   = '\0';
      95        49619 :             mCurrentPosition = mCurrentPosition + length + 1;
      96        49619 :             return true;
      97              :         }
      98        10418 :     }
      99              : }
     100              : 
     101          297 : const uint8_t * SerializedQNameIterator::FindDataEnd()
     102              : {
     103          677 :     while (Next(false))
     104              :     {
     105              :         // nothing to do, just advance
     106              :     }
     107              : 
     108          297 :     if (!IsValid())
     109              :     {
     110            0 :         return nullptr;
     111              :     }
     112              : 
     113              :     // normal end
     114          297 :     if (*mCurrentPosition == 0)
     115              :     {
     116              :         // mCurrentPosition MUST already be valid
     117           90 :         return mCurrentPosition + 1;
     118              :     }
     119              : 
     120              :     // ends with a dataptr
     121          207 :     if ((*mCurrentPosition & kPtrMask) == kPtrMask)
     122              :     {
     123          207 :         if (!mValidData.Contains(mCurrentPosition + 1))
     124              :         {
     125            0 :             return nullptr;
     126              :         }
     127          207 :         return mCurrentPosition + 2;
     128              :     }
     129              : 
     130              :     // invalid data
     131            0 :     return nullptr;
     132              : }
     133              : 
     134        28102 : bool SerializedQNameIterator::operator==(const FullQName & other) const
     135              : {
     136        28102 :     SerializedQNameIterator self = *this; // allow iteration
     137        28102 :     size_t idx                   = 0;
     138              : 
     139        34402 :     while ((idx < other.nameCount) && self.Next())
     140              :     {
     141        27378 :         if (strcasecmp(self.Value(), other.names[idx]) != 0)
     142              :         {
     143        21078 :             return false;
     144              :         }
     145         6300 :         idx++;
     146              :     }
     147              : 
     148         7024 :     return ((idx == other.nameCount) && !self.Next());
     149              : }
     150              : 
     151           66 : bool SerializedQNameIterator::operator==(const SerializedQNameIterator & other) const
     152              : {
     153           66 :     SerializedQNameIterator a = *this; // allow iteration
     154           66 :     SerializedQNameIterator b = other;
     155              : 
     156              :     while (true)
     157              :     {
     158          216 :         bool hasA = a.Next();
     159          216 :         bool hasB = b.Next();
     160              : 
     161          216 :         if (hasA ^ hasB)
     162              :         {
     163            6 :             return false; /// one is longer than the other
     164              :         }
     165              : 
     166          210 :         if (!a.IsValid() || !b.IsValid())
     167              :         {
     168            0 :             return false; // invalid data
     169              :         }
     170              : 
     171          210 :         if (!hasA || !hasB)
     172              :         {
     173              :             break;
     174              :         }
     175              : 
     176          167 :         if (strcasecmp(a.Value(), b.Value()) != 0)
     177              :         {
     178           17 :             return false;
     179              :         }
     180          150 :     }
     181              : 
     182           43 :     return a.IsValid() && b.IsValid();
     183              : }
     184              : 
     185         6687 : bool FullQName::operator==(const FullQName & other) const
     186              : {
     187         6687 :     if (nameCount != other.nameCount)
     188              :     {
     189         5181 :         return false;
     190              :     }
     191         4770 :     for (size_t i = 0; i < nameCount; i++)
     192              :     {
     193         3815 :         if (strcasecmp(names[i], other.names[i]) != 0)
     194              :         {
     195          551 :             return false;
     196              :         }
     197              :     }
     198          955 :     return true;
     199              : }
     200              : 
     201              : } // namespace Minimal
     202              : } // namespace mdns
        

Generated by: LCOV version 2.0-1