Matter SDK Coverage Report
Current view: top level - lib/dnssd/minimal_mdns/core - QName.cpp (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 85.9 % 78 67
Test Date: 2025-01-17 19:00:11 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        56149 : bool SerializedQNameIterator::Next()
      26              : {
      27        56149 :     return mIsValid && Next(true);
      28              : }
      29              : 
      30        56973 : bool SerializedQNameIterator::Next(bool followIndirectPointers)
      31              : {
      32        56973 :     if (!mIsValid)
      33              :     {
      34            0 :         return false;
      35              :     }
      36              : 
      37              :     while (true)
      38              :     {
      39        66806 :         assert(mValidData.Contains(mCurrentPosition));
      40              : 
      41        66806 :         const uint8_t length = *mCurrentPosition;
      42        66806 :         if (*mCurrentPosition == 0)
      43              :         {
      44              :             // Done with all items
      45        11313 :             return false;
      46              :         }
      47              : 
      48        55493 :         if ((length & kPtrMask) == kPtrMask)
      49              :         {
      50        10126 :             if (!followIndirectPointers)
      51              :             {
      52              :                 // Stop at first indirect pointer
      53          287 :                 return false;
      54              :             }
      55              : 
      56              :             // PTR contains 2 bytes
      57         9839 :             if (!mValidData.Contains(mCurrentPosition + 1))
      58              :             {
      59            2 :                 mIsValid = false;
      60            2 :                 return false;
      61              :             }
      62              : 
      63         9837 :             size_t offset = static_cast<size_t>(((*mCurrentPosition & 0x3F) << 8) | *(mCurrentPosition + 1));
      64         9837 :             if (offset >= mLookBehindMax)
      65              :             {
      66              :                 // Potential infinite recursion.
      67            4 :                 mIsValid = false;
      68            4 :                 return false;
      69              :             }
      70         9833 :             if (offset > mValidData.Size())
      71              :             {
      72              :                 // offset too large
      73            0 :                 mIsValid = false;
      74            0 :                 return false;
      75              :             }
      76              : 
      77              :             // Look behind has to keep going backwards, otherwise we may
      78              :             // get into an infinite list
      79         9833 :             if (offset >= static_cast<size_t>(mCurrentPosition - mValidData.Start()))
      80              :             {
      81            0 :                 mIsValid = false;
      82            0 :                 return false;
      83              :             }
      84              : 
      85         9833 :             mLookBehindMax   = offset;
      86         9833 :             mCurrentPosition = mValidData.Start() + offset;
      87              :         }
      88              :         else
      89              :         {
      90              :             // This branch handles non-pointer data. This will be string of size [length].
      91        45367 :             if (length > kMaxValueSize)
      92              :             {
      93              :                 // value is too large (larger than RFC limit)
      94            0 :                 mIsValid = false;
      95            0 :                 return false;
      96              :             }
      97              : 
      98        45367 :             if (!mValidData.Contains(mCurrentPosition + 1 + length))
      99              :             {
     100              :                 // string outside valid data
     101            7 :                 mIsValid = false;
     102            7 :                 return false;
     103              :             }
     104              : 
     105        45360 :             memcpy(mValue, mCurrentPosition + 1, length);
     106        45360 :             mValue[length]   = '\0';
     107        45360 :             mCurrentPosition = mCurrentPosition + length + 1;
     108        45360 :             return true;
     109              :         }
     110         9833 :     }
     111              : }
     112              : 
     113          384 : const uint8_t * SerializedQNameIterator::FindDataEnd()
     114              : {
     115          824 :     while (Next(false))
     116              :     {
     117              :         // nothing to do, just advance
     118              :     }
     119              : 
     120          384 :     if (!IsValid())
     121              :     {
     122            0 :         return nullptr;
     123              :     }
     124              : 
     125              :     // normal end
     126          384 :     if (*mCurrentPosition == 0)
     127              :     {
     128              :         // mCurrentPosition MUST already be valid
     129           97 :         return mCurrentPosition + 1;
     130              :     }
     131              : 
     132              :     // ends with a dataptr
     133          287 :     if ((*mCurrentPosition & kPtrMask) == kPtrMask)
     134              :     {
     135          287 :         if (!mValidData.Contains(mCurrentPosition + 1))
     136              :         {
     137            0 :             return nullptr;
     138              :         }
     139          287 :         return mCurrentPosition + 2;
     140              :     }
     141              : 
     142              :     // invalid data
     143            0 :     return nullptr;
     144              : }
     145              : 
     146        25566 : bool SerializedQNameIterator::operator==(const FullQName & other) const
     147              : {
     148        25566 :     SerializedQNameIterator self = *this; // allow iteration
     149        25566 :     size_t idx                   = 0;
     150              : 
     151        31151 :     while ((idx < other.nameCount) && self.Next())
     152              :     {
     153        24803 :         if (strcasecmp(self.Value(), other.names[idx]) != 0)
     154              :         {
     155        19218 :             return false;
     156              :         }
     157         5585 :         idx++;
     158              :     }
     159              : 
     160         6348 :     return ((idx == other.nameCount) && !self.Next());
     161              : }
     162              : 
     163           86 : bool SerializedQNameIterator::operator==(const SerializedQNameIterator & other) const
     164              : {
     165           86 :     SerializedQNameIterator a = *this; // allow iteration
     166           86 :     SerializedQNameIterator b = other;
     167              : 
     168              :     while (true)
     169              :     {
     170          284 :         bool hasA = a.Next();
     171          284 :         bool hasB = b.Next();
     172              : 
     173          284 :         if (hasA ^ hasB)
     174              :         {
     175            6 :             return false; /// one is longer than the other
     176              :         }
     177              : 
     178          278 :         if (!a.IsValid() || !b.IsValid())
     179              :         {
     180            0 :             return false; // invalid data
     181              :         }
     182              : 
     183          278 :         if (!hasA || !hasB)
     184              :         {
     185              :             break;
     186              :         }
     187              : 
     188          215 :         if (strcasecmp(a.Value(), b.Value()) != 0)
     189              :         {
     190           17 :             return false;
     191              :         }
     192          198 :     }
     193              : 
     194           63 :     return a.IsValid() && b.IsValid();
     195              : }
     196              : 
     197         5645 : bool FullQName::operator==(const FullQName & other) const
     198              : {
     199         5645 :     if (nameCount != other.nameCount)
     200              :     {
     201         4341 :         return false;
     202              :     }
     203         4072 :     for (size_t i = 0; i < nameCount; i++)
     204              :     {
     205         3229 :         if (strcasecmp(names[i], other.names[i]) != 0)
     206              :         {
     207          461 :             return false;
     208              :         }
     209              :     }
     210          843 :     return true;
     211              : }
     212              : 
     213              : } // namespace Minimal
     214              : } // namespace mdns
        

Generated by: LCOV version 2.0-1